diff --git a/client/web/compose/src/components/Common/RecordListFilter.vue b/client/web/compose/src/components/Common/RecordListFilter.vue
index 037465133..67a30d715 100644
--- a/client/web/compose/src/components/Common/RecordListFilter.vue
+++ b/client/web/compose/src/components/Common/RecordListFilter.vue
@@ -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)"
/>
-
+
+
+
+
+ {{ $t('general.label.and') }}
+
+
+
+
+
+
+
+
{
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)
+ },
},
}
diff --git a/client/web/compose/src/lib/record-filter.js b/client/web/compose/src/lib/record-filter.js
index 1a4261900..590afc0d1 100644
--- a/client/web/compose/src/lib/record-filter.js
+++ b/client/web/compose/src/lib/record-filter.js
@@ -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}')`
+ }
}
}
diff --git a/locale/en/corteza-webapp-compose/block.yaml b/locale/en/corteza-webapp-compose/block.yaml
index 63c3ce4c0..4598f6877 100644
--- a/locale/en/corteza-webapp-compose/block.yaml
+++ b/locale/en/corteza-webapp-compose/block.yaml
@@ -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