Fix prefilter merge conflicts
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-table-simple
|
||||
borderless
|
||||
class="mb-0"
|
||||
>
|
||||
<template v-for="(filterGroup, groupIndex) in value">
|
||||
<template v-if="filterGroup.filter.length">
|
||||
<b-tr
|
||||
@@ -7,28 +10,7 @@
|
||||
:key="`${groupIndex}-${index}`"
|
||||
class="pb-2"
|
||||
>
|
||||
<b-td
|
||||
class="align-middle"
|
||||
style="width: 1%;"
|
||||
>
|
||||
<h6
|
||||
v-if="index === 0"
|
||||
class="mb-0"
|
||||
>
|
||||
{{ $t("recordList.filter.where") }}
|
||||
</h6>
|
||||
|
||||
<b-form-select
|
||||
v-else
|
||||
v-model="filter.condition"
|
||||
:options="conditions"
|
||||
/>
|
||||
</b-td>
|
||||
|
||||
<b-td
|
||||
class="px-2"
|
||||
style="width: 250px;"
|
||||
>
|
||||
<b-td style="width: 250px;">
|
||||
<c-input-select
|
||||
v-model="filter.name"
|
||||
:options="fieldOptions"
|
||||
@@ -44,7 +26,7 @@
|
||||
<b-td
|
||||
v-if="getField(filter.name)"
|
||||
style="width: 250px;"
|
||||
:class="{ 'pr-2': getField(filter.name) }"
|
||||
:class="{ 'px-2': getField(filter.name) }"
|
||||
>
|
||||
<b-form-select
|
||||
v-if="getField(filter.name)"
|
||||
@@ -54,6 +36,7 @@
|
||||
@change="updateFilterProperties(filter)"
|
||||
/>
|
||||
</b-td>
|
||||
|
||||
<b-td v-if="getField(filter.name)">
|
||||
<template v-if="isBetweenOperator(filter.operator)">
|
||||
<template v-if="getField(`${filter.name}-start`)">
|
||||
@@ -90,6 +73,7 @@
|
||||
/>
|
||||
</template>
|
||||
</b-td>
|
||||
|
||||
<b-td
|
||||
v-if="getField(filter.name)"
|
||||
class="align-middle"
|
||||
@@ -98,8 +82,8 @@
|
||||
<b-button
|
||||
:id="`${groupIndex}-${index}`"
|
||||
ref="delete"
|
||||
variant="link"
|
||||
class="d-flex align-items-center"
|
||||
variant="outline-extra-light"
|
||||
class="d-block text-dark border-0 h-full ml-2 px-2"
|
||||
@click="deleteFilter(groupIndex, index)"
|
||||
>
|
||||
<font-awesome-icon
|
||||
@@ -110,16 +94,19 @@
|
||||
</b-td>
|
||||
</b-tr>
|
||||
|
||||
<b-tr :key="`addFilter-${groupIndex}`">
|
||||
<b-tr
|
||||
v-if="showAddCondition"
|
||||
:key="`addFilter-${groupIndex}`"
|
||||
>
|
||||
<b-td class="pb-0">
|
||||
<b-button
|
||||
variant="link text-decoration-none"
|
||||
style="min-height: 38px; min-width: 84px;"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
class="d-block mr-auto"
|
||||
@click="addFilter(groupIndex)"
|
||||
>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'plus']"
|
||||
size="sm"
|
||||
class="mr-1"
|
||||
/>
|
||||
{{ $t("general.label.add") }}
|
||||
@@ -134,17 +121,12 @@
|
||||
:class="{ 'pb-3': filterGroup.groupCondition }"
|
||||
>
|
||||
<div class="group-separator">
|
||||
<b-form-select
|
||||
v-if="filterGroup.groupCondition"
|
||||
v-model="filterGroup.groupCondition"
|
||||
class="m-auto w-auto d-block"
|
||||
:options="conditions"
|
||||
/>
|
||||
<div style="height: 20px; width: 100%;" />
|
||||
|
||||
<b-button
|
||||
v-else
|
||||
v-if="groupIndex === (value.length - 1)"
|
||||
variant="outline-primary"
|
||||
class="py-2 px-3 m-auto bg-white d-block btn-add-group"
|
||||
class="btn-add-group d-block py-2 px-3 m-auto bg-white "
|
||||
@click="addGroup()"
|
||||
>
|
||||
<font-awesome-icon
|
||||
@@ -157,7 +139,7 @@
|
||||
</b-tr>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</b-table-simple>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -186,9 +168,9 @@ export default {
|
||||
required: true,
|
||||
},
|
||||
|
||||
namespace: {
|
||||
type: compose.Namespace,
|
||||
required: true,
|
||||
selectedField: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
|
||||
mock: {
|
||||
@@ -200,6 +182,11 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
startEmpty: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
data () {
|
||||
@@ -230,11 +217,25 @@ export default {
|
||||
}),
|
||||
].filter(({ isFilterable }) => isFilterable)
|
||||
},
|
||||
|
||||
resolvedSelectedField () {
|
||||
if (this.selectedField) {
|
||||
return this.selectedField
|
||||
} else if (this.fields.length) {
|
||||
return this.fields[0]
|
||||
}
|
||||
|
||||
return {}
|
||||
},
|
||||
|
||||
showAddCondition () {
|
||||
return this.value.length >= 1 && this.value[0].filter[0].name
|
||||
},
|
||||
},
|
||||
|
||||
created () {
|
||||
if (this.resetFilterOnCreated) {
|
||||
this.resetFilter()
|
||||
if (this.resetFilterOnCreated || !this.startEmpty) {
|
||||
this.$emit('input', [this.createDefaultFilterGroup(undefined, this.startEmpty ? undefined : this.resolvedSelectedField)])
|
||||
}
|
||||
},
|
||||
|
||||
@@ -371,7 +372,7 @@ export default {
|
||||
},
|
||||
|
||||
deleteFilter (groupIndex, index) {
|
||||
const value = this.value
|
||||
let value = this.value
|
||||
const filterExists = !!(
|
||||
value[groupIndex] || { filter: [] }
|
||||
).filter[index]
|
||||
@@ -386,12 +387,13 @@ export default {
|
||||
|
||||
// If no more filterGroups, add default back
|
||||
if (!value.length) {
|
||||
this.resetFilter()
|
||||
value = [this.createDefaultFilterGroup()]
|
||||
} else if (groupIndex === value.length) {
|
||||
// Reset first filterGroup groupCondition if last filterGroup was deleted
|
||||
value[groupIndex - 1].groupCondition = undefined
|
||||
}
|
||||
}
|
||||
|
||||
this.$emit('input', value)
|
||||
}
|
||||
|
||||
@@ -409,10 +411,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
resetFilter () {
|
||||
this.$emit('input', [this.createDefaultFilterGroup()])
|
||||
},
|
||||
|
||||
getOptionKey ({ name }) {
|
||||
return name
|
||||
},
|
||||
@@ -422,7 +420,7 @@ export default {
|
||||
|
||||
if ((value[groupIndex] || {}).filter) {
|
||||
value[groupIndex].filter.push(
|
||||
this.createDefaultFilter('AND', this.selectedField)
|
||||
this.createDefaultFilter('AND', this.resolvedSelectedField)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -442,7 +440,7 @@ export default {
|
||||
value[value.length - 1].groupCondition =
|
||||
'AND'
|
||||
value.push(
|
||||
this.createDefaultFilterGroup(undefined, this.selectedField)
|
||||
this.createDefaultFilterGroup(undefined, this.resolvedSelectedField)
|
||||
)
|
||||
|
||||
this.$emit('input', value)
|
||||
|
||||
@@ -32,21 +32,17 @@
|
||||
class="position-static w-100"
|
||||
>
|
||||
<b-card-body
|
||||
class="px-1 pb-0 overflow-auto"
|
||||
class="px-2 pb-0 overflow-auto"
|
||||
>
|
||||
<b-table-simple
|
||||
<filter-toolbox
|
||||
v-if="componentFilter.length"
|
||||
borderless
|
||||
class="mb-0"
|
||||
>
|
||||
<filter-toolbox
|
||||
v-model="componentFilter"
|
||||
:module="module"
|
||||
:namespace="namespace"
|
||||
:mock.sync="mock"
|
||||
@prevent-close="onValueChange"
|
||||
/>
|
||||
</b-table-simple>
|
||||
v-model="componentFilter"
|
||||
:module="module"
|
||||
:selected-field="selectedField"
|
||||
:namespace="namespace"
|
||||
:mock.sync="mock"
|
||||
@prevent-close="onValueChange"
|
||||
/>
|
||||
</b-card-body>
|
||||
|
||||
<b-card-footer
|
||||
@@ -108,7 +104,7 @@ export default {
|
||||
|
||||
selectedField: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: undefined,
|
||||
},
|
||||
|
||||
namespace: {
|
||||
@@ -166,12 +162,12 @@ export default {
|
||||
computed: {
|
||||
inFilter () {
|
||||
return this.recordListFilter.some(({ filter }) => {
|
||||
return filter.some(({ name }) => name === this.selectedField.name)
|
||||
return filter.some(({ name }) => name === (this.selectedField || {}).name)
|
||||
})
|
||||
},
|
||||
|
||||
popoverTarget () {
|
||||
return `${this.target || '0'}-${this.selectedField.name}`
|
||||
return `${this.target || '0'}-${(this.selectedField || {}).name}`
|
||||
},
|
||||
},
|
||||
|
||||
@@ -374,7 +370,7 @@ export default {
|
||||
width: 800px;
|
||||
min-width: min(99vw, 350px);
|
||||
max-width: 99vw;
|
||||
max-height: 60vh;
|
||||
max-height: 25rem;
|
||||
padding: 0;
|
||||
color: var(--black);
|
||||
text-align: center;
|
||||
@@ -401,25 +397,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.group-separator {
|
||||
background-image: linear-gradient(to left, lightgray, lightgray);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 1px;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
padding-bottom: 0.5rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.btn-add-group {
|
||||
&:hover, &:active {
|
||||
background-color: var(--primary) !important;
|
||||
color: var(--white) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -93,9 +93,8 @@
|
||||
/>
|
||||
</c-input-select>
|
||||
|
||||
<b-input-group-append>
|
||||
<b-input-group-append v-if="canAddRecordThroughSelectField">
|
||||
<b-button
|
||||
v-if="canAddRecordThroughSelectField"
|
||||
v-b-tooltip.hover="{ title: $t('kind.record.tooltip.addRecord'), container: '#body' }"
|
||||
variant="light"
|
||||
class="d-flex align-items-center"
|
||||
@@ -138,9 +137,9 @@
|
||||
@next="goToPage(true)"
|
||||
/>
|
||||
</c-input-select>
|
||||
<b-input-group-append>
|
||||
|
||||
<b-input-group-append v-if="canAddRecordThroughSelectField">
|
||||
<b-button
|
||||
v-if="canAddRecordThroughSelectField"
|
||||
v-b-tooltip.hover="{ title: $t('kind.record.tooltip.addRecord'), container: '#body' }"
|
||||
variant="light"
|
||||
class="d-flex align-items-center"
|
||||
@@ -191,9 +190,9 @@
|
||||
@next="goToPage(true)"
|
||||
/>
|
||||
</c-input-select>
|
||||
<b-input-group-append>
|
||||
|
||||
<b-input-group-append v-if="canAddRecordThroughSelectField">
|
||||
<b-button
|
||||
v-if="canAddRecordThroughSelectField"
|
||||
v-b-tooltip.hover="{ title: $t('kind.record.tooltip.addRecord'), container: '#body' }"
|
||||
variant="light"
|
||||
class="d-flex align-items-center"
|
||||
@@ -315,7 +314,7 @@ export default {
|
||||
},
|
||||
|
||||
canAddRecordThroughSelectField () {
|
||||
if (this.module === undefined) return
|
||||
if (!this.extraOptions.recordSelectorShowAddRecordButton || this.module === undefined) return
|
||||
|
||||
return !!this.getRecordSelectorPage().page.pageID && this.module.canCreateRecord
|
||||
},
|
||||
|
||||
@@ -56,51 +56,20 @@
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
|
||||
<template v-if="isRecordConfigured">
|
||||
<b-col
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<b-form-group
|
||||
:label="$t('record.add')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<c-input-checkbox
|
||||
v-model="options.recordSelectorShowAddRecordButton"
|
||||
switch
|
||||
:labels="checkboxLabel"
|
||||
/>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
|
||||
<b-col
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<b-form-group
|
||||
:label="$t('record.recordSelectorAddRecordDisplayOption')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<b-form-select
|
||||
v-model="options.recordSelectorAddRecordDisplayOption"
|
||||
:options="recordDisplayOptions"
|
||||
:disabled="!options.recordSelectorShowAddRecordButton"
|
||||
/>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
</template>
|
||||
|
||||
<b-col
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<b-form-group
|
||||
:label="$t('record.recordSelectorDisplayOptions')"
|
||||
:label="$t('record.fieldsLayoutMode.label')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<b-form-select
|
||||
v-model="options.recordSelectorDisplayOption"
|
||||
:options="recordDisplayOptions"
|
||||
<c-input-select
|
||||
v-model="options.recordFieldLayoutOption"
|
||||
:options="recordFieldLayoutOptions"
|
||||
:reduce="option => option.value"
|
||||
:get-option-key="option => option.label"
|
||||
@input="handleRecordFieldLayout"
|
||||
/>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
@@ -125,24 +94,6 @@
|
||||
/>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
|
||||
<b-col
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<b-form-group
|
||||
:label="$t('record.fieldsLayoutMode.label')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<c-input-select
|
||||
v-model="options.recordFieldLayoutOption"
|
||||
:options="recordFieldLayoutOptions"
|
||||
:reduce="option => option.value"
|
||||
:get-option-key="option => option.label"
|
||||
@input="handleRecordFieldLayout"
|
||||
/>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
|
||||
@@ -165,6 +116,58 @@
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row
|
||||
v-if="isRecordConfigured"
|
||||
class="mt-3"
|
||||
>
|
||||
<b-col
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<b-form-group
|
||||
:label="$t('record.recordSelectorDisplayOptions')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<b-form-select
|
||||
v-model="options.recordSelectorDisplayOption"
|
||||
:options="recordDisplayOptions"
|
||||
/>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
|
||||
<b-col
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<b-form-group
|
||||
:label="$t('record.recordSelectorCanAddRecord')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<c-input-checkbox
|
||||
v-model="options.recordSelectorShowAddRecordButton"
|
||||
switch
|
||||
:labels="checkboxLabel"
|
||||
/>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
|
||||
<b-col
|
||||
cols="12"
|
||||
lg="6"
|
||||
>
|
||||
<b-form-group
|
||||
:label="$t('record.recordSelectorAddRecordDisplayOption')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<b-form-select
|
||||
v-model="options.recordSelectorAddRecordDisplayOption"
|
||||
:options="recordDisplayOptions"
|
||||
:disabled="!options.recordSelectorShowAddRecordButton"
|
||||
/>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
@@ -340,7 +343,7 @@ export default {
|
||||
},
|
||||
|
||||
isRecordConfigured () {
|
||||
return this.module.fields.some(f => f.kind === 'Record')
|
||||
return this.options.fields.some(f => f.kind === 'Record')
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
<template>
|
||||
<c-form-table-wrapper hide-add-button>
|
||||
<b-form-group
|
||||
:label="$t('recordList.record.prefilterCommand')"
|
||||
label-class="text-primary"
|
||||
class="m-0"
|
||||
>
|
||||
<b-row v-if="textInput">
|
||||
<b-col>
|
||||
<b-form-group label-class="text-primary">
|
||||
<c-input-expression
|
||||
v-model="options.prefilter"
|
||||
height="3.688rem"
|
||||
lang="javascript"
|
||||
:suggestion-params="recordAutoCompleteParams"
|
||||
/>
|
||||
|
||||
<i18next
|
||||
path="recordList.record.prefilterFootnote"
|
||||
tag="small"
|
||||
class="text-muted"
|
||||
>
|
||||
<code>${record.values.fieldName}</code>
|
||||
<code>${recordID}</code>
|
||||
<code>${ownerID}</code>
|
||||
<span><code>${userID}</code>, <code>${user.name}</code></span>
|
||||
</i18next>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<c-form-table-wrapper
|
||||
v-else
|
||||
hide-add-button
|
||||
>
|
||||
<filter-toolbox
|
||||
v-model="filterGroup"
|
||||
:module="module"
|
||||
:namespace="namespace"
|
||||
:mock.sync="mock"
|
||||
reset-filter-on-created
|
||||
/>
|
||||
</c-form-table-wrapper>
|
||||
|
||||
<div class="mt-1 d-flex align-items-center">
|
||||
<b-button
|
||||
variant="link"
|
||||
size="sm"
|
||||
class="ml-auto text-decoration-none"
|
||||
@click="toggleFilterView"
|
||||
>
|
||||
{{ $t('recordList.prefilter.toggleInputType') }}
|
||||
</b-button>
|
||||
</div>
|
||||
</b-form-group>
|
||||
</c-form-table-wrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { components } from '@cortezaproject/corteza-vue'
|
||||
import { compose, validator } from '@cortezaproject/corteza-js'
|
||||
import {
|
||||
getRecordListFilterSql,
|
||||
trimChar,
|
||||
} from 'corteza-webapp-compose/src/lib/record-filter.js'
|
||||
import FilterToolbox from 'corteza-webapp-compose/src/components/Common/FilterToolbox.vue'
|
||||
import autocomplete from 'corteza-webapp-compose/src/mixins/autocomplete.js'
|
||||
|
||||
const { CInputExpression } = components
|
||||
|
||||
export default {
|
||||
i18nOptions: {
|
||||
namespaces: 'block',
|
||||
},
|
||||
|
||||
name: 'RecordListConfiguratorPrefilter',
|
||||
|
||||
components: {
|
||||
FilterToolbox,
|
||||
CInputExpression,
|
||||
},
|
||||
|
||||
mixins: [autocomplete],
|
||||
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
|
||||
namespace: {
|
||||
type: compose.Namespace,
|
||||
required: true,
|
||||
},
|
||||
|
||||
module: {
|
||||
type: compose.Module,
|
||||
required: true,
|
||||
},
|
||||
|
||||
record: {
|
||||
type: [Object, null],
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
textInput: true,
|
||||
filterGroup: [],
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
recordAutoCompleteParams () {
|
||||
return this.processRecordAutoCompleteParams({ operators: true })
|
||||
},
|
||||
},
|
||||
|
||||
created () {
|
||||
// Change all module fields to single value to keep multi value fields and single value
|
||||
const module = JSON.parse(JSON.stringify(this.module || {}))
|
||||
|
||||
module.fields = [
|
||||
...[...module.fields].map((f) => {
|
||||
f.multi = f.isMulti
|
||||
f.isMulti = false
|
||||
|
||||
// Disable edge case options
|
||||
if (f.kind === 'DateTime') {
|
||||
f.options.onlyFutureValues = false
|
||||
f.options.onlyPastValues = false
|
||||
}
|
||||
|
||||
return f
|
||||
}),
|
||||
...this.module.systemFields().map((sf) => {
|
||||
return { ...sf, label: this.$t(`field:system.${sf.name}`) }
|
||||
}),
|
||||
]
|
||||
|
||||
this.mock = {
|
||||
namespace: this.namespace,
|
||||
module,
|
||||
errors: new validator.Validated(),
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleFilterView () {
|
||||
if (!this.textInput) {
|
||||
this.options.prefilter = this.parseFilter()
|
||||
}
|
||||
|
||||
this.textInput = !this.textInput
|
||||
},
|
||||
|
||||
getOptionKey ({ name }) {
|
||||
return name
|
||||
},
|
||||
|
||||
processFilter (filterGroup = this.value) {
|
||||
return filterGroup.map(({ groupCondition, filter = [], name }) => {
|
||||
filter = filter.map(({ record, ...f }) => {
|
||||
if (record) {
|
||||
f.value = record[f.name] || record.values[f.name]
|
||||
}
|
||||
|
||||
if (this.isBetweenOperator(f.operator)) {
|
||||
f.value = {
|
||||
start: this.getField(f.name).isSystem
|
||||
? record[`${f.name}-start`]
|
||||
: record.values[`${f.name}-start`],
|
||||
end: this.getField(f.name).isSystem
|
||||
? record[`${f.name}-end`]
|
||||
: record.values[`${f.name}-end`],
|
||||
}
|
||||
}
|
||||
|
||||
return f
|
||||
})
|
||||
|
||||
return { groupCondition, filter, name }
|
||||
})
|
||||
},
|
||||
|
||||
isBetweenOperator (op) {
|
||||
return ['BETWEEN', 'NOT BETWEEN'].includes(op)
|
||||
},
|
||||
|
||||
parseFilter (filterGroup = this.filterGroup) {
|
||||
const filter = this.processFilter(filterGroup)
|
||||
|
||||
const filterSqlArray = filter
|
||||
.map(({ groupCondition, filter = [] }) => {
|
||||
groupCondition = groupCondition ? ` ${groupCondition} ` : ''
|
||||
filter = getRecordListFilterSql(filter)
|
||||
|
||||
return filter ? `${filter}${groupCondition}` : ''
|
||||
})
|
||||
.filter((filter) => filter)
|
||||
|
||||
const filterSql = trimChar(
|
||||
trimChar(filterSqlArray.join(''), ' AND '),
|
||||
' OR '
|
||||
)
|
||||
|
||||
return filterSql
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -8,9 +8,11 @@
|
||||
<b-row v-if="textInput">
|
||||
<b-col>
|
||||
<b-form-group label-class="text-primary">
|
||||
<b-form-textarea
|
||||
<c-input-expression
|
||||
v-model="options.prefilter"
|
||||
:placeholder="$t('recordList.record.prefilterPlaceholder')"
|
||||
height="3.688rem"
|
||||
lang="javascript"
|
||||
:suggestion-params="recordAutoCompleteParams"
|
||||
/>
|
||||
|
||||
<i18next
|
||||
@@ -27,18 +29,14 @@
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<c-form-table-wrapper
|
||||
<filter-toolbox
|
||||
v-else
|
||||
hide-add-button
|
||||
>
|
||||
<filter-toolbox
|
||||
v-model="filterGroup"
|
||||
:module="module"
|
||||
:namespace="namespace"
|
||||
:mock.sync="mock"
|
||||
reset-filter-on-created
|
||||
/>
|
||||
</c-form-table-wrapper>
|
||||
v-model="filterGroup"
|
||||
:module="module"
|
||||
:mock.sync="mock"
|
||||
reset-filter-on-created
|
||||
start-empty
|
||||
/>
|
||||
|
||||
<div class="mt-1 d-flex align-items-center">
|
||||
<b-button
|
||||
@@ -55,12 +53,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { components } from '@cortezaproject/corteza-vue'
|
||||
import { compose, validator } from '@cortezaproject/corteza-js'
|
||||
import {
|
||||
getRecordListFilterSql,
|
||||
trimChar,
|
||||
} from 'corteza-webapp-compose/src/lib/record-filter.js'
|
||||
import FilterToolbox from 'corteza-webapp-compose/src/components/Common/FilterToolbox.vue'
|
||||
import autocomplete from 'corteza-webapp-compose/src/mixins/autocomplete.js'
|
||||
|
||||
const { CInputExpression } = components
|
||||
|
||||
export default {
|
||||
i18nOptions: {
|
||||
@@ -71,8 +73,11 @@ export default {
|
||||
|
||||
components: {
|
||||
FilterToolbox,
|
||||
CInputExpression,
|
||||
},
|
||||
|
||||
mixins: [autocomplete],
|
||||
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
@@ -88,6 +93,12 @@ export default {
|
||||
type: compose.Module,
|
||||
required: true,
|
||||
},
|
||||
|
||||
record: {
|
||||
type: [Object, null],
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
data () {
|
||||
@@ -97,6 +108,12 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
recordAutoCompleteParams () {
|
||||
return this.processRecordAutoCompleteParams({ operators: true })
|
||||
},
|
||||
},
|
||||
|
||||
created () {
|
||||
// Change all module fields to single value to keep multi value fields and single value
|
||||
const module = JSON.parse(JSON.stringify(this.module || {}))
|
||||
@@ -129,7 +146,7 @@ export default {
|
||||
methods: {
|
||||
toggleFilterView () {
|
||||
if (!this.textInput) {
|
||||
this.options.prefilter = this.parseFilter()
|
||||
this.options.prefilter = this.parseFilter() || this.options.prefilter
|
||||
}
|
||||
|
||||
this.textInput = !this.textInput
|
||||
|
||||
@@ -303,100 +303,85 @@
|
||||
>
|
||||
<b-spinner v-if="fetchingRoles" />
|
||||
|
||||
<template v-else>
|
||||
<b-table-simple
|
||||
borderless
|
||||
small
|
||||
responsive="lg"
|
||||
class="mb-0"
|
||||
<b-table-simple
|
||||
v-else
|
||||
borderless
|
||||
small
|
||||
responsive="lg"
|
||||
class="mb-2"
|
||||
>
|
||||
<draggable
|
||||
:list.sync="options.filterPresets"
|
||||
group="sort"
|
||||
handle=".grab"
|
||||
tag="tbody"
|
||||
>
|
||||
<draggable
|
||||
:list.sync="options.filterPresets"
|
||||
group="sort"
|
||||
handle=".grab"
|
||||
tag="tbody"
|
||||
<b-tr
|
||||
v-for="(filter, index) in options.filterPresets"
|
||||
:key="index"
|
||||
>
|
||||
<b-tr
|
||||
v-for="(filter, index) in options.filterPresets"
|
||||
:key="index"
|
||||
<b-td
|
||||
class="grab text-center align-middle"
|
||||
style="width: 40px;"
|
||||
>
|
||||
<b-td
|
||||
class="grab text-center align-middle"
|
||||
style="width: 40px;"
|
||||
>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'bars']"
|
||||
class="text-secondary"
|
||||
/>
|
||||
</b-td>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'bars']"
|
||||
class="text-secondary"
|
||||
/>
|
||||
</b-td>
|
||||
|
||||
<b-td
|
||||
class="align-middle"
|
||||
style="min-width: 150px;"
|
||||
>
|
||||
<b-input-group>
|
||||
<b-form-input
|
||||
v-model="filter.name"
|
||||
:placeholder="$t('recordList.filter.name.placeholder')"
|
||||
<b-td
|
||||
class="align-middle"
|
||||
style="min-width: 150px;"
|
||||
>
|
||||
<b-input-group>
|
||||
<b-form-input
|
||||
v-model="filter.name"
|
||||
:placeholder="$t('recordList.filter.name.placeholder')"
|
||||
/>
|
||||
|
||||
<b-input-group-append>
|
||||
<record-list-filter
|
||||
class="d-print-none"
|
||||
:target="`record-filter-${index}`"
|
||||
:namespace="namespace"
|
||||
:module="recordListModule"
|
||||
:record-list-filter="filter.filter"
|
||||
variant="extra-light"
|
||||
inactive-icon-class="text-light"
|
||||
button-class="px-2 pt-2"
|
||||
button-style="border-top-left-radius: 0; border-bottom-left-radius: 0;"
|
||||
@filter="(filter) => onFilter(filter, index)"
|
||||
/>
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
</b-td>
|
||||
|
||||
<b-input-group-append>
|
||||
<record-list-filter
|
||||
class="d-print-none"
|
||||
:target="`record-filter-${index}`"
|
||||
:namespace="namespace"
|
||||
:module="recordListModule"
|
||||
:selected-field="recordListModule.fields[0]"
|
||||
:record-list-filter="filter.filter"
|
||||
variant="extra-light"
|
||||
inactive-icon-class="text-light"
|
||||
button-class="px-2 pt-2"
|
||||
button-style="border-top-left-radius: 0; border-bottom-left-radius: 0;"
|
||||
@filter="(filter) => onFilter(filter, index)"
|
||||
/>
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
</b-td>
|
||||
<b-td
|
||||
class="text-center align-middle"
|
||||
style="min-width: 200px;"
|
||||
>
|
||||
<c-input-role
|
||||
:value="getFilterRoles(filter)"
|
||||
:placeholder="$t('recordList.filter.role.placeholder')"
|
||||
:visible="isRoleVisible"
|
||||
multiple
|
||||
@input="onFilterRoleChange(filter, $event)"
|
||||
/>
|
||||
</b-td>
|
||||
|
||||
<b-td
|
||||
class="text-center align-middle"
|
||||
style="min-width: 200px;"
|
||||
>
|
||||
<c-input-role
|
||||
:value="getFilterRoles(filter)"
|
||||
:placeholder="$t('recordList.filter.role.placeholder')"
|
||||
:visible="isRoleVisible"
|
||||
multiple
|
||||
@input="onFilterRoleChange(filter, $event)"
|
||||
/>
|
||||
</b-td>
|
||||
|
||||
<b-td
|
||||
class="text-right align-middle"
|
||||
style="min-width: 80px; width: 80px;"
|
||||
>
|
||||
<c-input-confirm
|
||||
show-icon
|
||||
@confirmed="options.filterPresets.splice(index, 1)"
|
||||
/>
|
||||
</b-td>
|
||||
</b-tr>
|
||||
</draggable>
|
||||
</b-table-simple>
|
||||
|
||||
<b-button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
class="mt-1"
|
||||
@click="addFilterPreset"
|
||||
>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'plus']"
|
||||
class="mr-1"
|
||||
/>
|
||||
{{ $t('general:label.add') }}
|
||||
</b-button>
|
||||
</template>
|
||||
<b-td
|
||||
class="text-right align-middle"
|
||||
style="min-width: 80px; width: 80px;"
|
||||
>
|
||||
<c-input-confirm
|
||||
show-icon
|
||||
@confirmed="options.filterPresets.splice(index, 1)"
|
||||
/>
|
||||
</b-td>
|
||||
</b-tr>
|
||||
</draggable>
|
||||
</b-table-simple>
|
||||
</c-form-table-wrapper>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<b-row>
|
||||
<b-col lg="6">
|
||||
<b-card
|
||||
:header="$t('automation.configuredButtons')"
|
||||
:title="$t('automation.configuredButtons')"
|
||||
footer-class="text-right"
|
||||
class="border"
|
||||
>
|
||||
@@ -70,7 +70,7 @@
|
||||
<b-col>
|
||||
<b-card
|
||||
v-if="available.length > 0"
|
||||
:header="$t('automation.availableScriptsAndWorkflow', { count: available.length })"
|
||||
:title="$t('automation.availableScriptsAndWorkflow', { count: available.length })"
|
||||
class="border"
|
||||
>
|
||||
<c-input-search
|
||||
@@ -87,12 +87,12 @@
|
||||
@click.prevent="appendButton(b)"
|
||||
>
|
||||
<b-list-group-item>
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5>
|
||||
<div class="d-flex align-items-center w-100 justify-content-between">
|
||||
<h6>
|
||||
{{ b.label || b.script }}
|
||||
<b-badge
|
||||
v-if="b.workflowID"
|
||||
variant="light"
|
||||
variant="info"
|
||||
>
|
||||
{{ $t('automation.badge.workflow') }}
|
||||
</b-badge>
|
||||
@@ -102,7 +102,7 @@
|
||||
>
|
||||
{{ $t('automation.badge.script') }}
|
||||
</b-badge>
|
||||
</h5>
|
||||
</h6>
|
||||
<code v-if="b.label && b.script">{{ b.script }}</code>
|
||||
</div>
|
||||
<p
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<b-card
|
||||
:header="workflow ? $t('editTitle.workflow') : $t('editTitle.script')"
|
||||
footer-class="text-right"
|
||||
:title="workflow ? $t('editTitle.workflow') : $t('editTitle.script')"
|
||||
footer-class="text-right pt-0"
|
||||
class="border"
|
||||
>
|
||||
<b-form-group
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="list-background w-100 p-3 rounded border border-light">
|
||||
<slot></slot>
|
||||
<slot />
|
||||
|
||||
<b-button
|
||||
v-if="!hideAddButton"
|
||||
@@ -11,10 +11,10 @@
|
||||
:disabled="disableAddButton"
|
||||
@click="$emit('add-item')"
|
||||
>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'plus']"
|
||||
class="mr-1"
|
||||
/>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'plus']"
|
||||
class="mr-1"
|
||||
/>
|
||||
|
||||
{{ labels.addButton || '' }}
|
||||
</b-button>
|
||||
@@ -46,10 +46,10 @@ export default {
|
||||
default: '',
|
||||
},
|
||||
|
||||
buttonTestId : {
|
||||
buttonTestId: {
|
||||
type: String,
|
||||
default: '',
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -278,10 +278,9 @@ metric:
|
||||
valueLabel: Value style
|
||||
label: Metric
|
||||
record:
|
||||
add: Can create records via selector
|
||||
referenceRecordField: Reference record field
|
||||
referenceRecordFieldPlaceholder: Select reference record selector
|
||||
referenceRecordFieldDescription: Multi value record selector fields are not available
|
||||
referenceRecordField: Reference record
|
||||
referenceRecordFieldPlaceholder: Select reference record field
|
||||
referenceRecordFieldDescription: Used to show record details of reference record. Multi value record selector fields are not available
|
||||
confirmDelete: Are you sure you want to delete this record?
|
||||
deleteFailed: Could not delete record
|
||||
deleteRecord: Delete record
|
||||
@@ -304,7 +303,7 @@ record:
|
||||
fieldsFromModule: Single record block, displaying fields ({{0}}) from module {{1}}
|
||||
untitled: Untitled
|
||||
recordDeleted: This record was deleted
|
||||
recordSelectorDisplayOptions: On record value click
|
||||
recordSelectorDisplayOptions: When clicking on record field value
|
||||
openInSameTab: Open record in the same tab
|
||||
openInNewTab: Open record in a new tab
|
||||
openInModal: Open record in a modal
|
||||
@@ -318,7 +317,8 @@ record:
|
||||
condition: Condition
|
||||
tooltip:
|
||||
performance: Using conditional fields will impact performance
|
||||
recordSelectorAddRecordDisplayOption: On selector record create
|
||||
recordSelectorCanAddRecord: Can add records via record selector
|
||||
recordSelectorAddRecordDisplayOption: When adding a record via record selector
|
||||
recordList:
|
||||
addRecord: Add
|
||||
cancelSelection: Cancel
|
||||
|
||||
Reference in New Issue
Block a user