1
0
mirror of https://github.com/PanJiaChen/vue-element-admin.git synced 2025-08-11 05:11:59 +08:00

feat: Add operators comparison to advanced search. (#287)

* feat: Add operators comparison to advanced search.

* Set is null and not null operator.

* Add multiple values to IN and NOT IN operators.

* Add component render to set values to IN and NOT IN operators.

* Add IN and NOT IN operators in date component.

* Fix attribute comparison (isAdvancedQuery).
This commit is contained in:
EdwinBetanc0urt 2020-01-31 12:53:04 -04:00 committed by GitHub
parent 88c1f03494
commit 7870fdbfab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 531 additions and 119 deletions

View File

@ -76,7 +76,7 @@ export function getEntity({ tableName, recordId, recordUuid }) {
* @param {string} tableName
* @param {string} query
* @param {string} whereClause
* @param {array} conditions
* @param {array} conditionsList
* @param {string} orderByClause
* @param {string} nextPageToken
*/
@ -84,7 +84,7 @@ export function getEntitiesList({
tableName,
query,
whereClause,
conditions: conditionsList = [],
conditionsList = [],
orderByClause,
nextPageToken: pageToken,
pageSize
@ -100,6 +100,27 @@ export function getEntitiesList({
})
}
/**
* Get all operator or get key value type from value
* @param {number} keyToFind
EQUAL = 0;
NOT_EQUAL = 1;
LIKE = 2;
NOT_LIKE = 3;
GREATER = 4;
GREATER_EQUAL = 5;
LESS = 6;
LESS_EQUAL = 7;
BETWEEN = 8;
NOT_NULL = 9;
NULL = 10;
IN = 11;
NOT_IN = 12;
*/
export function getConditionOperators(keyToFind) {
return Instance.call(this).getConditionOperators(keyToFind)
}
/**
* Rollback entity (Create, Update, Delete)
* @param {string} tableName

View File

@ -98,15 +98,18 @@ export default {
},
computed: {
typePicker() {
let range = ''
let time = ''
if (String(this.metadata.displayType) === String(16)) {
time = 'time'
let picker = 'date'
if (['IN', 'NOT_IN'].includes(this.metadata.operator) && this.metadata.isAdvancedQuery) {
picker += 's'
return picker
}
if (this.metadata.displayType === 16) {
picker += 'time'
}
if (this.metadata.isRange && !this.metadata.inTable) {
range = 'range'
picker += 'range'
}
return 'date' + time + range
return picker
},
/**
* Parse the date format to be compatible with element-ui
@ -150,9 +153,30 @@ export default {
parsedDateValue(value) {
// not return undefined to v-model
if (this.isEmptyValue(value)) {
if (['IN', 'NOT_IN'].includes(this.metadata.operator) && this.metadata.isAdvancedQuery) {
return []
}
return null
}
if (['IN', 'NOT_IN'].includes(this.metadata.operator) && this.metadata.isAdvancedQuery) {
if (Array.isArray(value)) {
value = value.map(itemValue => {
if (typeof itemValue === 'object') {
return itemValue.toUTCString()
}
return itemValue
})
} else {
const tempValue = []
if (!this.isEmptyValue(value)) {
tempValue.push(value)
}
value = tempValue
}
return value
}
// instance date from long value
if (typeof value === 'number') {
value = new Date(value).toUTCString()
@ -177,6 +201,14 @@ export default {
let startValue, endValue
startValue = value
if (this.typePicker === 'dates') {
if (Array.isArray(value)) {
value = value.map(itemValue => new Date(itemValue))
}
this.handleChange(value)
return
}
if (this.metadata.isRange && !this.metadata.inTable && Array.isArray(value)) {
startValue = value[0]
endValue = value[1]

View File

@ -6,8 +6,11 @@
:placeholder="metadata.help"
:loading="isLoading"
value-key="key"
class="select-base"
:class="classStyle"
clearable
:multiple="isSelectMultiple"
:allow-create="metadata.isSelectCreated"
:collapse-tags="!isSelectMultiple"
:disabled="isDisabled"
@change="preHandleChange"
@visible-change="getDataLookupList"
@ -60,6 +63,16 @@ export default {
isMobile() {
return this.$store.state.app.device === 'mobile'
},
isSelectMultiple() {
return ['IN', 'NOT_IN'].includes(this.metadata.operator) && this.metadata.isAdvancedQuery
},
classStyle() {
let styleClass = 'custom-field-select'
if (this.isSelectMultiple) {
styleClass += ' custom-field-select-multiple'
}
return styleClass
},
getterLookupItem() {
if (this.isEmptyValue(this.metadata.reference.directQuery)) {
return this.blanckOption
@ -99,6 +112,23 @@ export default {
}
},
watch: {
isSelectMultiple(isMultiple) {
if (isMultiple) {
const valueInArray = []
if (!this.isEmptyValue(this.value)) {
valueInArray.push(this.value)
}
this.value = valueInArray
} else {
if (Array.isArray(this.value)) {
if (this.value.length) {
this.value = this.value[0]
} else {
this.value = undefined
}
}
}
},
valueModel(value) {
if (this.metadata.inTable) {
this.value = value
@ -159,7 +189,8 @@ export default {
return selected
},
async getDataLookupItem() {
if (this.isEmptyValue(this.metadata.reference.directQuery)) {
if (this.isEmptyValue(this.metadata.reference.directQuery) ||
(this.metadata.isAdvancedQuery && this.isSelectMultiple)) {
return
}
this.isLoading = true
@ -234,8 +265,16 @@ export default {
}
</script>
<style scoped>
.select-base {
<style lang="scss">
.custom-field-select {
width: 100%;
}
.custom-field-select-multiple {
overflow: auto;
max-height: 100px;
.el-select__tags {
max-height: 100px;
}
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<el-select
v-model="value"
multiple
filterable
allow-create
:placeholder="metadata.help"
class="custom-field-select custom-field-select-multiple"
@change="preHandleChange"
>
<el-option
v-for="(option, key) in value"
:key="key"
:value="option"
/>
</el-select>
</template>
<script>
import { fieldMixin } from '@/components/ADempiere/Field/FieldMixin'
/**
* This component is a list type field, for IN and NOT IN search with advanced query
*/
export default {
name: 'FieldSelectMultiple',
mixins: [fieldMixin],
methods: {
preHandleChange(value) {
this.handleChange(value)
}
}
}
</script>

View File

@ -0,0 +1,98 @@
<template>
<span>
<el-popover
ref="operatorComarison"
placement="top"
width="200"
trigger="click"
>
<span class="custom-tittle-popover">
{{ $t('operators.operator') }}:
</span>
<el-select
v-model="value"
@change="changeOperator"
>
<el-option
v-for="(item, key) in operatorsList"
:key="key"
:value="item"
:label="$t('operators.' + item)"
/>
</el-select>
</el-popover>
<span v-popover:operatorComarison>
{{ fieldAttributes.name }}
</span>
</span>
</template>
<script>
import { FIELD_OPERATORS_LIST } from '@/utils/ADempiere/dataUtils'
export default {
name: 'FieldOperatorComparison',
props: {
fieldAttributes: {
type: Object,
required: true
}
},
data() {
return {
value: this.fieldAttributes.operator
}
},
computed: {
operatorsList() {
const { conditionsList } = FIELD_OPERATORS_LIST.find(item => {
return item.type === this.fieldAttributes.componentPath
})
return conditionsList
}
},
watch: {
'fieldAttributes.operator'(newValue) {
this.value = newValue
if (!this.isEmptyValue(this.fieldAttributes.value) ||
['NULL', 'NOT_NULL'].includes(this.fieldAttributes.operator)) {
this.handleChange(this.fieldAttributes.value)
}
}
},
methods: {
changeOperator(value) {
this.$store.dispatch('changeFieldAttribure', {
containerUuid: this.fieldAttributes.containerUuid,
columnName: this.fieldAttributes.columnName,
isAdvancedQuery: true,
attributeName: 'operator',
attributeValue: value
})
},
/**
* @param {mixed} value, main value in component
* @param {mixed} valueTo, used in end value in range
* @param {string} label, or displayColumn to show in select
*/
handleChange(value) {
const sendParameters = {
parentUuid: this.fieldAttributes.parentUuid,
containerUuid: this.fieldAttributes.containerUuid,
field: this.fieldAttributes,
panelType: this.fieldAttributes.panelType,
columnName: this.fieldAttributes.columnName,
newValue: value === 'NotSend' ? this.value : value,
isAdvancedQuery: this.fieldAttributes.isAdvancedQuery,
isSendToServer: !(value === 'NotSend' || this.fieldAttributes.isAdvancedQuery),
isSendCallout: !(value === 'NotSend' || this.fieldAttributes.isAdvancedQuery)
}
this.$store.dispatch('notifyFieldChange', {
...sendParameters,
isChangedOldValue: this.fieldAttributes.componentPath === 'FieldYesNo' && Boolean(value === 'NotSend')
})
}
}
}
</script>

View File

@ -9,10 +9,10 @@
>
<div>
<span class="custom-tittle-popover">
{{ name }}
{{ fieldAttributes.name }}
</span>
<template v-if="!isEmptyValue(help)">
: {{ help }}
<template v-if="!isEmptyValue(fieldAttributes.help)">
: {{ fieldAttributes.help }}
</template>
</div>
<el-form-item
@ -66,29 +66,13 @@ import { getLanguage } from '@/lang/index'
export default {
name: 'FieldTranslated',
props: {
containerUuid: {
type: String,
fieldAttributes: {
type: Object,
required: true
},
columnName: {
type: String,
required: true
},
name: {
type: String,
default: undefined
},
help: {
type: String,
default: undefined
},
recordUuid: {
type: String,
default: undefined
},
tableName: {
type: String,
required: true
}
},
data() {
@ -112,7 +96,7 @@ export default {
},
getterTranslationValues() {
const values = this.$store.getters.getTranslationByLanguage({
containerUuid: this.containerUuid,
containerUuid: this.fieldAttributes.containerUuid,
language: this.langValue,
recordUuid: this.recordUuid
})
@ -126,7 +110,7 @@ export default {
if (this.isEmptyValue(values)) {
return undefined
}
return values[this.columnName]
return values[this.fieldAttributes.columnName]
}
},
watch: {
@ -154,9 +138,9 @@ export default {
getTranslationsFromServer() {
this.isLoading = true
this.$store.dispatch('getTranslationsFromServer', {
containerUuid: this.containerUuid,
containerUuid: this.fieldAttributes.containerUuid,
recordUuid: this.recordUuid,
tableName: this.tableName,
tableName: this.fieldAttributes.tableName,
language: this.langValue
})
.finally(() => {
@ -165,9 +149,9 @@ export default {
},
changeTranslationValue(value) {
this.$store.dispatch('changeTranslationValue', {
containerUuid: this.containerUuid,
containerUuid: this.fieldAttributes.containerUuid,
language: this.langValue,
columnName: this.columnName,
columnName: this.fieldAttributes.columnName,
value
})
}

View File

@ -6,7 +6,7 @@
<el-col
v-if="!inTable"
v-show="isDisplayed()"
key="panel-template"
key="is-panel-template"
:xs="sizeFieldResponsive.xs"
:sm="sizeFieldResponsive.sm"
:md="sizeFieldResponsive.md"
@ -18,22 +18,26 @@
:required="isMandatory()"
>
<template slot="label">
<field-context-info
v-if="(field.contextInfo && field.contextInfo.isActive) || field.reference.zoomWindowList.length"
<field-operator-comparison
v-if="isAdvancedQuery && isDisplayed()"
key="is-field-operator-comparison"
:field-attributes="fieldAttributes"
:field-value="field.value"
/>
<template v-else>
<field-context-info
v-else-if="(field.contextInfo && field.contextInfo.isActive) || field.reference.zoomWindowList.length"
key="is-field-context-info"
:field-attributes="fieldAttributes"
:field-value="field.value"
/>
<span v-else key="is-field-name">
{{ isFieldOnly() }}
</template>
</span>
<field-translated
v-if="field.isTranslated && !isAdvancedQuery"
:name="field.name"
:help="field.help"
:container-uuid="containerUuid"
:column-name="field.columnName"
:field-attributes="fieldAttributes"
:record-uuid="field.optionCRUD"
:table-name="field.tableName"
/>
</template>
<component
@ -47,7 +51,7 @@
<component
:is="componentRender"
v-else
key="table-template"
key="is-table-template"
:class="classField"
:metadata="fieldAttributes"
:value-model="recordDataFields"
@ -57,6 +61,7 @@
<script>
import FieldContextInfo from '@/components/ADempiere/Field/fieldContextInfo'
import FieldTranslated from '@/components/ADempiere/Field/fieldTranslated'
import FieldOperatorComparison from '@/components/ADempiere/Field/fieldOperatorComparison'
import { FIELD_ONLY } from '@/components/ADempiere/Field/references'
import { DEFAULT_SIZE } from '@/components/ADempiere/Field/fieldSize'
import { fieldIsDisplayed } from '@/utils/ADempiere'
@ -71,7 +76,8 @@ export default {
name: 'Field',
components: {
FieldContextInfo,
FieldTranslated
FieldTranslated,
FieldOperatorComparison
},
props: {
parentUuid: {
@ -120,6 +126,9 @@ export default {
computed: {
// load the component that is indicated in the attributes of received property
componentRender() {
if (this.isSelectCreated) {
return () => import(`@/components/ADempiere/Field/FieldSelectMultiple`)
}
return () => import(`@/components/ADempiere/Field/${this.field.componentPath}`)
},
fieldAttributes() {
@ -132,9 +141,15 @@ export default {
required: this.isMandatory(),
readonly: this.isReadOnly(),
displayed: this.isDisplayed(),
disabled: !this.field.isActive
disabled: !this.field.isActive,
isSelectCreated: this.isSelectCreated
}
},
isSelectCreated() {
return this.isAdvancedQuery &&
!['FieldBinary', 'FieldDate', 'FieldSelect', 'FieldYesNo'].includes(this.field.componentPath) &&
['IN', 'NOT_IN'].includes(this.field.operator)
},
getWidth() {
return this.$store.getters.getWidthLayout
},

View File

@ -273,7 +273,7 @@ export default {
notes: 'Notes',
changeLog: 'Change Log',
workflowLog: 'Workflow Log',
changeDetail: 'Detalle del cambio',
changeDetail: 'Change detail',
logWorkflow: {
message: 'Message',
responsible: 'Responsible',
@ -298,5 +298,21 @@ export default {
sequence: {
available: 'Available',
sequence: 'Sequence'
},
operators: {
operator: 'Comparison operator',
EQUAL: 'Equal to "="',
NOT_EQUAL: 'Not equal to "<>"',
LIKE: 'Like "~"',
NOT_LIKE: 'Not like "!~"',
GREATER: 'Greater than ">"',
GREATER_EQUAL: 'Greater than equal to ">="',
LESS: 'Less than "<"',
LESS_EQUAL: 'Less than equal to "<="',
BETWEEN: 'Between ">-<"',
NOT_NULL: 'Is not null',
NULL: 'Is null',
IN: 'Include',
NOT_IN: 'Not include'
}
}

View File

@ -273,5 +273,21 @@ export default {
sequence: {
available: 'Disponibles',
sequence: 'Secuencia'
},
operators: {
operator: 'Operador de comparación',
EQUAL: 'Igual a "="',
NOT_EQUAL: 'Diferente a "<>"',
LIKE: 'Contiene "~"',
NOT_LIKE: 'No contiene "!~"',
GREATER: 'Mayor que ">"',
GREATER_EQUAL: 'Mayor o igual que ">="',
LESS: 'Menor que "<"',
LESS_EQUAL: 'Menor o igual que "<="',
BETWEEN: 'Entre ">-<"',
NULL: 'No tiene valor',
NOT_NULL: 'Tiene un valor',
IN: 'Incluye',
NOT_IN: 'No incluye'
}
}

View File

@ -450,12 +450,12 @@ const data = {
* @param {string} query, criteria to search record data
* @param {string} whereClause, criteria to search record data
* @param {string} orderByClause, criteria to search record data
* @param {array} conditions, conditions to criteria
* @param {array} conditionsList, conditions list to criteria
*/
getObjectListFromCriteria({ commit, dispatch, getters, rootGetters }, parameters) {
const {
parentUuid, containerUuid,
tableName, query, whereClause, orderByClause, conditions = [],
tableName, query, whereClause, orderByClause, conditionsList = [],
isShowNotification = true, isParentTab = true, isAddRecord = false
} = parameters
if (isShowNotification) {
@ -483,7 +483,7 @@ const data = {
commit('addInGetting', {
containerUuid,
tableName,
conditions
conditionsList
})
// gets the default value of the fields (including whether it is empty or undefined)
@ -496,7 +496,7 @@ const data = {
tableName,
query,
whereClause,
conditions,
conditionsList,
orderByClause,
nextPageToken
})

View File

@ -43,6 +43,9 @@ const panel = {
changeFieldList(state, payload) {
payload.fieldList = payload.newFieldList
},
changeField(state, payload) {
payload.field = payload.newField
},
changeFieldValue(state, payload) {
payload.field.oldValue = payload.field.value
payload.field.value = payload.newValue
@ -134,17 +137,18 @@ const panel = {
groupField
}) {
const panel = getters.getPanel(containerUuid, isAdvancedQuery)
var newPanel = panel
var showsFieldsWithValue = false
var hiddenFieldsWithValue = false
var newFields = panel.fieldList.map(itemField => {
const newPanel = panel
let showsFieldsWithValue = false
let hiddenFieldsWithValue = false
newPanel.fieldList = panel.fieldList.map(itemField => {
const isMandatory = itemField.isMandatory || itemField.isMandatoryFromLogic
if (!isMandatory && fieldIsDisplayed(itemField)) {
if (isAdvancedQuery || itemField.groupAssigned === groupField) {
if (fieldsUser.length && fieldsUser.includes(itemField.columnName)) {
// if it isShowedFromUser it is false, and it has some value, it means
// that it is going to show, therefore the SmartBrowser must be searched
if (!isEmptyValue(itemField.value) && !itemField.isShowedFromUser) {
if ((!isEmptyValue(itemField.value) && !itemField.isShowedFromUser) ||
(isAdvancedQuery && ['NULL', 'NOT_NULL'].includes(itemField.operator))) {
showsFieldsWithValue = true
}
if (isAdvancedQuery) {
@ -155,7 +159,8 @@ const panel = {
}
// if it isShowedFromUser it is true, and it has some value, it means
// that it is going to hidden, therefore the SmartBrowser must be searched
if (!isEmptyValue(itemField.value) && itemField.isShowedFromUser) {
if ((!isEmptyValue(itemField.value) && itemField.isShowedFromUser) ||
(isAdvancedQuery && ['NULL', 'NOT_NULL'].includes(itemField.operator))) {
hiddenFieldsWithValue = true
}
if (isAdvancedQuery) {
@ -168,7 +173,8 @@ const panel = {
if (fieldsUser.length && fieldsUser.includes(itemField.columnName)) {
// if it isShowedFromUser it is false, and it has some value, it means
// that it is going to show, therefore the SmartBrowser must be searched
if (!isEmptyValue(itemField.value) && !itemField.isShowedFromUser) {
if ((!isEmptyValue(itemField.value) && !itemField.isShowedFromUser) ||
(isAdvancedQuery && ['NULL', 'NOT_NULL'].includes(itemField.operator))) {
showsFieldsWithValue = true
}
if (isAdvancedQuery) {
@ -177,7 +183,8 @@ const panel = {
itemField.isShowedFromUser = true
return itemField
}
if (!isEmptyValue(itemField.value) && itemField.isShowedFromUser) {
if ((!isEmptyValue(itemField.value) && itemField.isShowedFromUser) ||
(isAdvancedQuery && ['NULL', 'NOT_NULL'].includes(itemField.operator))) {
hiddenFieldsWithValue = true
}
if (isAdvancedQuery) {
@ -188,34 +195,34 @@ const panel = {
}
return itemField
})
panel.fieldList = newFields
commit('changePanel', {
containerUuid,
newPanel,
panel
panel,
newPanel
})
if (showsFieldsWithValue || hiddenFieldsWithValue) {
// Updated record result
if (panel.panelType === 'browser') {
dispatch('getBrowserSearch', {
containerUuid: panel.uuid,
containerUuid,
isClearSelection: true
})
} else if (panel.panelType === 'table' && panel.isAdvancedQuery) {
dispatch('getObjectListFromCriteria', {
parentUuid: panel.parentUuid,
containerUuid: panel.uuid,
containerUuid,
tableName: panel.tableName,
query: panel.query,
whereClause: panel.whereClause,
conditions: getters.getParametersToServer({
conditionsList: getters.getParametersToServer({
containerUuid,
isAdvancedQuery: true,
isAdvancedQuery,
isEvaluateMandatory: false
})
})
.catch(error => {
console.warn(`Error getting Advanced Query (changeFieldShowedFromUser): ${error.message}. Code: ${error.code}`)
console.warn(`Error getting Advanced Query (changeFieldShowedFromUser): ${error.message}. Code: ${error.code}.`)
})
}
}
@ -466,28 +473,30 @@ const panel = {
* @param {array} withOutColumnNames
*/
notifyFieldChange({ commit, dispatch, getters }, {
parentUuid, containerUuid, panelType = 'window', isAdvancedQuery = false, columnName,
newValue, valueTo, displayColumn,
parentUuid, containerUuid, panelType = 'window', isAdvancedQuery = false,
columnName, newValue, valueTo, displayColumn,
isSendToServer = true, isSendCallout = true,
isChangedOldValue = false, withOutColumnNames = []
}) {
const panel = getters.getPanel(containerUuid, isAdvancedQuery)
var fieldList = panel.fieldList
const fieldList = panel.fieldList
// get field
var field = fieldList.find(fieldItem => fieldItem.columnName === columnName)
const field = fieldList.find(fieldItem => fieldItem.columnName === columnName)
newValue = parsedValueComponent({
fieldType: field.componentPath,
referenceType: field.referenceType,
value: newValue
})
if (field.isRange) {
valueTo = parsedValueComponent({
if (!(isAdvancedQuery && ['IN', 'NOT_IN'].includes(field.operator))) {
newValue = parsedValueComponent({
fieldType: field.componentPath,
referenceType: field.referenceType,
value: valueTo
value: newValue
})
if (field.isRange) {
valueTo = parsedValueComponent({
fieldType: field.componentPath,
referenceType: field.referenceType,
value: valueTo
})
}
}
if (!(panelType === 'table' || isAdvancedQuery)) {
@ -584,7 +593,7 @@ const panel = {
})
}
if (field.panelType === 'window' && fieldIsDisplayed(field)) {
var uuid = getters.getUuid(containerUuid)
const uuid = getters.getUuid(containerUuid)
if (isEmptyValue(uuid)) {
dispatch('createNewEntity', {
parentUuid,
@ -605,7 +614,7 @@ const panel = {
message: error.message,
type: 'error'
})
console.warn(`Create Entity Error ${error.code}: ${error.message}`)
console.warn(`Create Entity Error ${error.code}: ${error.message}.`)
})
} else {
dispatch('updateCurrentEntity', {
@ -647,7 +656,9 @@ const panel = {
}
} else {
if (panelType === 'table' || isAdvancedQuery) {
if (field.isShowedFromUser && field.oldValue !== field.value) {
if (field.isShowedFromUser && (field.oldValue !== field.value ||
['NULL', 'NOT_NULL'].includes(field.operator) ||
field.operator !== field.oldOperator)) {
// change action to advanced query on field value is changed in this panel
if (router.currentRoute.query.action !== 'advancedQuery') {
router.push({
@ -663,13 +674,20 @@ const panel = {
tableName: panel.tableName,
query: panel.query,
whereClause: panel.whereClause,
conditions: getters.getParametersToServer({
conditionsList: getters.getParametersToServer({
containerUuid,
isAdvancedQuery: true,
isEvaluateMandatory: false
})
})
.then(response => {
commit('changeField', {
field,
newField: {
...field,
oldOperator: field.operator
}
})
if (response && response.length) {
dispatch('notifyPanelChange', {
parentUuid,
@ -683,7 +701,7 @@ const panel = {
}
})
.catch(error => {
console.warn(`Error getting Advanced Query (notifyFieldChange): ${error.message}. Code: ${error.code}`)
console.warn(`Error getting Advanced Query (notifyFieldChange): ${error.message}. Code: ${error.code}.`)
})
}
}
@ -773,6 +791,9 @@ const panel = {
})
})
},
/**
* @deprecated used changeFieldAttribure
*/
notifyFieldChangeDisplayColumn({ commit, getters }, {
containerUuid,
isAdvancedQuery,
@ -843,6 +864,24 @@ const panel = {
newPanel: newPanel
})
},
changeFieldAttribure({ commit, getters }, {
containerUuid,
isAdvancedQuery,
columnName,
field,
attributeName,
attributeValue
}) {
if (isEmptyValue(field)) {
field = getters.getFieldFromColumnName({ containerUuid, isAdvancedQuery, columnName })
}
const newField = field
newField[attributeName] = attributeValue
commit('changeField', {
field,
newField
})
},
dictionaryResetCache({ commit }) {
commit('dictionaryResetCache')
commit('dictionaryResetCacheContext')
@ -1216,7 +1255,7 @@ const panel = {
},
/**
* Getter converter selection params with value format
* [{ columname: name key, value: value to send }]
* [{ columname: name key, value: value to send, operator }]
*/
getParametersToServer: (state, getters) => ({
containerUuid,
@ -1225,16 +1264,15 @@ const panel = {
withOutColumnNames = [],
isEvaluateDisplayed = true,
isEvaluateMandatory = true,
isConvertedDateToTimestamp = false,
isAdvancedQuery = false
}) => {
if (fieldList.length <= 0) {
fieldList = getters.getFieldsListFromPanel(containerUuid, isAdvancedQuery)
}
var parametersRange = []
const parametersRange = []
// filter fields
var parametersList = fieldList
let parametersList = fieldList
.filter(fieldItem => {
// columns to exclude
if (withOutColumnNames.includes(fieldItem.columnName)) {
@ -1256,7 +1294,7 @@ const panel = {
// evaluate displayed fields
if (isEvaluateDisplayed) {
var isDisplayed = fieldIsDisplayed(fieldItem) && (fieldItem.isShowedFromUser || isMandatory)
let isDisplayed = fieldIsDisplayed(fieldItem) && (fieldItem.isShowedFromUser || isMandatory)
if (isAdvancedQuery) {
isDisplayed = fieldItem.isShowedFromUser
}
@ -1267,7 +1305,8 @@ const panel = {
return true
}
} else {
if (!isEmptyValue(fieldItem.value)) {
if (!isEmptyValue(fieldItem.value) || (isAdvancedQuery &&
['NULL', 'NOT_NULL'].includes(fieldItem.operator))) {
return true
}
}
@ -1280,23 +1319,27 @@ const panel = {
// conever parameters
parametersList = parametersList
.map(parameterItem => {
var value = row ? row[parameterItem.columnName] : parameterItem.value
var valueTo = row ? row[`${parameterItem.columnName}_To`] : parameterItem.valueTo
let value = row ? row[parameterItem.columnName] : parameterItem.value
const valueTo = row ? row[`${parameterItem.columnName}_To`] : parameterItem.valueTo
let values = []
if (Array.isArray(value)) {
values = value
if (isAdvancedQuery && ['IN', 'NOT_IN'].includes(parameterItem.operator)) {
if (Array.isArray(value)) {
values = value.map(itemValue => {
const isMandatory = !isAdvancedQuery && (parameterItem.isMandatory || parameterItem.isMandatoryFromLogic)
return parsedValueComponent({
fieldType: parameterItem.componentPath,
value: itemValue,
referenceType: parameterItem.referenceType,
isMandatory
})
})
} else {
values.push(value)
}
value = undefined
}
if (isConvertedDateToTimestamp) {
if (['FieldDate', 'FieldTime'].includes(parameterItem.componentPath) &&
Object.prototype.toString.call(value) === '[object Date]') {
value = value.getTime()
if (valueTo) {
valueTo = valueTo.getTime()
}
}
}
// only to fields type Time, Datea and DateTime
if (parameterItem.isRange && parameterItem.componentPath !== 'FieldNumber') {
parametersRange.push({
@ -1307,9 +1350,10 @@ const panel = {
return {
columnName: parameterItem.columnName,
value: value,
value,
isRange: parameterItem.isRange,
values: values
values,
operator: isAdvancedQuery ? parameterItem.operator : undefined
}
})

View File

@ -606,9 +606,10 @@ const windowControl = {
}
}
const conditions = []
if (tab.isParentTab && !isEmptyValue(tab.tableName) && !isEmptyValue(value)) {
conditions.push({
const conditionsList = []
// TODO: evaluate if overwrite values to conditions
if (!isLoadAllRecords && tab.isParentTab && !isEmptyValue(tab.tableName) && !isEmptyValue(value)) {
conditionsList.push({
columnName: columnName,
value: value
})
@ -620,8 +621,7 @@ const windowControl = {
query: parsedQuery,
whereClause: parsedWhereClause,
orderByClause: tab.orderByClause,
// TODO: evaluate if overwrite values to conditions
conditions: isLoadAllRecords ? [] : conditions,
conditionsList,
isParentTab: tab.isParentTab,
isAddRecord: isAddRecord,
isShowNotification: isShowNotification

View File

@ -0,0 +1,109 @@
export const OPERATORS = [
{
operator: 'EQUAL',
symbol: '='
},
{
operator: 'NOT_EQUAL',
symbol: '<>'
},
{
operator: 'LIKE',
symbol: '%'
},
{
operator: 'NOT_LIKE',
symbol: '!%'
},
{
operator: 'GREATER',
symbol: '>'
},
{
operator: 'GREATER_EQUAL',
symbol: '>='
},
{
operator: 'LESS',
symbol: '<'
},
{
operator: 'LESS_EQUAL',
symbol: '<='
},
{
operator: 'BETWEEN',
symbol: '>-<'
},
{
operator: 'NOT_NULL',
symbol: ''
},
{
operator: 'NULL',
symbol: ''
},
{
operator: 'IN',
symbol: '()'
},
{
operator: 'NOT_IN',
symbol: '!()'
}
]
// Components associated with search type
export const FIELD_OPERATORS_LIST = [
{
type: 'FieldBinary',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldButton',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldDate',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'GREATER', 'GREATER_EQUAL', 'LESS', 'LESS_EQUAL', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldImage',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldNumber',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'GREATER', 'GREATER_EQUAL', 'LESS', 'LESS_EQUAL', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldSelect',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'IN', 'NOT_IN', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldText',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'LIKE', 'NOT_LIKE', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldTextLong',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'LIKE', 'NOT_LIKE', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldTime',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'GREATER', 'GREATER_EQUAL', 'LESS', 'LESS_EQUAL', 'IN', 'NOT_IN', 'NULL', 'NOT_NULL']
},
{
type: 'FieldYesNo',
isRange: false,
conditionsList: ['EQUAL', 'NOT_EQUAL', 'NULL', 'NOT_NULL']
}
]

View File

@ -109,7 +109,11 @@ export function generateField(fieldToGenerate, moreAttributes, typeRange = false
// app attributes
isShowedFromUser,
isShowedTableFromUser: fieldToGenerate.isDisplayed,
isFixedTableColumn: false
isFixedTableColumn: false,
// Advanced query
operator: 'EQUAL', // current operator
oldOperator: undefined, // old operator
defaultOperator: 'EQUAL'
}
// evaluate simple logics without context

View File

@ -334,7 +334,7 @@ export function parsedValueComponent({ fieldType, value, referenceType, isMandat
if (!isNaN(value)) {
value = Number(value)
}
if (typeof value === 'number') {
if (typeof value === 'number' || typeof value === 'string') {
value = new Date(value)
}
if (typeof value === 'object' && value.hasOwnProperty('query')) {