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