diff --git a/packages/web/src/designer/DesignerQueryDumper.ts b/packages/web/src/designer/DesignerQueryDumper.ts index 6d367024b..182406e6c 100644 --- a/packages/web/src/designer/DesignerQueryDumper.ts +++ b/packages/web/src/designer/DesignerQueryDumper.ts @@ -79,18 +79,19 @@ export class DesignerQueryDumper { return select; } - addConditions(select: Select, tables: DesignerTableInfo[]) { + buildConditionFromFilterField(tables: DesignerTableInfo[], filterField: string): Condition { + const conditions = []; + for (const column of this.designer.columns || []) { - if (!column.filter) continue; + if (!column[filterField]) continue; const table = (this.designer.tables || []).find(x => x.designerId == column.designerId); if (!table) continue; if (!tables.find(x => x.designerId == table.designerId)) continue; try { - const condition = parseFilter(column.filter, findDesignerFilterType(column, this.designer)); + const condition = parseFilter(column[filterField], findDesignerFilterType(column, this.designer)); if (condition) { - select.where = mergeConditions( - select.where, + conditions.push( _.cloneDeepWith(condition, expr => { if (expr.exprType == 'placeholder') return { @@ -106,6 +107,39 @@ export class DesignerQueryDumper { continue; } } + + if (conditions.length == 0) { + return null; + } + + if (conditions.length == 1) { + return conditions[0]; + } + + return { + conditionType: 'and', + conditions, + }; + } + + addConditions(select: Select, tables: DesignerTableInfo[]) { + const additionalFilterCount = this.designer.settings?.additionalFilterCount || 0; + + const filterFields = ['filter', ..._.range(additionalFilterCount).map(index => `additionalFilter${index + 1}`)]; + + const conditions = _.compact(filterFields.map(field => this.buildConditionFromFilterField(tables, field))); + + if (conditions.length == 0) { + return; + } + if (conditions.length == 0) { + select.where = mergeConditions(select.where, conditions[0]); + return; + } + select.where = mergeConditions(select.where, { + conditionType: 'or', + conditions, + }); } addGroupConditions(select: Select, tables: DesignerTableInfo[], selectIsGrouped: boolean) { diff --git a/packages/web/src/designer/types.ts b/packages/web/src/designer/types.ts index ee77e1e2f..3116116d0 100644 --- a/packages/web/src/designer/types.ts +++ b/packages/web/src/designer/types.ts @@ -37,6 +37,7 @@ export type DesignerColumnInfo = { export type DesignerSettings = { isDistinct?: boolean; + additionalFilterCount?: number; }; export type DesignerInfo = { diff --git a/packages/web/src/elements/QueryDesignColumns.svelte b/packages/web/src/elements/QueryDesignColumns.svelte index dc6195066..e50db5227 100644 --- a/packages/web/src/elements/QueryDesignColumns.svelte +++ b/packages/web/src/elements/QueryDesignColumns.svelte @@ -17,6 +17,7 @@ import TableControl from './TableControl.svelte'; import FormStyledButton from '../buttons/FormStyledButton.svelte'; + import _ from 'lodash'; export let value; export let onChange; @@ -44,8 +45,29 @@ })); }; + const addOrCondition = () => { + onChange(current => ({ + ...current, + settings: { + ...current?.settings, + additionalFilterCount: (current?.settings?.additionalFilterCount ?? 0) + 1, + }, + })); + }; + + const removeOrCondition = () => { + onChange(current => ({ + ...current, + settings: { + ...current?.settings, + additionalFilterCount: (current?.settings?.additionalFilterCount ?? 1) - 1, + }, + })); + }; + $: columns = value?.columns; $: tables = value?.tables; + $: settings = value?.settings; $: hasGroupedColumn = !!(columns || []).find(x => x.isGrouped); @@ -60,7 +82,13 @@ { fieldName: 'isGrouped', header: 'Group by', slot: 2 }, { fieldName: 'aggregate', header: 'Aggregate', slot: 3 }, { fieldName: 'sortOrder', header: 'Sort order', slot: 4 }, - { fieldName: 'filter', header: 'Filter', slot: 5 }, + { fieldName: 'filter', header: 'Filter', slot: 5, props: { filterField: 'filter' } }, + ..._.range(settings?.additionalFilterCount || 0).map(index => ({ + fieldName: `additionalFilter${index + 1}`, + header: `OR Filter ${index + 2}`, + slot: 5, + props: { filterField: `additionalFilter${index + 1}` }, + })), hasGroupedColumn && { fieldName: 'groupFilter', header: 'Group filter', slot: 6 }, { fieldName: 'actions', header: '', slot: 7 }, ]} @@ -138,12 +166,12 @@ ]} /> - + { - changeColumn({ ...row, filter }); + changeColumn({ ...row, [filterField]: filter }); }} /> @@ -161,6 +189,10 @@ + + {#if settings?.additionalFilterCount > 0} + + {/if}