OR in group filter

This commit is contained in:
Jan Prochazka 2022-07-17 19:15:42 +02:00
parent ae963d7a3b
commit 5b4339889f
3 changed files with 70 additions and 46 deletions

View File

@ -79,26 +79,27 @@ export class DesignerQueryDumper {
return select;
}
buildConditionFromFilterField(tables: DesignerTableInfo[], filterField: string): Condition {
buildConditionFromFilterField(tables: DesignerTableInfo[], filterField: string, getExpression?: Function): Condition {
const conditions = [];
for (const column of this.designer.columns || []) {
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;
if (!column.isCustomExpression) {
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[filterField], findDesignerFilterType(column, this.designer));
if (condition) {
conditions.push(
_.cloneDeepWith(condition, expr => {
if (expr.exprType == 'placeholder')
return {
exprType: 'column',
columnName: column.columnName,
source: findQuerySource(this.designer, column.designerId),
};
if (expr.exprType == 'placeholder') {
if (getExpression) return getExpression(column);
return this.getColumnExpression(column);
}
})
);
}
@ -122,45 +123,39 @@ export class DesignerQueryDumper {
};
}
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)));
addConditionsCore(select: Select, tables: DesignerTableInfo[], filterFields, selectField, getExpression?) {
const conditions: Condition[] = _.compact(
filterFields.map(field => this.buildConditionFromFilterField(tables, field, getExpression))
);
if (conditions.length == 0) {
return;
}
if (conditions.length == 0) {
select.where = mergeConditions(select.where, conditions[0]);
select[selectField] = mergeConditions(select[selectField], conditions[0]);
return;
}
select.where = mergeConditions(select.where, {
select[selectField] = mergeConditions(select[selectField], {
conditionType: 'or',
conditions,
});
}
addGroupConditions(select: Select, tables: DesignerTableInfo[], selectIsGrouped: boolean) {
for (const column of this.designer.columns || []) {
if (!column.groupFilter) continue;
const table = (this.designer.tables || []).find(x => x.designerId == column.designerId);
if (!table) continue;
if (!tables.find(x => x.designerId == table.designerId)) continue;
addConditions(select: Select, tables: DesignerTableInfo[]) {
const additionalFilterCount = this.designer.settings?.additionalFilterCount || 0;
const filterFields = ['filter', ..._.range(additionalFilterCount).map(index => `additionalFilter${index + 1}`)];
this.addConditionsCore(select, tables, filterFields, 'where');
}
const condition = parseFilter(column.groupFilter, findDesignerFilterType(column, this.designer));
if (condition) {
select.having = mergeConditions(
select.having,
_.cloneDeepWith(condition, expr => {
if (expr.exprType == 'placeholder') {
return this.getColumnResultField(column, selectIsGrouped);
}
})
);
}
}
addGroupConditions(select: Select, tables: DesignerTableInfo[], selectIsGrouped: boolean) {
const additionalGroupFilterCount = this.designer.settings?.additionalGroupFilterCount || 0;
const filterFields = [
'groupFilter',
..._.range(additionalGroupFilterCount).map(index => `additionalGroupFilter${index + 1}`),
];
this.addConditionsCore(select, tables, filterFields, 'having', column =>
this.getColumnResultField(column, selectIsGrouped)
);
}
getColumnExpression(col): Expression {

View File

@ -38,6 +38,7 @@ export type DesignerColumnInfo = {
export type DesignerSettings = {
isDistinct?: boolean;
additionalFilterCount?: number;
additionalGroupFilterCount?: number;
};
export type DesignerInfo = {

View File

@ -65,6 +65,26 @@
}));
};
const addGroupOrCondition = () => {
onChange(current => ({
...current,
settings: {
...current?.settings,
additionalGroupFilterCount: (current?.settings?.additionalGroupFilterCount ?? 0) + 1,
},
}));
};
const removeGroupOrCondition = () => {
onChange(current => ({
...current,
settings: {
...current?.settings,
additionalGroupFilterCount: (current?.settings?.additionalGroupFilterCount ?? 1) - 1,
},
}));
};
$: columns = value?.columns;
$: tables = value?.tables;
$: settings = value?.settings;
@ -89,7 +109,18 @@
slot: 5,
props: { filterField: `additionalFilter${index + 1}` },
})),
hasGroupedColumn && { fieldName: 'groupFilter', header: 'Group filter', slot: 6 },
hasGroupedColumn && {
fieldName: 'groupFilter',
header: 'Group filter',
slot: 5,
props: { filterField: 'groupFilter' },
},
..._.range(hasGroupedColumn ? settings?.additionalGroupFilterCount || 0 : 0).map(index => ({
fieldName: `additionalGroupFilter${index + 1}`,
header: `OR group filter ${index + 2}`,
slot: 5,
props: { filterField: `additionalGroupFilter${index + 1}` },
})),
{ fieldName: 'actions', header: '', slot: 7 },
]}
>
@ -175,15 +206,6 @@
}}
/>
</svelte:fragment>
<svelte:fragment slot="6" let:row>
<DataFilterControl
filterType={findDesignerFilterType(row, value)}
filter={row.groupFilter}
setFilter={groupFilter => {
changeColumn({ ...row, groupFilter });
}}
/>
</svelte:fragment>
<svelte:fragment slot="7" let:row>
<InlineButton on:click={() => removeColumn(row)}>Remove</InlineButton>
</svelte:fragment>
@ -193,6 +215,12 @@
{#if settings?.additionalFilterCount > 0}
<FormStyledButton value="Remove OR condition" on:click={removeOrCondition} style="width:200px" />
{/if}
{#if hasGroupedColumn}
<FormStyledButton value="Add group OR condition" on:click={addGroupOrCondition} style="width:200px" />
{/if}
{#if hasGroupedColumn && settings?.additionalGroupFilterCount > 0}
<FormStyledButton value="Remove group OR condition" on:click={removeGroupOrCondition} style="width:200px" />
{/if}
</div>
<style>