Add between and not between operators functionality
This commit is contained in:
parent
ba15a3ba96
commit
f761d0183b
@ -86,20 +86,48 @@
|
|||||||
v-model="filter.operator"
|
v-model="filter.operator"
|
||||||
:options="getOperators(filter.kind, getField(filter.name))"
|
:options="getOperators(filter.kind, getField(filter.name))"
|
||||||
class="d-flex field-operator w-100"
|
class="d-flex field-operator w-100"
|
||||||
|
@change="updateFilterProperties(filter)"
|
||||||
/>
|
/>
|
||||||
</b-td>
|
</b-td>
|
||||||
<b-td
|
<b-td
|
||||||
v-if="getField(filter.name)"
|
v-if="getField(filter.name)"
|
||||||
>
|
>
|
||||||
<field-editor
|
<template v-if="isBetweenOperator(filter.operator)">
|
||||||
v-bind="mock"
|
<template
|
||||||
class="field-editor mb-0"
|
v-if="getField(`${filter.name}-start`)"
|
||||||
value-only
|
>
|
||||||
:field="getField(filter.name)"
|
<field-editor
|
||||||
:record="filter.record"
|
v-bind="mock"
|
||||||
:operator="filter.operator"
|
class="field-editor mb-0"
|
||||||
@change="onValueChange"
|
value-only
|
||||||
/>
|
:field="getField(`${filter.name}-start`)"
|
||||||
|
:record="filter.record"
|
||||||
|
@change="onValueChange"
|
||||||
|
/>
|
||||||
|
<span class="text-center my-1 w-100">
|
||||||
|
{{ $t('general.label.and') }}
|
||||||
|
</span>
|
||||||
|
<field-editor
|
||||||
|
v-bind="mock"
|
||||||
|
class="field-editor mb-0"
|
||||||
|
value-only
|
||||||
|
:field="getField(`${filter.name}-end`)"
|
||||||
|
:record="filter.record"
|
||||||
|
@change="onValueChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<field-editor
|
||||||
|
v-bind="mock"
|
||||||
|
class="field-editor mb-0"
|
||||||
|
value-only
|
||||||
|
:field="getField(filter.name)"
|
||||||
|
:record="filter.record"
|
||||||
|
@change="onValueChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
</b-td>
|
</b-td>
|
||||||
<b-td
|
<b-td
|
||||||
v-if="getField(filter.name)"
|
v-if="getField(filter.name)"
|
||||||
@ -390,16 +418,27 @@ export default {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const betweenOperators = [
|
||||||
|
{
|
||||||
|
value: 'BETWEEN',
|
||||||
|
text: this.$t('recordList.filter.operators.between'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'NOT BETWEEN',
|
||||||
|
text: this.$t('recordList.filter.operators.notBetween'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
if (field.multi) {
|
if (field.multi) {
|
||||||
return inOperators
|
return inOperators
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case 'Number':
|
case 'Number':
|
||||||
return [...operators, ...lgOperators]
|
return [...operators, ...lgOperators, ...betweenOperators]
|
||||||
|
|
||||||
case 'DateTime':
|
case 'DateTime':
|
||||||
return [...operators, ...lgOperators]
|
return [...operators, ...lgOperators, ...betweenOperators]
|
||||||
|
|
||||||
case 'String':
|
case 'String':
|
||||||
case 'Url':
|
case 'Url':
|
||||||
@ -499,8 +538,21 @@ export default {
|
|||||||
filter = filter.map(({ value, ...f }) => {
|
filter = filter.map(({ value, ...f }) => {
|
||||||
f.record = new compose.Record(this.mock.module, {})
|
f.record = new compose.Record(this.mock.module, {})
|
||||||
|
|
||||||
// If its a system field add value to root of record
|
if (this.isBetweenOperator(f.operator)) {
|
||||||
if (Object.keys(f.record).includes(f.name)) {
|
if (this.getField(f.name).isSystem) {
|
||||||
|
f.record[`${f.name}-start`] = value.start
|
||||||
|
f.record[`${f.name}-end`] = value.end
|
||||||
|
} else {
|
||||||
|
f.record.values[`${f.name}-start`] = value.start
|
||||||
|
f.record.values[`${f.name}-end`] = value.end
|
||||||
|
}
|
||||||
|
|
||||||
|
const field = this.mock.module.fields.find(field => field.name === f.name)
|
||||||
|
|
||||||
|
this.mock.module.fields.push({ ...field, name: `${f.name}-end` })
|
||||||
|
this.mock.module.fields.push({ ...field, name: `${f.name}-start` })
|
||||||
|
} else if (Object.keys(f.record).includes(f.name)) {
|
||||||
|
// If its a system field add value to root of record
|
||||||
f.record[f.name] = value
|
f.record[f.name] = value
|
||||||
} else {
|
} else {
|
||||||
f.record.values[f.name] = value
|
f.record.values[f.name] = value
|
||||||
@ -531,12 +583,35 @@ export default {
|
|||||||
f.value = record[f.name] || record.values[f.name]
|
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 f
|
||||||
})
|
})
|
||||||
|
|
||||||
return { groupCondition, filter }
|
return { groupCondition, filter }
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateFilterProperties (filter) {
|
||||||
|
if (this.isBetweenOperator(filter.operator)) {
|
||||||
|
filter.record.values[`${filter.name}-start`] = filter.record.values[`${filter.name}-start`]
|
||||||
|
filter.record.values[`${filter.name}-end`] = filter.record.values[`${filter.name}-end`]
|
||||||
|
|
||||||
|
const field = this.mock.module.fields.find(f => f.name === filter.name)
|
||||||
|
|
||||||
|
this.mock.module.fields.push({ ...field, name: `${filter.name}-end` })
|
||||||
|
this.mock.module.fields.push({ ...field, name: `${filter.name}-start` })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isBetweenOperator (op) {
|
||||||
|
return ['BETWEEN', 'NOT BETWEEN'].includes(op)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ export function getRecordListFilterSql (filter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fieldFilter = getFieldFilter(f.name, f.kind, f.value, f.operator)
|
const fieldFilter = getFieldFilter(f.name, f.kind, f.value, f.operator)
|
||||||
|
|
||||||
if (fieldFilter) {
|
if (fieldFilter) {
|
||||||
query += getFieldFilter(f.name, f.kind, f.value, f.operator)
|
query += getFieldFilter(f.name, f.kind, f.value, f.operator)
|
||||||
existsPreviousElement = true
|
existsPreviousElement = true
|
||||||
@ -28,9 +29,13 @@ export function getRecordListFilterSql (filter) {
|
|||||||
|
|
||||||
// Helper function that creates a query for a specific field kind
|
// Helper function that creates a query for a specific field kind
|
||||||
export function getFieldFilter (name, kind, query = '', operator = '=') {
|
export function getFieldFilter (name, kind, query = '', operator = '=') {
|
||||||
const boolQuery = toBoolean(query)
|
let boolQuery = query
|
||||||
const numQuery = Number.parseFloat(query)
|
let numQuery = query
|
||||||
|
|
||||||
|
if (typeof query === 'object' && query !== null) {
|
||||||
|
boolQuery = toBoolean(query)
|
||||||
|
numQuery = Number.parseFloat(query)
|
||||||
|
}
|
||||||
const build = (op, left, right) => {
|
const build = (op, left, right) => {
|
||||||
switch (op.toUpperCase()) {
|
switch (op.toUpperCase()) {
|
||||||
case '!=':
|
case '!=':
|
||||||
@ -39,7 +44,10 @@ export function getFieldFilter (name, kind, query = '', operator = '=') {
|
|||||||
case 'IN':
|
case 'IN':
|
||||||
case 'NOT IN':
|
case 'NOT IN':
|
||||||
// flip left/right for IN/NOT IN
|
// flip left/right for IN/NOT IN
|
||||||
return `${right} ${op} ${left}`
|
return `'${right}' ${op} ${left}`
|
||||||
|
case 'BETWEEN':
|
||||||
|
case 'NOT BETWEEN':
|
||||||
|
return `${name} ${op} ${query.start} ${query.end}`
|
||||||
default:
|
default:
|
||||||
return `${left} ${op} ${right}`
|
return `${left} ${op} ${right}`
|
||||||
}
|
}
|
||||||
@ -68,23 +76,43 @@ export function getFieldFilter (name, kind, query = '', operator = '=') {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['Number'].includes(kind) && !isNaN(numQuery)) {
|
if (['Number'].includes(kind)) {
|
||||||
return build(operator, name, `'${numQuery}'`)
|
if (['BETWEEN', 'NOT BETWEEN'].includes(operator)) {
|
||||||
|
return build(operator, name, numQuery)
|
||||||
|
} else if (!isNaN(numQuery)) {
|
||||||
|
return build(operator, name, numQuery)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['DateTime'].includes(kind)) {
|
if (['DateTime'].includes(kind)) {
|
||||||
// Build different querries if date, time or datetime
|
if (['BETWEEN', 'NOT BETWEEN'].includes(operator)) {
|
||||||
const date = moment(query, ['YYYY-MM-DDTHH:mm:ssZ', 'YYYY-MM-DD'])
|
const startDate = moment(query.start, ['YYYY-MM-DDTHH:mm:ssZ', 'YYYY-MM-DD'])
|
||||||
const time = moment(query, ['HH:mm'])
|
const endDate = moment(query.end, ['YYYY-MM-DDTHH:mm:ssZ', 'YYYY-MM-DD'])
|
||||||
|
|
||||||
// @note tweaking the template a bit:
|
const startTime = moment(query.start, ['HH:mm'])
|
||||||
// * adding %f to include fractions; mysql sometimes forces them when formatting date
|
const endTime = moment(query.end, ['HH:mm'])
|
||||||
// * changing Z to +00:00
|
|
||||||
// * doing the same for time-only fields
|
const dataFmtEntry = (date) => `TIMESTAMP(DATE_FORMAT('${date.format()}', '%Y-%m-%dT%H:%i:00.%f+00:00'))`
|
||||||
if (date.isValid()) {
|
|
||||||
return `TIMESTAMP(DATE_FORMAT(${name}, '%Y-%m-%dT%H:%i:00.%f+00:00')) ${operator} TIMESTAMP(DATE_FORMAT('${date.format()}', '%Y-%m-%dT%H:%i:00.%f+00:00'))`
|
if (startDate.isValid() && endDate.isValid()) {
|
||||||
} else if (time.isValid()) {
|
return `TIMESTAMP(DATE_FORMAT(${name}, '%Y-%m-%dT%H:%i:00.%f+00:00')) ${operator} ${dataFmtEntry(startDate)} ${dataFmtEntry(endDate)}`
|
||||||
return `TIME(DATE_FORMAT(${name}, '%Y-%m-%dT%H:%i:00.%f+00:00')) ${operator} TIME('${query}')`
|
} else if (startTime.isValid() && endTime.isValid()) {
|
||||||
|
return `TIME(DATE_FORMAT(${name}, '%Y-%m-%dT%H:%i:00.%f+00:00')) ${operator} TIME('${query.start}') TIME('${query.end}')`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Build different querries if date, time or datetime
|
||||||
|
const date = moment(query, ['YYYY-MM-DDTHH:mm:ssZ', 'YYYY-MM-DD'])
|
||||||
|
const time = moment(query, ['HH:mm'])
|
||||||
|
|
||||||
|
// @note tweaking the template a bit:
|
||||||
|
// * adding %f to include fractions; mysql sometimes forces them when formatting date
|
||||||
|
// * changing Z to +00:00
|
||||||
|
// * doing the same for time-only fields
|
||||||
|
if (date.isValid()) {
|
||||||
|
return `TIMESTAMP(DATE_FORMAT(${name}, '%Y-%m-%dT%H:%i:00.%f+00:00')) ${operator} TIMESTAMP(DATE_FORMAT('${date.format()}', '%Y-%m-%dT%H:%i:00.%f+00:00'))`
|
||||||
|
} else if (time.isValid()) {
|
||||||
|
return `TIME(DATE_FORMAT(${name}, '%Y-%m-%dT%H:%i:00.%f+00:00')) ${operator} TIME('${query}')`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -138,6 +138,7 @@ general:
|
|||||||
save: Save
|
save: Save
|
||||||
search: Search
|
search: Search
|
||||||
magnify: Magnify Block
|
magnify: Magnify Block
|
||||||
|
and: And
|
||||||
module: Module
|
module: Module
|
||||||
style:
|
style:
|
||||||
danger: Danger variant
|
danger: Danger variant
|
||||||
@ -281,6 +282,8 @@ recordList:
|
|||||||
greaterThan: Greater than
|
greaterThan: Greater than
|
||||||
lessThan: Less than
|
lessThan: Less than
|
||||||
notEqual: Not equal
|
notEqual: Not equal
|
||||||
|
between: Between
|
||||||
|
notBetween: Not between
|
||||||
title: Record list filter
|
title: Record list filter
|
||||||
update: Update filter
|
update: Update filter
|
||||||
where: Where
|
where: Where
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user