From a2043b237f6cf697fc2ced4fc3c3e0e35ebc00bd Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 26 Feb 2023 16:48:32 +0100 Subject: [PATCH] multi column condition in perspectives --- packages/datalib/src/PerspectiveConfig.ts | 2 + packages/datalib/src/PerspectiveTreeNode.ts | 65 ++++++++++++++++++- .../web/src/datagrid/DataFilterControl.svelte | 4 +- .../web/src/designer/DesignerTable.svelte | 10 +++ .../perspectives/PerspectiveDesigner.svelte | 14 ++++ 5 files changed, 91 insertions(+), 4 deletions(-) diff --git a/packages/datalib/src/PerspectiveConfig.ts b/packages/datalib/src/PerspectiveConfig.ts index fd80d83b..c8a421a6 100644 --- a/packages/datalib/src/PerspectiveConfig.ts +++ b/packages/datalib/src/PerspectiveConfig.ts @@ -80,6 +80,8 @@ export interface PerspectiveNodeConfig { isAutoGenerated?: true | undefined; isNodeChecked?: boolean; + multiColumnFilter?: string; + position?: { x: number; y: number; diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index 53db1400..953cd3d7 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -35,7 +35,7 @@ import { PerspectiveDataLoadProps, PerspectiveDataProvider } from './Perspective import stableStringify from 'json-stable-stringify'; import { getFilterType, parseFilter } from 'dbgate-filterparser'; import { FilterType } from 'dbgate-filterparser/lib/types'; -import { Condition, Expression, Select } from 'dbgate-sqltree'; +import { CompoudCondition, Condition, Expression, Select } from 'dbgate-sqltree'; // import { getPerspectiveDefaultColumns } from './getPerspectiveDefaultColumns'; import uuidv1 from 'uuid/v1'; import { PerspectiveDataPatternColumn } from './PerspectiveDataPattern'; @@ -341,10 +341,66 @@ export abstract class PerspectiveTreeNode { ); } + getMutliColumnSqlCondition(source): Condition { + if (!this.nodeConfig?.multiColumnFilter) return null; + const base = this.getBaseTableFromThis() as TableInfo | ViewInfo; + if (!base) return null; + try { + const condition = parseFilter(this.nodeConfig?.multiColumnFilter, 'string'); + if (condition) { + const orCondition: CompoudCondition = { + conditionType: 'or', + conditions: [], + }; + for (const column of base.columns || []) { + orCondition.conditions.push( + _cloneDeepWith(condition, (expr: Expression) => { + if (expr.exprType == 'placeholder') { + return { + exprType: 'column', + alias: source, + columnName: column.columnName, + }; + } + }) + ); + } + if (orCondition.conditions.length > 0) { + return orCondition; + } + } + } catch (err) { + console.warn(err.message); + } + return null; + } + + getMutliColumnMongoCondition(): {} { + if (!this.nodeConfig?.multiColumnFilter) return null; + const pattern = this.dataProvider?.dataPatterns?.[this.designerId]; + if (!pattern) return null; + + const condition = parseFilter(this.nodeConfig?.multiColumnFilter, 'mongo'); + if (!condition) return null; + const res = pattern.columns.map(col => { + return _cloneDeepWith(condition, expr => { + if (expr.__placeholder__) { + return { + [col.name]: expr.__placeholder__, + }; + } + }); + }); + return { + $or: res, + }; + } + getChildrenSqlCondition(source = null): Condition { const conditions = _compact([ ...this.childNodes.map(x => x.parseFilterCondition(source)), ...this.buildParentFilterConditions(), + this.getMutliColumnSqlCondition(source), ]); if (conditions.length == 0) { return null; @@ -359,7 +415,10 @@ export abstract class PerspectiveTreeNode { } getChildrenMongoCondition(source = null): {} { - const conditions = _compact([...this.childNodes.map(x => x.parseFilterCondition(source))]); + const conditions = _compact([ + ...this.childNodes.map(x => x.parseFilterCondition(source)), + this.getMutliColumnMongoCondition(), + ]); if (conditions.length == 0) { return null; } @@ -402,7 +461,7 @@ export abstract class PerspectiveTreeNode { } return res; } - getBaseTableFromThis() { + getBaseTableFromThis(): TableInfo | ViewInfo | CollectionInfo { return null; } diff --git a/packages/web/src/datagrid/DataFilterControl.svelte b/packages/web/src/datagrid/DataFilterControl.svelte index 39d68181..540d4dd9 100644 --- a/packages/web/src/datagrid/DataFilterControl.svelte +++ b/packages/web/src/datagrid/DataFilterControl.svelte @@ -40,6 +40,8 @@ export let columnName = null; export let uniqueName = null; + export let placeholder = 'Filter'; + let value; let isError; let isOk; @@ -318,7 +320,7 @@ on:paste={handlePaste} class:isError class:isOk - placeholder="Filter" + {placeholder} /> {#if customCommandIcon && onCustomCommand} diff --git a/packages/web/src/designer/DesignerTable.svelte b/packages/web/src/designer/DesignerTable.svelte index 3294cd7c..6d58ace2 100644 --- a/packages/web/src/designer/DesignerTable.svelte +++ b/packages/web/src/designer/DesignerTable.svelte @@ -4,6 +4,7 @@ import { tick } from 'svelte'; import { createDatabaseObjectMenu } from '../appobj/DatabaseObjectAppObject.svelte'; + import DataFilterControl from '../datagrid/DataFilterControl.svelte'; import CheckboxField from '../forms/CheckboxField.svelte'; import FontIcon from '../icons/FontIcon.svelte'; @@ -300,6 +301,15 @@ {/if} + {#if settings?.getMutliColumnFilter && settings?.setMutliColumnFilter} + settings?.setMutliColumnFilter(designerId, value)} + placeholder="Data filter" + /> + {/if} +
tick().then(onMoveReferences)} class:scroll={settings?.allowScrollColumns}> {#each flatColumns || [] as column (column.columnName)} column.toggleExpanded(value), getColumnDisplayName: column => column.shortName || column.columnName, getParentColumnName: getPerspectiveParentColumnName, + getMutliColumnFilter: designerId => config.nodes.find(x => x.designerId == designerId).multiColumnFilter, + setMutliColumnFilter: (designerId, multiColumnFilter) => { + setConfig(cfg => ({ + ...cfg, + nodes: cfg.nodes.map(node => + node.designerId == designerId + ? { + ...node, + multiColumnFilter, + } + : node + ), + })); + }, }} referenceComponent={QueryDesignerReference} value={createDesignerModel(config, dbInfos, dataPatterns)}