diff --git a/knowage-vue/src/components/UI/KnParameterSidebar/KnParameterSidebar.d.ts b/knowage-vue/src/components/UI/KnParameterSidebar/KnParameterSidebar.d.ts index 5eef4ace72..6b167c4881 100644 --- a/knowage-vue/src/components/UI/KnParameterSidebar/KnParameterSidebar.d.ts +++ b/knowage-vue/src/components/UI/KnParameterSidebar/KnParameterSidebar.d.ts @@ -34,6 +34,8 @@ export interface iParameter { lovDependentParameters?: iParameter[] driverMaxValue?: string | null driverMaxDateValue?: Date | null + valueColumnNameMetadata?: string + descriptionColumnNameMetadata: string initialValue?: string | number | Date | null } diff --git a/knowage-vue/src/modules/qbe/QBE.d.ts b/knowage-vue/src/modules/qbe/QBE.d.ts index 8bf383db92..7b09c10b17 100644 --- a/knowage-vue/src/modules/qbe/QBE.d.ts +++ b/knowage-vue/src/modules/qbe/QBE.d.ts @@ -117,7 +117,7 @@ export interface iFilter { leftOperandLastValue: any leftOperandLongDescription: string leftOperandType: string - leftOperandValue: string + leftOperandValue: any operator: string promptable: boolean rightOperandAlias?: any diff --git a/knowage-vue/src/modules/qbe/QBE.vue b/knowage-vue/src/modules/qbe/QBE.vue index 1f7418ea3b..8740c6cd60 100644 --- a/knowage-vue/src/modules/qbe/QBE.vue +++ b/knowage-vue/src/modules/qbe/QBE.vue @@ -203,6 +203,7 @@ import calcFieldDescriptor from './QBECalcFieldDescriptor.json' import KnCalculatedField from '@/components/functionalities/KnCalculatedField/KnCalculatedField.vue' import Dropdown from 'primevue/dropdown' import { getCorrectRolesForExecution } from '@/helpers/commons/roleHelper' +import { getFormattedQBECatalogueForAPI } from './QBEHelper' const crypto = require('crypto') const deepcopy = require('deepcopy') @@ -233,7 +234,7 @@ export default defineComponent({ KnCalculatedField, Dropdown }, - props: { visible: { type: Boolean }, dataset: { type: Object }, returnQueryMode: { type: Boolean }, getQueryFromDatasetProp: { type: Boolean }, sourceDataset: { type: Object },fromDsManagement: { type: Boolean, default: false } }, + props: { visible: { type: Boolean }, dataset: { type: Object }, returnQueryMode: { type: Boolean }, getQueryFromDatasetProp: { type: Boolean }, sourceDataset: { type: Object }, fromDsManagement: { type: Boolean, default: false } }, emits: ['close', 'querySaved'], data() { return { @@ -344,7 +345,7 @@ export default defineComponent({ } }) .catch(() => this.$emit('close')) - }else await this.loadPage() + } else await this.loadPage() }, methods: { //#region ===================== Load QBE and format data ==================================================== @@ -599,12 +600,12 @@ export default defineComponent({ } }) }, - async executeQBEQuery(showPreview: boolean) { + async executeQBEQuery(showPreview: boolean, filters?: iFilter[]) { if (!this.qbe) return if (this.qbe.qbeJSONQuery && this.qbe.qbeJSONQuery.catalogue.queries[0].fields.length == 0) return this.loading = true - const postData = { catalogue: this.qbe?.qbeJSONQuery?.catalogue.queries, meta: this.formatQbeMeta(), pars: this.qbe?.pars, qbeJSONQuery: {}, schedulingCronLine: '0 * * * * ?' } + const postData = { catalogue: getFormattedQBECatalogueForAPI(this.qbe?.qbeJSONQuery?.catalogue.queries, filters), meta: this.formatQbeMeta(), pars: this.qbe?.pars, qbeJSONQuery: {}, schedulingCronLine: '0 * * * * ?' } await this.$http .post(process.env.VUE_APP_QBE_PATH + `qbequery/executeQuery/?SBI_EXECUTION_ID=${this.uniqueID}¤tQueryId=${this.selectedQuery.id}&start=${this.pagination.start}&limit=${this.pagination.limit}`, postData) .then((response: AxiosResponse) => { diff --git a/knowage-vue/src/modules/qbe/QBEFilterService.ts b/knowage-vue/src/modules/qbe/QBEFilterService.ts index d27ed71b9a..fa43671abd 100644 --- a/knowage-vue/src/modules/qbe/QBEFilterService.ts +++ b/knowage-vue/src/modules/qbe/QBEFilterService.ts @@ -25,7 +25,7 @@ export function onFiltersSaveCallback(filters: iFilter[], field: iField, paramet qbe.pars = parameters ? [...parameters] : [] if (smartView) { - executeQBEQuery(false) + executeQBEQuery(false, filters) } } @@ -63,4 +63,4 @@ export function removeDeletedFilters(filters: iFilter[], field: iField, expressi } } } -} \ No newline at end of file +} diff --git a/knowage-vue/src/modules/qbe/QBEHelper.ts b/knowage-vue/src/modules/qbe/QBEHelper.ts new file mode 100644 index 0000000000..ee85490706 --- /dev/null +++ b/knowage-vue/src/modules/qbe/QBEHelper.ts @@ -0,0 +1,81 @@ +import { localeDate } from '@/helpers/commons/localeHelper' +import { iFilter } from './QBE' +import moment from 'moment' +import deepcopy from 'deepcopy' + +export const getFormattedQBECatalogueForAPI = (qbeCatalogue: any, filters: iFilter[] | undefined) => { + if (!filters) return qbeCatalogue + + const tempCatalogue = deepcopy(qbeCatalogue) + + const filtersCopy = filters.map((filter) => ({ ...filter })) + + filtersCopy.forEach((filter: iFilter) => { + const isDateOrTimestamp = ['DATE', 'TIMESTAMP'].includes(filter.leftOperandValue?.type) + const isCaluclatedField = filter.leftOperandType === 'inline.calculated.field' + if (isDateOrTimestamp && isCaluclatedField) formatManualDate(filter, tempCatalogue) + }) + + return tempCatalogue +} + +const formatManualDate = (filter: iFilter, qbeCatalogue: any) => { + const serverFormat = 'DD/MM/YYYY hh:mm' + const format = localeDate() + .replace(/yyyy/g, 'YYYY') + .replace(/dd/g, 'DD') + .replace(/d/g, 'D') + .replace(/MM/g, 'MM') + .replace(/M/g, 'M') + .replace(/hh/g, 'HH') + .replace(/mm/g, 'mm') + .replace(/ss/g, 'ss') + .replace(/SSS/g, 'SSS') + const momentDate = moment(filter.rightOperandDescription, format, true) + + if (momentDate.isValid()) { + const formattedDate = momentDate.format(serverFormat) + const properDateForAPI = truncateDateTimeForAPI(formattedDate) + filter.rightOperandValue = [properDateForAPI] + filter.rightOperandDescription = properDateForAPI + } else { + filter.rightOperandValue = [] + filter.rightOperandDescription = '' + } + + updateFilterRightOperandValue(qbeCatalogue, filter) +} + +const updateFilterRightOperandValue = (qbeCatalogue: any[], qbeFilter: iFilter) => { + if (!Array.isArray(qbeCatalogue)) return + + qbeCatalogue.forEach((catalogue) => { + if (!catalogue?.filters || !catalogue?.expression) return + + const filterToUpdate = catalogue.filters.find((filter: iFilter) => filter.filterId === qbeFilter.filterId) + + if (filterToUpdate) { + filterToUpdate.rightOperandValue = qbeFilter.rightOperandValue + filterToUpdate.rightOperandDescription = qbeFilter.rightOperandDescription + + const updateExpressionTree = (node: any): void => { + if (!node) return + + if (node.value.includes(qbeFilter.filterId)) node.details.rightOperandValue = qbeFilter.rightOperandValue + + if (node.childNodes && Array.isArray(node.childNodes)) { + node.childNodes.forEach(updateExpressionTree) + } + } + + updateExpressionTree(catalogue.expression) + } + }) +} + +function truncateDateTimeForAPI(dateTime: string | null | undefined) { + if (!dateTime || dateTime.trim() === '') { + return '' + } + return dateTime.split(' ')[0] +} diff --git a/knowage-vue/src/modules/qbe/qbeDialogs/qbeFilterDialog/QBEFilterCard.vue b/knowage-vue/src/modules/qbe/qbeDialogs/qbeFilterDialog/QBEFilterCard.vue index 582592bf32..a89aeb876e 100644 --- a/knowage-vue/src/modules/qbe/qbeDialogs/qbeFilterDialog/QBEFilterCard.vue +++ b/knowage-vue/src/modules/qbe/qbeDialogs/qbeFilterDialog/QBEFilterCard.vue @@ -121,7 +121,6 @@ import Dropdown from 'primevue/dropdown' import QBEFilterDialogDescriptor from './QBEFilterDialogDescriptor.json' import QBEFilterValuesTable from './QBEFilterValuesTable.vue' import moment from 'moment' -import { localeDate } from '@/helpers/commons/localeHelper' export default defineComponent({ name: 'qbe-filter-card', @@ -308,23 +307,9 @@ export default defineComponent({ }, onManualValueChange() { if (this.filter) { - const isDateOrTimestamp = ['DATE', 'TIMESTAMP'].includes(this.field?.id?.type) - if (isDateOrTimestamp) this.formatManualDate() this.filter.rightOperandValue = [this.filter.rightOperandDescription] } }, - formatManualDate() { - if (!this.filter) return - - const serverFormat = 'DD/MM/YYYY hh:mm' - const format = localeDate().replace(/yyyy/g, 'YYYY').replace(/dd/g, 'DD').replace(/d/g, 'D').replace(/MM/g, 'MM').replace(/M/g, 'M').replace(/hh/g, 'HH').replace(/mm/g, 'mm').replace(/ss/g, 'ss').replace(/SSS/g, 'SSS') - const momentDate = moment(this.filter.rightOperandDescription, format, true) - - if (momentDate.isValid()) { - const formattedDate = momentDate.format(serverFormat) - this.filter.rightOperandDescription = formattedDate - } - }, onManualBetweenChange() { if (this.filter) { this.filter.rightOperandValue = [this.firstOperand, this.secondOperand]