From 0cb4ec54bc3ec73a55911cf8984ac1cb4bcc0d0b Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 12 Jun 2022 19:30:54 +0200 Subject: [PATCH 001/132] perspective WIP --- .../src/appobj/DatabaseObjectAppObject.svelte | 12 ++++ packages/web/src/icons/FontIcon.svelte | 1 + .../perspectives/PerspectiveColumns.svelte | 0 .../src/perspectives/PerspectiveCore.svelte | 0 .../src/perspectives/PerspectiveView.svelte | 57 +++++++++++++++++++ packages/web/src/tabs/PerspectiveTab.svelte | 11 ++++ packages/web/src/tabs/index.js | 2 + 7 files changed, 83 insertions(+) create mode 100644 packages/web/src/perspectives/PerspectiveColumns.svelte create mode 100644 packages/web/src/perspectives/PerspectiveCore.svelte create mode 100644 packages/web/src/perspectives/PerspectiveView.svelte create mode 100644 packages/web/src/tabs/PerspectiveTab.svelte diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte index 3a178163..94b05655 100644 --- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte +++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte @@ -116,6 +116,12 @@ insert: true, }, }, + { + label: 'Create perspective', + tab: 'PerspectiveTab', + forceNewTab: true, + icon: 'img perspective', + }, ], views: [ { @@ -179,6 +185,12 @@ dropViews: true, }, }, + { + label: 'Create perspective', + tab: 'PerspectiveTab', + forceNewTab: true, + icon: 'img perspective', + }, ], matviews: [ { diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index c7ac644d..dedaa49f 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -171,6 +171,7 @@ 'img link': 'mdi mdi-link', 'img filter': 'mdi mdi-filter', 'img group': 'mdi mdi-group', + 'img perspective': 'mdi mdi-eye color-icon-yellow', 'img folder': 'mdi mdi-folder color-icon-yellow', 'img type-string': 'mdi mdi-alphabetical color-icon-blue', diff --git a/packages/web/src/perspectives/PerspectiveColumns.svelte b/packages/web/src/perspectives/PerspectiveColumns.svelte new file mode 100644 index 00000000..e69de29b diff --git a/packages/web/src/perspectives/PerspectiveCore.svelte b/packages/web/src/perspectives/PerspectiveCore.svelte new file mode 100644 index 00000000..e69de29b diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte new file mode 100644 index 00000000..b13d220f --- /dev/null +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -0,0 +1,57 @@ + + + +
+ + + + + +
+ + + + +
+ + diff --git a/packages/web/src/tabs/PerspectiveTab.svelte b/packages/web/src/tabs/PerspectiveTab.svelte new file mode 100644 index 00000000..33964347 --- /dev/null +++ b/packages/web/src/tabs/PerspectiveTab.svelte @@ -0,0 +1,11 @@ + + + diff --git a/packages/web/src/tabs/index.js b/packages/web/src/tabs/index.js index ae85d663..0cc22df2 100644 --- a/packages/web/src/tabs/index.js +++ b/packages/web/src/tabs/index.js @@ -25,6 +25,7 @@ import * as DbKeyDetailTab from './DbKeyDetailTab.svelte'; import * as QueryDataTab from './QueryDataTab.svelte'; import * as ConnectionTab from './ConnectionTab.svelte'; import * as MapTab from './MapTab.svelte'; +import * as PerspectiveTab from './PerspectiveTab.svelte'; export default { TableDataTab, @@ -54,4 +55,5 @@ export default { QueryDataTab, ConnectionTab, MapTab, + PerspectiveTab, }; From 18710bc67d4b3cc35cdac54174ef391eb1088ced Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Mon, 13 Jun 2022 19:31:31 +0200 Subject: [PATCH 002/132] v5.0.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aafe08d2..0ac31b4f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "5.0.4-beta.9", + "version": "5.0.4", "name": "dbgate-all", "workspaces": [ "packages/*", From 75bf0e53fca663eea85bfb78e18655740ea8f1c5 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 16 Jun 2022 17:05:42 +0200 Subject: [PATCH 003/132] perspectives WIP --- .../src/PerspectiveColumnDefinition.ts | 50 +++++++++++++++++++ packages/datalib/src/PerspectiveConfig.ts | 17 +++++++ packages/datalib/src/index.ts | 2 + .../perspectives/PerspectiveColumnRow.svelte | 50 +++++++++++++++++++ .../perspectives/PerspectiveColumns.svelte | 11 ++++ .../src/perspectives/PerspectiveView.svelte | 27 ++++++++-- packages/web/src/tabs/PerspectiveTab.svelte | 5 +- .../web/src/utility/usePerspectiveConfig.ts | 25 ++++++++++ 8 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 packages/datalib/src/PerspectiveColumnDefinition.ts create mode 100644 packages/datalib/src/PerspectiveConfig.ts create mode 100644 packages/web/src/perspectives/PerspectiveColumnRow.svelte create mode 100644 packages/web/src/utility/usePerspectiveConfig.ts diff --git a/packages/datalib/src/PerspectiveColumnDefinition.ts b/packages/datalib/src/PerspectiveColumnDefinition.ts new file mode 100644 index 00000000..ac2b1359 --- /dev/null +++ b/packages/datalib/src/PerspectiveColumnDefinition.ts @@ -0,0 +1,50 @@ +import { ColumnInfo, ForeignKeyInfo, TableInfo } from 'dbgate-types'; +import { clearConfigCache } from 'prettier'; +import { ChangePerspectiveConfigFunc, PerspectiveConfig } from './PerspectiveConfig'; + +export abstract class PerspectiveColumnDefinition { + abstract get title(); + abstract get props(); + abstract get isExpanded(); + abstract get isExpandable(); + abstract get level(); + abstract toggleExpanded(); +} + +export class PerspectiveTableColumnDefinition extends PerspectiveColumnDefinition { + foreignKey: ForeignKeyInfo; + constructor( + public column: ColumnInfo, + public table: TableInfo, + public config: PerspectiveConfig, + public setConfig: ChangePerspectiveConfigFunc + ) { + super(); + + this.foreignKey = + table.foreignKeys && + table.foreignKeys.find(fk => fk.columns.length == 1 && fk.columns[0].columnName == column.columnName); + } + + get title() { + return this.column.columnName; + } + + get props() { + return this.column; + } + + get isExpanded() { + return this.config.expandedColumns.includes(this.column.uniqueName); + } + + get isExpandable() { + return !!this.foreignKey; + } + + get level() { + return 0; + } + + toggleExpanded() {} +} diff --git a/packages/datalib/src/PerspectiveConfig.ts b/packages/datalib/src/PerspectiveConfig.ts new file mode 100644 index 00000000..b24be768 --- /dev/null +++ b/packages/datalib/src/PerspectiveConfig.ts @@ -0,0 +1,17 @@ +export interface PerspectiveConfig { + hiddenColumns: string[]; + shownColumns: string[]; + expandedColumns: string[]; + collapsedColumns: string[]; +} + +export function createPerspectiveConfig(): PerspectiveConfig { + return { + hiddenColumns: [], + shownColumns: [], + expandedColumns: [], + collapsedColumns: [], + }; +} + +export type ChangePerspectiveConfigFunc = (changeFunc: (config: PerspectiveConfig) => PerspectiveConfig) => void; diff --git a/packages/datalib/src/index.ts b/packages/datalib/src/index.ts index 7bff4808..3c6f3403 100644 --- a/packages/datalib/src/index.ts +++ b/packages/datalib/src/index.ts @@ -1,5 +1,7 @@ export * from './GridDisplay'; export * from './GridConfig'; +export * from './PerspectiveConfig'; +export * from './PerspectiveColumnDefinition'; export * from './TableGridDisplay'; export * from './ViewGridDisplay'; export * from './JslGridDisplay'; diff --git a/packages/web/src/perspectives/PerspectiveColumnRow.svelte b/packages/web/src/perspectives/PerspectiveColumnRow.svelte new file mode 100644 index 00000000..062a557d --- /dev/null +++ b/packages/web/src/perspectives/PerspectiveColumnRow.svelte @@ -0,0 +1,50 @@ + + +
+ + column.togglExpanded()} + /> + + + { + e.stopPropagation(); + }} + on:mousedown={e => { + e.stopPropagation(); + }} + on:change={() => { + const newValue = !column.isChecked; + // display.setColumnVisibility(column.uniquePath, newValue); + // dispatch('setvisibility', newValue); + }} + /> + + +
+ + diff --git a/packages/web/src/perspectives/PerspectiveColumns.svelte b/packages/web/src/perspectives/PerspectiveColumns.svelte index e69de29b..29820bbf 100644 --- a/packages/web/src/perspectives/PerspectiveColumns.svelte +++ b/packages/web/src/perspectives/PerspectiveColumns.svelte @@ -0,0 +1,11 @@ + + +{#each columns as column} + +{/each} diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index b13d220f..3288610f 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -1,4 +1,6 @@
- + {#if columns} + + {/if}
diff --git a/packages/web/src/tabs/PerspectiveTab.svelte b/packages/web/src/tabs/PerspectiveTab.svelte index 33964347..6a61bc30 100644 --- a/packages/web/src/tabs/PerspectiveTab.svelte +++ b/packages/web/src/tabs/PerspectiveTab.svelte @@ -1,11 +1,14 @@ - + diff --git a/packages/web/src/utility/usePerspectiveConfig.ts b/packages/web/src/utility/usePerspectiveConfig.ts new file mode 100644 index 00000000..5d77bb68 --- /dev/null +++ b/packages/web/src/utility/usePerspectiveConfig.ts @@ -0,0 +1,25 @@ +import { createPerspectiveConfig } from 'dbgate-datalib'; +import { writable } from 'svelte/store'; +import { onDestroy } from 'svelte'; + +function doLoadPerspectiveConfigFunc(tabid) { + try { + const existing = localStorage.getItem(`tabdata_perspective_${tabid}`); + if (existing) { + return { + ...createPerspectiveConfig(), + ...JSON.parse(existing), + }; + } + } catch (err) { + console.warn('Error loading perspective config:', err.message); + } + return createPerspectiveConfig(); +} + +export default function usePerspectiveConfig(tabid) { + const config = writable(doLoadPerspectiveConfigFunc(tabid)); + const unsubscribe = config.subscribe(value => localStorage.setItem(`tabdata_perspective_${tabid}`, JSON.stringify(value))); + onDestroy(unsubscribe); + return config; +} From 2b78a8dcae31bb0348e7740e65af48cafbfb98a0 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 17 Jun 2022 22:30:10 +0200 Subject: [PATCH 004/132] perspective WIP --- .../src/PerspectiveColumnDefinition.ts | 71 +++++++++++++++---- .../perspectives/PerspectiveColumnRow.svelte | 2 +- .../perspectives/PerspectiveColumns.svelte | 17 ++++- .../src/perspectives/PerspectiveView.svelte | 15 ++-- 4 files changed, 82 insertions(+), 23 deletions(-) diff --git a/packages/datalib/src/PerspectiveColumnDefinition.ts b/packages/datalib/src/PerspectiveColumnDefinition.ts index ac2b1359..edc67d98 100644 --- a/packages/datalib/src/PerspectiveColumnDefinition.ts +++ b/packages/datalib/src/PerspectiveColumnDefinition.ts @@ -1,14 +1,47 @@ -import { ColumnInfo, ForeignKeyInfo, TableInfo } from 'dbgate-types'; +import { ColumnInfo, DatabaseInfo, ForeignKeyInfo, TableInfo } from 'dbgate-types'; import { clearConfigCache } from 'prettier'; import { ChangePerspectiveConfigFunc, PerspectiveConfig } from './PerspectiveConfig'; export abstract class PerspectiveColumnDefinition { + constructor( + public config: PerspectiveConfig, + public setConfig: ChangePerspectiveConfigFunc, + public parentColumn: PerspectiveTableColumnDefinition + ) {} abstract get title(); + abstract get codeName(); abstract get props(); - abstract get isExpanded(); abstract get isExpandable(); - abstract get level(); - abstract toggleExpanded(); + abstract get childColumns(): PerspectiveColumnDefinition[]; + get uniqueName() { + if (this.parentColumn) return `${this.parentColumn.uniqueName}.${this.codeName}`; + return this.codeName; + } + get level() { + if (this.parentColumn) return this.parentColumn.level + 1; + return 0; + } + get isExpanded() { + return this.config.expandedColumns.includes(this.uniqueName); + } + + toggleExpanded(value?: boolean) { + this.includeInColumnSet('expandedColumns', this.uniqueName, value == null ? !this.isExpanded : value); + } + + includeInColumnSet(field: keyof PerspectiveConfig, uniqueName: string, isIncluded: boolean) { + if (isIncluded) { + this.setConfig(cfg => ({ + ...cfg, + [field]: [...(cfg[field] || []), uniqueName], + })); + } else { + this.setConfig(cfg => ({ + ...cfg, + [field]: (cfg[field] || []).filter(x => x != uniqueName), + })); + } + } } export class PerspectiveTableColumnDefinition extends PerspectiveColumnDefinition { @@ -16,16 +49,22 @@ export class PerspectiveTableColumnDefinition extends PerspectiveColumnDefinitio constructor( public column: ColumnInfo, public table: TableInfo, - public config: PerspectiveConfig, - public setConfig: ChangePerspectiveConfigFunc + public db: DatabaseInfo, + config: PerspectiveConfig, + setConfig: ChangePerspectiveConfigFunc, + parentColumn: PerspectiveTableColumnDefinition ) { - super(); + super(config, setConfig, parentColumn); this.foreignKey = table.foreignKeys && table.foreignKeys.find(fk => fk.columns.length == 1 && fk.columns[0].columnName == column.columnName); } + get codeName() { + return this.column.columnName; + } + get title() { return this.column.columnName; } @@ -34,17 +73,19 @@ export class PerspectiveTableColumnDefinition extends PerspectiveColumnDefinitio return this.column; } - get isExpanded() { - return this.config.expandedColumns.includes(this.column.uniqueName); - } - get isExpandable() { return !!this.foreignKey; } - get level() { - return 0; + get childColumns(): PerspectiveColumnDefinition[] { + if (!this.foreignKey) return []; + const tbl = this?.db?.tables?.find( + x => x.pureName == this.foreignKey?.refTableName && x.schemaName == this.foreignKey?.refSchemaName + ); + return ( + tbl?.columns?.map( + col => new PerspectiveTableColumnDefinition(col, tbl, this.db, this.config, this.setConfig, this) + ) || [] + ); } - - toggleExpanded() {} } diff --git a/packages/web/src/perspectives/PerspectiveColumnRow.svelte b/packages/web/src/perspectives/PerspectiveColumnRow.svelte index 062a557d..81893cf1 100644 --- a/packages/web/src/perspectives/PerspectiveColumnRow.svelte +++ b/packages/web/src/perspectives/PerspectiveColumnRow.svelte @@ -10,7 +10,7 @@ column.togglExpanded()} + on:click={() => column.toggleExpanded()} /> diff --git a/packages/web/src/perspectives/PerspectiveColumns.svelte b/packages/web/src/perspectives/PerspectiveColumns.svelte index 29820bbf..d426a036 100644 --- a/packages/web/src/perspectives/PerspectiveColumns.svelte +++ b/packages/web/src/perspectives/PerspectiveColumns.svelte @@ -4,8 +4,23 @@ import PerspectiveColumnRow from './PerspectiveColumnRow.svelte'; export let columns = []; + + function processFlatColumns(res, columns) { + for (const col of columns) { + res.push(col); + if (col.isExpanded) { + processFlatColumns(res, col.childColumns); + } + } + } + + function getFlatColumns(columns) { + const res = []; + processFlatColumns(res, columns); + return res; + } -{#each columns as column} +{#each getFlatColumns(columns) as column} {/each} diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 3288610f..389d4f48 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -4,7 +4,7 @@ import _ from 'lodash'; import HorizontalSplitter from '../elements/HorizontalSplitter.svelte'; - import { useTableInfo, useViewInfo } from '../utility/metadataLoaders'; + import { useDatabaseInfo, useTableInfo, useViewInfo } from '../utility/metadataLoaders'; import { getLocalStorage, setLocalStorage } from '../utility/storageCache'; import WidgetColumnBar from '../widgets/WidgetColumnBar.svelte'; @@ -32,24 +32,27 @@ return '300px'; } + const dbInfo = useDatabaseInfo({ conid, database }); const tableInfo = useTableInfo({ conid, database, schemaName, pureName }); const viewInfo = useViewInfo({ conid, database, schemaName, pureName }); // $: console.log('tableInfo', $tableInfo); // $: console.log('viewInfo', $viewInfo); - function getTableColumns(table, config, setConfig) { - return table.columns.map(col => new PerspectiveTableColumnDefinition(col, table, config, setConfig)); + function getTableColumns(table, dbInfo, config, setConfig) { + return table.columns.map(col => new PerspectiveTableColumnDefinition(col, table, dbInfo, config, setConfig, null)); } - function getViewColumns(view, config, setConfig) { + function getViewColumns(view, dbInfo, config, setConfig) { return []; } + $: console.log('CFG', config); + $: columns = $tableInfo - ? getTableColumns($tableInfo, config, setConfig) + ? getTableColumns($tableInfo, $dbInfo, config, setConfig) : $viewInfo - ? getViewColumns($viewInfo, config, setConfig) + ? getViewColumns($viewInfo, $dbInfo, config, setConfig) : null; From f3ab06d3b819c105b8a9979804cc0d6af6af0eaa Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 18 Jun 2022 08:00:00 +0200 Subject: [PATCH 005/132] refactor --- ...mnDefinition.ts => PerspectiveTreeNode.ts} | 37 ++++++++++++------- packages/datalib/src/index.ts | 2 +- .../perspectives/PerspectiveColumns.svelte | 2 +- .../src/perspectives/PerspectiveView.svelte | 6 +-- 4 files changed, 29 insertions(+), 18 deletions(-) rename packages/datalib/src/{PerspectiveColumnDefinition.ts => PerspectiveTreeNode.ts} (65%) diff --git a/packages/datalib/src/PerspectiveColumnDefinition.ts b/packages/datalib/src/PerspectiveTreeNode.ts similarity index 65% rename from packages/datalib/src/PerspectiveColumnDefinition.ts rename to packages/datalib/src/PerspectiveTreeNode.ts index edc67d98..e21f51a0 100644 --- a/packages/datalib/src/PerspectiveColumnDefinition.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -2,23 +2,23 @@ import { ColumnInfo, DatabaseInfo, ForeignKeyInfo, TableInfo } from 'dbgate-type import { clearConfigCache } from 'prettier'; import { ChangePerspectiveConfigFunc, PerspectiveConfig } from './PerspectiveConfig'; -export abstract class PerspectiveColumnDefinition { +export abstract class PerspectiveTreeNode { constructor( public config: PerspectiveConfig, public setConfig: ChangePerspectiveConfigFunc, - public parentColumn: PerspectiveTableColumnDefinition + public parentNode: PerspectiveTreeNode ) {} abstract get title(); abstract get codeName(); abstract get props(); abstract get isExpandable(); - abstract get childColumns(): PerspectiveColumnDefinition[]; + abstract get childNodes(): PerspectiveTreeNode[]; get uniqueName() { - if (this.parentColumn) return `${this.parentColumn.uniqueName}.${this.codeName}`; + if (this.parentNode) return `${this.parentNode.uniqueName}.${this.codeName}`; return this.codeName; } get level() { - if (this.parentColumn) return this.parentColumn.level + 1; + if (this.parentNode) return this.parentNode.level + 1; return 0; } get isExpanded() { @@ -44,7 +44,7 @@ export abstract class PerspectiveColumnDefinition { } } -export class PerspectiveTableColumnDefinition extends PerspectiveColumnDefinition { +export class PerspectiveTableColumnNode extends PerspectiveTreeNode { foreignKey: ForeignKeyInfo; constructor( public column: ColumnInfo, @@ -52,7 +52,7 @@ export class PerspectiveTableColumnDefinition extends PerspectiveColumnDefinitio public db: DatabaseInfo, config: PerspectiveConfig, setConfig: ChangePerspectiveConfigFunc, - parentColumn: PerspectiveTableColumnDefinition + parentColumn: PerspectiveTreeNode ) { super(config, setConfig, parentColumn); @@ -77,15 +77,26 @@ export class PerspectiveTableColumnDefinition extends PerspectiveColumnDefinitio return !!this.foreignKey; } - get childColumns(): PerspectiveColumnDefinition[] { + get childNodes(): PerspectiveTreeNode[] { if (!this.foreignKey) return []; const tbl = this?.db?.tables?.find( x => x.pureName == this.foreignKey?.refTableName && x.schemaName == this.foreignKey?.refSchemaName ); - return ( - tbl?.columns?.map( - col => new PerspectiveTableColumnDefinition(col, tbl, this.db, this.config, this.setConfig, this) - ) || [] - ); + return getTableChildPerspectiveNodes(tbl, this.db, this.config, this.setConfig, this); + // return ( + // tbl?.columns?.map(col => new PerspectiveTableColumnNode(col, tbl, this.db, this.config, this.setConfig, this)) || + // [] + // ); } } + +export function getTableChildPerspectiveNodes( + table: TableInfo, + db: DatabaseInfo, + config: PerspectiveConfig, + setConfig: ChangePerspectiveConfigFunc, + parentColumn: PerspectiveTreeNode +) { + if (!table) return []; + return table.columns.map(col => new PerspectiveTableColumnNode(col, table, db, config, setConfig, parentColumn)); +} diff --git a/packages/datalib/src/index.ts b/packages/datalib/src/index.ts index 3c6f3403..ed75afad 100644 --- a/packages/datalib/src/index.ts +++ b/packages/datalib/src/index.ts @@ -1,7 +1,7 @@ export * from './GridDisplay'; export * from './GridConfig'; export * from './PerspectiveConfig'; -export * from './PerspectiveColumnDefinition'; +export * from './PerspectiveTreeNode'; export * from './TableGridDisplay'; export * from './ViewGridDisplay'; export * from './JslGridDisplay'; diff --git a/packages/web/src/perspectives/PerspectiveColumns.svelte b/packages/web/src/perspectives/PerspectiveColumns.svelte index d426a036..2eaef616 100644 --- a/packages/web/src/perspectives/PerspectiveColumns.svelte +++ b/packages/web/src/perspectives/PerspectiveColumns.svelte @@ -9,7 +9,7 @@ for (const col of columns) { res.push(col); if (col.isExpanded) { - processFlatColumns(res, col.childColumns); + processFlatColumns(res, col.childNodes); } } } diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 389d4f48..225b97d0 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -1,5 +1,5 @@
- + column.toggleExpanded()} + icon={node.isExpandable ? plusExpandIcon(node.isExpanded) : 'icon invisible-box'} + on:click={() => node.toggleExpanded()} /> { e.stopPropagation(); }} @@ -24,13 +24,15 @@ e.stopPropagation(); }} on:change={() => { - const newValue = !column.isChecked; + const newValue = !node.isChecked; // display.setColumnVisibility(column.uniquePath, newValue); // dispatch('setvisibility', newValue); }} /> - + + + {node.title}
diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 6d9bfd66..b329c35b 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -63,13 +63,20 @@ // : null; async function loader(props: PerspectiveDataLoadProps) { - const { schemaName, pureName, bindingColumns, bindingValues } = props; + const { schemaName, pureName, bindingColumns, bindingValues, dataColumns } = props; const select: Select = { commandType: 'select', from: { name: { schemaName, pureName }, }, - selectAll: true, + columns: dataColumns?.map(columnName => ({ + exprType: 'column', + columnName, + source: { + name: { schemaName, pureName }, + }, + })), + selectAll: !dataColumns, }; if (bindingColumns?.length == 1) { select.where = { From b6b75f0743ca41b37cc51ea7897f03ef4bc5d412 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 23 Jun 2022 16:50:56 +0200 Subject: [PATCH 010/132] perspectives WIP --- packages/datalib/src/PerspectiveDisplay.ts | 23 +++++++++++++++++-- packages/datalib/src/PerspectiveTreeNode.ts | 10 ++++++++ .../src/perspectives/PerspectiveTable.svelte | 10 ++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/packages/datalib/src/PerspectiveDisplay.ts b/packages/datalib/src/PerspectiveDisplay.ts index 330fb9c9..ca4cff0e 100644 --- a/packages/datalib/src/PerspectiveDisplay.ts +++ b/packages/datalib/src/PerspectiveDisplay.ts @@ -1,7 +1,11 @@ import { PerspectiveTableNode, PerspectiveTreeNode } from './PerspectiveTreeNode'; export class PerspectiveDisplayColumn { - constructor(public label: string, public field: string) {} + subColumns: PerspectiveDisplayColumn[] = []; + title: string; + dataField: string; + + constructor() {} } export class PerspectiveDisplay { @@ -9,10 +13,25 @@ export class PerspectiveDisplay { constructor(public root: PerspectiveTreeNode, public rows: any[]) { const children = root.childNodes; + this.fillChildren(root.childNodes, this.columns); + } + + fillChildren(children: PerspectiveTreeNode[], columns: PerspectiveDisplayColumn[]) { for (const child of children) { if (child.isChecked) { - this.columns.push(new PerspectiveDisplayColumn(child.title, child.codeName)); + const childColumn = this.nodeToColumn(child); + columns.push(childColumn); } } } + + nodeToColumn(node: PerspectiveTreeNode) { + const res = new PerspectiveDisplayColumn(); + res.title = node.columnTitle; + res.dataField = node.dataField; + if (node.isExpandable) { + this.fillChildren(node.childNodes, res.subColumns); + } + return res; + } } diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index e9075b0a..7fae9aa7 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -53,6 +53,9 @@ export abstract class PerspectiveTreeNode { get fieldName() { return this.codeName; } + get dataField() { + return this.codeName; + } abstract getNodeLoadProps(parentRows: any[]): PerspectiveDataLoadProps; get isRoot() { return this.parentNode == null; @@ -75,6 +78,9 @@ export abstract class PerspectiveTreeNode { get isChecked() { return this.config.checkedColumns.includes(this.uniqueName); } + get columnTitle() { + return this.title; + } toggleExpanded(value?: boolean) { this.includeInColumnSet('expandedColumns', this.uniqueName, value == null ? !this.isExpanded : value); @@ -233,6 +239,10 @@ export class PerspectiveTableReferenceNode extends PerspectiveTableNode { dataColumns: null, }; } + + get columnTitle() { + return this.table.pureName; + } } export function getTableChildPerspectiveNodes( diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index 1c4f5f69..d1600fcf 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -78,9 +78,15 @@ {#if display} + + {#each display.columns as column} - + {/each} @@ -88,7 +94,7 @@ {#each display.rows as row} {#each display.columns as column} - + {/each} {/each} From 301222d118fa0beb9cc571e0dc0de013e7af0aa2 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 30 Jun 2022 10:38:03 +0200 Subject: [PATCH 011/132] perspectives: show nested columns --- packages/datalib/src/PerspectiveDisplay.ts | 55 +++++++++++++++---- .../src/perspectives/PerspectiveTable.svelte | 28 +++++----- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/packages/datalib/src/PerspectiveDisplay.ts b/packages/datalib/src/PerspectiveDisplay.ts index ca4cff0e..7e1985a6 100644 --- a/packages/datalib/src/PerspectiveDisplay.ts +++ b/packages/datalib/src/PerspectiveDisplay.ts @@ -1,37 +1,68 @@ import { PerspectiveTableNode, PerspectiveTreeNode } from './PerspectiveTreeNode'; +import _max from 'lodash/max'; export class PerspectiveDisplayColumn { - subColumns: PerspectiveDisplayColumn[] = []; title: string; dataField: string; + parentColumns: string[] = []; + display: PerspectiveDisplay; + colSpanAtLevel = {}; + + get rowSpan() { + return this.display.columnLevelCount - this.parentColumns.length; + } + + showParent(level: number) { + return !!this.colSpanAtLevel[level]; + } + + getColSpan(level: number) { + return this.colSpanAtLevel[level]; + } + + isVisible(level: number) { + return level == this.columnLevel; + } + + get columnLevel() { + return this.parentColumns.length; + } constructor() {} } export class PerspectiveDisplay { columns: PerspectiveDisplayColumn[] = []; + readonly columnLevelCount: number; constructor(public root: PerspectiveTreeNode, public rows: any[]) { - const children = root.childNodes; - this.fillChildren(root.childNodes, this.columns); + this.fillChildren(root.childNodes, []); + this.columnLevelCount = _max(this.columns.map(x => x.parentColumns.length)) + 1; } - fillChildren(children: PerspectiveTreeNode[], columns: PerspectiveDisplayColumn[]) { + fillChildren(children: PerspectiveTreeNode[], parentColumns: string[]) { for (const child of children) { if (child.isChecked) { - const childColumn = this.nodeToColumn(child); - columns.push(childColumn); + this.processColumn(child, parentColumns); } } } - nodeToColumn(node: PerspectiveTreeNode) { - const res = new PerspectiveDisplayColumn(); - res.title = node.columnTitle; - res.dataField = node.dataField; + processColumn(node: PerspectiveTreeNode, parentColumns: string[]) { if (node.isExpandable) { - this.fillChildren(node.childNodes, res.subColumns); + const countBefore = this.columns.length; + this.fillChildren(node.childNodes, [...parentColumns, node.title]); + + if (this.columns.length > countBefore) { + this.columns[countBefore].colSpanAtLevel[parentColumns.length] = this.columns.length - countBefore; + } + } else { + const column = new PerspectiveDisplayColumn(); + column.title = node.columnTitle; + column.dataField = node.dataField; + column.parentColumns = parentColumns; + column.display = this; + this.columns.push(column); } - return res; } } diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index d1600fcf..fef44d2c 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -6,7 +6,7 @@ PerspectiveDisplay, PerspectiveTreeNode, } from 'dbgate-datalib'; - import _ from 'lodash'; + import _, { range } from 'lodash'; import { onMount } from 'svelte'; import { prop_dev } from 'svelte/internal'; @@ -60,7 +60,8 @@ const rows = []; await loadLevelData(node, rows); dataRows = rows; - // console.log('RESULT', rows); + + console.log('DISPLAY ROWS', rows); // const rows = await node.loadLevelData(); // for (const child of node.childNodes) { // const loadProps = []; @@ -78,17 +79,18 @@ {#if display}
{column.label}{column.title}
{row[column.field]}{row[column.dataField]}
- - - - {#each display.columns as column} - - {/each} - + {#each _.range(display.columnLevelCount) as columnLevel} + + {#each display.columns as column} + {#if column.isVisible(columnLevel)} + + {/if} + {#if column.showParent(columnLevel)} + + {/if} + {/each} + + {/each} {#each display.rows as row} From 8228afd72524347ae2c8d9cf9ca8f40006c8b7e1 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 30 Jun 2022 18:10:50 +0200 Subject: [PATCH 012/132] perspective rows WIP --- packages/datalib/src/PerspectiveDisplay.ts | 147 ++++++++++++++++-- .../src/perspectives/PerspectiveTable.svelte | 4 +- 2 files changed, 134 insertions(+), 17 deletions(-) diff --git a/packages/datalib/src/PerspectiveDisplay.ts b/packages/datalib/src/PerspectiveDisplay.ts index 7e1985a6..edf85923 100644 --- a/packages/datalib/src/PerspectiveDisplay.ts +++ b/packages/datalib/src/PerspectiveDisplay.ts @@ -1,15 +1,21 @@ import { PerspectiveTableNode, PerspectiveTreeNode } from './PerspectiveTreeNode'; import _max from 'lodash/max'; +import _range from 'lodash/max'; +import _fill from 'lodash/fill'; +import _findIndex from 'lodash/findIndex'; export class PerspectiveDisplayColumn { title: string; dataField: string; - parentColumns: string[] = []; - display: PerspectiveDisplay; + parentNodes: PerspectiveTreeNode[] = []; colSpanAtLevel = {}; + columnIndex = 0; + dataNode: PerspectiveTreeNode = null; + + constructor(public display: PerspectiveDisplay) {} get rowSpan() { - return this.display.columnLevelCount - this.parentColumns.length; + return this.display.columnLevelCount - this.parentNodes.length; } showParent(level: number) { @@ -25,44 +31,155 @@ export class PerspectiveDisplayColumn { } get columnLevel() { - return this.parentColumns.length; + return this.parentNodes.length; } - constructor() {} + getParentName(level) { + return this.parentNodes[level]?.title; + } + + // hasParentNode(node: PerspectiveTreeNode) { + // return this.parentNodes.includes(node); + // } +} + +class PerspectiveSubRowCollection { + rows: CollectedPerspectiveDisplayRow[] = []; + // startIndex = 0; +} + +export class CollectedPerspectiveDisplayRow { + // startIndex = 0; + columnIndexes: number[] = []; + rowData: any[] = []; + // rowSpans: number[] = null; + subRowCollections: PerspectiveSubRowCollection[] = []; +} + +export class PerspectiveDisplayRow { + constructor(public display: PerspectiveDisplay) {} + + rowData: any[] = []; + rowSpans: number[] = null; } export class PerspectiveDisplay { columns: PerspectiveDisplayColumn[] = []; + rows: PerspectiveDisplayRow[] = []; readonly columnLevelCount: number; - constructor(public root: PerspectiveTreeNode, public rows: any[]) { - this.fillChildren(root.childNodes, []); - this.columnLevelCount = _max(this.columns.map(x => x.parentColumns.length)) + 1; + constructor(public root: PerspectiveTreeNode, rows: any[]) { + this.fillColumns(root.childNodes, []); + this.columnLevelCount = _max(this.columns.map(x => x.parentNodes.length)) + 1; + const collectedRows = this.collectRows(rows, root.childNodes); + console.log('COLLECTED', collectedRows); + // this.mergeRows(collectedRows); } - fillChildren(children: PerspectiveTreeNode[], parentColumns: string[]) { + fillColumns(children: PerspectiveTreeNode[], parentNodes: PerspectiveTreeNode[]) { for (const child of children) { if (child.isChecked) { - this.processColumn(child, parentColumns); + this.processColumn(child, parentNodes); } } } - processColumn(node: PerspectiveTreeNode, parentColumns: string[]) { + processColumn(node: PerspectiveTreeNode, parentNodes: PerspectiveTreeNode[]) { if (node.isExpandable) { const countBefore = this.columns.length; - this.fillChildren(node.childNodes, [...parentColumns, node.title]); + this.fillColumns(node.childNodes, [...parentNodes, node]); if (this.columns.length > countBefore) { - this.columns[countBefore].colSpanAtLevel[parentColumns.length] = this.columns.length - countBefore; + this.columns[countBefore].colSpanAtLevel[parentNodes.length] = this.columns.length - countBefore; } } else { - const column = new PerspectiveDisplayColumn(); + const column = new PerspectiveDisplayColumn(this); column.title = node.columnTitle; column.dataField = node.dataField; - column.parentColumns = parentColumns; + column.parentNodes = parentNodes; column.display = this; + column.columnIndex = this.columns.length; + column.dataNode = node; this.columns.push(column); } } + + findColumnIndexFromNode(node: PerspectiveTreeNode) { + return _findIndex(this.columns, x => x.dataNode.uniqueName == node.uniqueName); + } + + collectRows(sourceRows: any[], nodes: PerspectiveTreeNode[]): CollectedPerspectiveDisplayRow[] { + const columnNodes = nodes.filter(x => x.isChecked && !x.isExpandable); + const treeNodes = nodes.filter(x => x.isChecked && x.isExpandable); + + console.log( + 'columnNodes', + columnNodes.map(x => x.fieldName) + ); + + const columnIndexes = columnNodes.map(node => this.findColumnIndexFromNode(node)); + + // const nodeStartIndexes = new WeakMap(); + // for (const node of treeNodes) { + // const column = this.columns.find(x => x.hasParentNode(node)); + // if (column) nodeStartIndexes.set(node, column.columnIndex); + // } + + const res: CollectedPerspectiveDisplayRow[] = []; + for (const sourceRow of sourceRows) { + // console.log('PROCESS SOURCE', sourceRow); + const row = new CollectedPerspectiveDisplayRow(); + // row.startIndex = startIndex; + row.rowData = columnNodes.map(node => sourceRow[node.codeName]); + row.columnIndexes = columnIndexes; + + for (const node of treeNodes) { + // if (sourceRow.AlbumId == 1) { + // if (node.fieldName == 'ArtistIdRef') { + // console.log('XXX', sourceRow['ArtistIdRef']); + // console.log(require('lodash').keys(sourceRow)) + // console.dir(sourceRow); + // } + // console.log(node.fieldName, sourceRow[node.fieldName], sourceRow); + // } + // console.log('sourceRow[node.fieldName]', sourceRow[node.fieldName]); + if (sourceRow[node.fieldName]) { + const subrows = new PerspectiveSubRowCollection(); + // subrows.startIndex = nodeStartIndexes.get(node); + subrows.rows = this.collectRows(sourceRow[node.fieldName], node.childNodes); + row.subRowCollections.push(subrows); + } + } + + res.push(row); + } + + return res; + } + + // mergeRows(rows: PerspectiveDisplayRow[]) {} + + // flattenRows(sourceRow: CollectedPerspectiveDisplayRow) { + // let rowIndex = 0; + // const res = []; + // while (true) { + // const row = new PerspectiveDisplayRow(this); + // row.rowData = _fill(Array(this.columns.length), undefined); + // row.rowSpans = _fill(Array(this.columns.length), 0); + // for (let colIndex = 0; colIndex < this.columns.length; colIndex++) { + // if (colIndex < sourceRow.startIndex) { + // continue; + // } + // if (colIndex < sourceRow.startIndex + sourceRow.rowData.length) { + // if (rowIndex == 0) { + // row.rowData[colIndex] = sourceRow.rowData[sourceRow.startIndex + colIndex]; + // row.rowSpans[colIndex] = 1; + // } else { + // row.rowSpans[colIndex] += 1; + // } + // } + // const subrows = sourceRow.subRowCollections.find(x=>x.); + // } + // } + // } } diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index fef44d2c..43488bf0 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -33,7 +33,7 @@ for (const child of node.childNodes) { if (child.isExpandable && child.isChecked) { - loadLevelData(child, rows); + await loadLevelData(child, rows); // loadProps.push(child.getNodeLoadProps()); } } @@ -86,7 +86,7 @@ {/if} {#if column.showParent(columnLevel)} - + {/if} {/each} From b0eed05a1aa23a5446f8d9d61ad82e44e1292b97 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 30 Jun 2022 19:13:01 +0200 Subject: [PATCH 013/132] perspective rows --- packages/datalib/src/PerspectiveDisplay.ts | 139 +++++++++++++----- .../src/perspectives/PerspectiveTable.svelte | 2 +- 2 files changed, 103 insertions(+), 38 deletions(-) diff --git a/packages/datalib/src/PerspectiveDisplay.ts b/packages/datalib/src/PerspectiveDisplay.ts index edf85923..63073990 100644 --- a/packages/datalib/src/PerspectiveDisplay.ts +++ b/packages/datalib/src/PerspectiveDisplay.ts @@ -1,4 +1,4 @@ -import { PerspectiveTableNode, PerspectiveTreeNode } from './PerspectiveTreeNode'; +import { getTableChildPerspectiveNodes, PerspectiveTableNode, PerspectiveTreeNode } from './PerspectiveTreeNode'; import _max from 'lodash/max'; import _range from 'lodash/max'; import _fill from 'lodash/fill'; @@ -43,21 +43,32 @@ export class PerspectiveDisplayColumn { // } } -class PerspectiveSubRowCollection { - rows: CollectedPerspectiveDisplayRow[] = []; - // startIndex = 0; +interface PerspectiveSubRowCollection { + rows: CollectedPerspectiveDisplayRow[]; } -export class CollectedPerspectiveDisplayRow { +interface CollectedPerspectiveDisplayRow { // startIndex = 0; - columnIndexes: number[] = []; - rowData: any[] = []; + columnIndexes: number[]; + rowData: any[]; // rowSpans: number[] = null; - subRowCollections: PerspectiveSubRowCollection[] = []; + subRowCollections: PerspectiveSubRowCollection[]; } export class PerspectiveDisplayRow { - constructor(public display: PerspectiveDisplay) {} + constructor(public display: PerspectiveDisplay) { + this.rowData = _fill(Array(display.columns.length), undefined); + } + + getRow(rowIndex): PerspectiveDisplayRow { + if (rowIndex == 0) return this; + while (this.subrows.length < rowIndex) { + this.subrows.push(new PerspectiveDisplayRow(this.display)); + } + return this.subrows[rowIndex - 1]; + } + + subrows: PerspectiveDisplayRow[] = []; rowData: any[] = []; rowSpans: number[] = null; @@ -74,6 +85,8 @@ export class PerspectiveDisplay { const collectedRows = this.collectRows(rows, root.childNodes); console.log('COLLECTED', collectedRows); // this.mergeRows(collectedRows); + this.mergeRows(collectedRows); + console.log('MERGED', this.rows); } fillColumns(children: PerspectiveTreeNode[], parentNodes: PerspectiveTreeNode[]) { @@ -128,10 +141,9 @@ export class PerspectiveDisplay { const res: CollectedPerspectiveDisplayRow[] = []; for (const sourceRow of sourceRows) { // console.log('PROCESS SOURCE', sourceRow); - const row = new CollectedPerspectiveDisplayRow(); // row.startIndex = startIndex; - row.rowData = columnNodes.map(node => sourceRow[node.codeName]); - row.columnIndexes = columnIndexes; + const rowData = columnNodes.map(node => sourceRow[node.codeName]); + const subRowCollections = []; for (const node of treeNodes) { // if (sourceRow.AlbumId == 1) { @@ -144,42 +156,95 @@ export class PerspectiveDisplay { // } // console.log('sourceRow[node.fieldName]', sourceRow[node.fieldName]); if (sourceRow[node.fieldName]) { - const subrows = new PerspectiveSubRowCollection(); - // subrows.startIndex = nodeStartIndexes.get(node); - subrows.rows = this.collectRows(sourceRow[node.fieldName], node.childNodes); - row.subRowCollections.push(subrows); + const subrows = { + rows: this.collectRows(sourceRow[node.fieldName], node.childNodes), + }; + subRowCollections.push(subrows); } } - res.push(row); + res.push({ + rowData, + columnIndexes, + subRowCollections, + }); } return res; } - // mergeRows(rows: PerspectiveDisplayRow[]) {} + flushFlatRows(row: PerspectiveDisplayRow) { + this.rows.push(row); + for (const child of row.subrows) { + this.flushFlatRows(child); + } + } - // flattenRows(sourceRow: CollectedPerspectiveDisplayRow) { - // let rowIndex = 0; + mergeRows(collectedRows: CollectedPerspectiveDisplayRow[]) { + const rows = []; + for (const collectedRow of collectedRows) { + const resultRow = new PerspectiveDisplayRow(this); + this.mergeRow(collectedRow, resultRow); + rows.push(resultRow); + } + for (const row of rows) { + this.flushFlatRows(row); + } + } + + mergeRow(collectedRow: CollectedPerspectiveDisplayRow, resultRow: PerspectiveDisplayRow) { + for (let i = 0; i < collectedRow.columnIndexes.length; i++) { + resultRow.rowData[collectedRow.columnIndexes[i]] = collectedRow.rowData[i]; + } + + for (const subrows of collectedRow.subRowCollections) { + let rowIndex = 0; + for (const subrow of subrows.rows) { + const targetRow = resultRow.getRow(rowIndex); + this.mergeRow(subrow, targetRow); + rowIndex++; + } + } + } + + // rowToFlatRows(sourceRow: CollectedPerspectiveDisplayRow) { // const res = []; - // while (true) { - // const row = new PerspectiveDisplayRow(this); - // row.rowData = _fill(Array(this.columns.length), undefined); - // row.rowSpans = _fill(Array(this.columns.length), 0); - // for (let colIndex = 0; colIndex < this.columns.length; colIndex++) { - // if (colIndex < sourceRow.startIndex) { - // continue; - // } - // if (colIndex < sourceRow.startIndex + sourceRow.rowData.length) { - // if (rowIndex == 0) { - // row.rowData[colIndex] = sourceRow.rowData[sourceRow.startIndex + colIndex]; - // row.rowSpans[colIndex] = 1; - // } else { - // row.rowSpans[colIndex] += 1; - // } - // } - // const subrows = sourceRow.subRowCollections.find(x=>x.); + + // const row = new PerspectiveDisplayRow(this); + // row.rowData = _fill(Array(this.columns.length), undefined); + // row.rowSpans = _fill(Array(this.columns.length), 1); + // res.push(row) + + // for (let i = 0; i < sourceRow.columnIndexes.length; i++) { + // row.rowData[sourceRow.columnIndexes[i]] = sourceRow.rowData[i]; + // } + + // for(const subrows of sourceRow.subRowCollections) { + // let rowIndex=0; + // for(const subrow of subrows.rows) { + // if () + // rowIndex++; + // } // } + + // return res; + + // // while (true) { + // // for (let colIndex = 0; colIndex < this.columns.length; colIndex++) { + // // if (colIndex < sourceRow.startIndex) { + // // continue; + // // } + // // if (colIndex < sourceRow.startIndex + sourceRow.rowData.length) { + // // if (rowIndex == 0) { + // // row.rowData[colIndex] = sourceRow.rowData[sourceRow.startIndex + colIndex]; + // // row.rowSpans[colIndex] = 1; + // // } else { + // // row.rowSpans[colIndex] += 1; + // // } + // // } + // // const subrows = sourceRow.subRowCollections.find(x=>x.); + // // } + // // } // } } diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index 43488bf0..ced7395a 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -96,7 +96,7 @@ {#each display.rows as row} {#each display.columns as column} - + {/each} {/each} From 07fc5513838e64b98f3b71be66a8d8138fe0c316 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 30 Jun 2022 21:01:27 +0200 Subject: [PATCH 014/132] perspective row spans --- packages/datalib/src/PerspectiveDisplay.ts | 23 ++++++++++++++++++- .../src/perspectives/PerspectiveTable.svelte | 5 +++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/datalib/src/PerspectiveDisplay.ts b/packages/datalib/src/PerspectiveDisplay.ts index 63073990..04530b39 100644 --- a/packages/datalib/src/PerspectiveDisplay.ts +++ b/packages/datalib/src/PerspectiveDisplay.ts @@ -58,6 +58,7 @@ interface CollectedPerspectiveDisplayRow { export class PerspectiveDisplayRow { constructor(public display: PerspectiveDisplay) { this.rowData = _fill(Array(display.columns.length), undefined); + this.rowSpans = _fill(Array(display.columns.length), 1); } getRow(rowIndex): PerspectiveDisplayRow { @@ -68,7 +69,7 @@ export class PerspectiveDisplayRow { return this.subrows[rowIndex - 1]; } - subrows: PerspectiveDisplayRow[] = []; + subrows?: PerspectiveDisplayRow[] = []; rowData: any[] = []; rowSpans: number[] = null; @@ -180,6 +181,22 @@ export class PerspectiveDisplay { } } + fillRowSpans() { + const lastFilledColumns = _fill(Array(this.columns.length), 0); + let rowIndex = 0; + for (const row of this.rows) { + for (let i = 0; i < this.columns.length; i++) { + if (row.rowData[i] !== undefined) { + if (rowIndex - lastFilledColumns[i] > 1) { + this.rows[lastFilledColumns[i]].rowSpans[i] = rowIndex - lastFilledColumns[i]; + } + lastFilledColumns[i] = rowIndex; + } + } + rowIndex++; + } + } + mergeRows(collectedRows: CollectedPerspectiveDisplayRow[]) { const rows = []; for (const collectedRow of collectedRows) { @@ -190,6 +207,10 @@ export class PerspectiveDisplay { for (const row of rows) { this.flushFlatRows(row); } + for (const row of this.rows) { + delete row.subrows; + } + this.fillRowSpans(); } mergeRow(collectedRow: CollectedPerspectiveDisplayRow, resultRow: PerspectiveDisplayRow) { diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index ced7395a..373f32e3 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -96,7 +96,10 @@ {#each display.rows as row} {#each display.columns as column} - + + {#if row.rowData[column.columnIndex] !== undefined} + + {/if} {/each} {/each} From 34084d0e94d1bf65059ff94ea76c61718864f6f7 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 30 Jun 2022 21:14:56 +0200 Subject: [PATCH 015/132] perspective styling --- .../src/perspectives/PerspectiveTable.svelte | 33 ++++++++++++++++++- .../src/perspectives/PerspectiveView.svelte | 9 +++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index 373f32e3..047f1ef5 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -113,6 +113,37 @@ overflow: scroll; } + table { + /* position: absolute; + left: 0; + top: 0; + bottom: 20px; */ + overflow: scroll; + border-collapse: collapse; + outline: none; + } + th { + border: 1px solid var(--theme-border); + text-align: left; + padding: 0; + margin: 0; + background-color: var(--theme-bg-1); + overflow: hidden; + vertical-align: center; + } + + td { + font-weight: normal; + border: 1px solid var(--theme-border); + background-color: var(--theme-bg-0); + padding: 2px; + white-space: nowrap; + position: relative; + overflow: hidden; + vertical-align: top; + } + +/* table { border: 1px solid; border-collapse: collapse; @@ -121,5 +152,5 @@ td, th { border: 1px solid; - } + } */ diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index b329c35b..366beb29 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -18,6 +18,7 @@ import PerspectiveTable from './PerspectiveTable.svelte'; import { apiCall } from '../utility/api'; import { Select } from 'dbgate-sqltree'; +import ManagerInnerContainer from '../elements/ManagerInnerContainer.svelte'; export let conid; export let database; @@ -108,9 +109,11 @@
- {#if root} - - {/if} + + {#if root} + + {/if} +
From 34ca4c501af74e99585c37cc2e2651c877c528d2 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 30 Jun 2022 21:46:45 +0200 Subject: [PATCH 016/132] fixed table header --- .../web/src/perspectives/PerspectiveTable.svelte | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index 047f1ef5..1fede42c 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -12,6 +12,7 @@ export let root: PerspectiveTreeNode; let dataRows; + let domWrapper; async function loadLevelData(node: PerspectiveTreeNode, parentRows: any[]) { // const loadProps: PerspectiveDataLoadPropsWithNode[] = []; @@ -71,11 +72,16 @@ // } } + function handleScroll() { + const translate = 'translate(0,' + domWrapper.scrollTop + 'px)'; + domWrapper.querySelector('thead').style.transform = translate; + } + $: loadData(root); $: display = root && dataRows ? new PerspectiveDisplay(root, dataRows) : null; -
+
{#if display}
{column.title}
{column.title}{column.parentColumns[columnLevel]}
{column.title}{column.parentColumns[columnLevel]}{column.getParentName(columnLevel)}
{row[column.dataField]}{row.rowData[column.columnIndex]}
{row.rowData[column.columnIndex]}{row.rowData[column.columnIndex]}
@@ -111,13 +117,16 @@ diff --git a/packages/web/src/datagrid/DataGridCell.svelte b/packages/web/src/datagrid/DataGridCell.svelte index e342663b..2a3ddee5 100644 --- a/packages/web/src/datagrid/DataGridCell.svelte +++ b/packages/web/src/datagrid/DataGridCell.svelte @@ -1,38 +1,3 @@ - - + + + + diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index bbbd4d2c..3074b6bd 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -13,7 +13,7 @@ + +{#if column.isVisible(columnLevel)} + +{/if} +{#if column.showParent(columnLevel)} + +{/if} + + diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index cd7201f7..ede92f9d 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -28,12 +28,14 @@ import PerspectiveCell from './PerspectiveCell.svelte'; import DataGridCell from '../datagrid/DataGridCell.svelte'; import PerspectiveLoadingIndicator from './PerspectiveLoadingIndicator.svelte'; + import PerspectiveHeaderControl from './PerspectiveHeaderControl.svelte'; const dbg = debug('dbgate:PerspectivaTable'); export const activator = createActivator('PerspectiveTable', true); export let root: PerspectiveTreeNode; export let loadedCounts; + export let config; export let setConfig; let dataRows; @@ -159,12 +161,7 @@ {#each _.range(display.columnLevelCount) as columnLevel} {#each display.columns as column} - {#if column.isVisible(columnLevel)} - - {/if} - {#if column.showParent(columnLevel)} - - {/if} + {/each} {/each} @@ -266,25 +263,6 @@ z-index: 100; } - th { - /* border: 1px solid var(--theme-border); */ - text-align: left; - padding: 2px; - margin: 0; - background-color: var(--theme-bg-1); - overflow: hidden; - vertical-align: center; - z-index: 100; - font-weight: normal; - - border-bottom: 1px solid var(--theme-border); - border-right: 1px solid var(--theme-border); - } - - th.tableName { - font-weight: bold; - } - th.filter { padding: 0; } diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 3efee050..50e3ecb4 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -79,7 +79,7 @@ - + diff --git a/packages/web/src/tabs/PerspectiveTab.svelte b/packages/web/src/tabs/PerspectiveTab.svelte index 8b34d045..fb136fad 100644 --- a/packages/web/src/tabs/PerspectiveTab.svelte +++ b/packages/web/src/tabs/PerspectiveTab.svelte @@ -12,6 +12,8 @@ testEnabled: () => getCurrentEditor() != null, onClick: () => getCurrentEditor().refresh(), }); + + export const allowAddToFavorites = props => true; -
... data to be loaded
+
... data to be loaded {incompleteRowsIndicator.join(',')}
diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index a35e11d3..7ddfca54 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -12,9 +12,9 @@ -
+
{#if display} -
+ {#if value !== undefined} + + {/if} + (mouseIn = true)} + on:mouseleave={() => (mouseIn = false)} + > +
+
+ {column.title} +
+ + {#if order == 'ASC'} + + + {#if orderIndex >= 0} + {orderIndex + 1} + {/if} + + {/if} + {#if order == 'DESC'} + + + {#if orderIndex >= 0} + {orderIndex + 1} + {/if} + + {/if} +
+ + {#if mouseIn} + + {/if} +
{column.getParentName(columnLevel)}
{column.title}{column.getParentName(columnLevel)}
+
{#each _.range(display.columnLevelCount) as columnLevel} {#each display.columns as column} - + {/each} {/each} @@ -185,12 +261,13 @@ {#each display.rows as row} - {#if row.incompleteRowsIndicator} - - {:else} - {#each display.columns as column} - {#if !row.rowCellSkips[column.columnIndex]} - - {/if} - {/each} - {/if} + {#each display.columns as column} + {#if !row.rowCellSkips[column.columnIndex]} + + {/if} + {/each} {/each} From c8d031e2c463ba22eac96659a39bf082287de9c0 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 31 Jul 2022 16:10:57 +0200 Subject: [PATCH 077/132] removed debug code --- packages/datalib/src/PerspectiveDataProvider.ts | 10 ++++++++-- packages/web/src/tabs/PerspectiveTab.svelte | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/datalib/src/PerspectiveDataProvider.ts b/packages/datalib/src/PerspectiveDataProvider.ts index 7f1374f2..4842b20e 100644 --- a/packages/datalib/src/PerspectiveDataProvider.ts +++ b/packages/datalib/src/PerspectiveDataProvider.ts @@ -1,10 +1,13 @@ +import debug from 'debug'; import { Condition } from 'dbgate-sqltree'; import { RangeDefinition } from 'dbgate-types'; import { format } from 'path'; import { PerspectiveBindingGroup, PerspectiveCache } from './PerspectiveCache'; import { PerspectiveDataLoader } from './PerspectiveDataLoader'; -export const PERSPECTIVE_PAGE_SIZE = 10; +export const PERSPECTIVE_PAGE_SIZE = 100; + +const dbg = debug('dbgate:PerspectiveDataProvider'); export interface PerspectiveDatabaseConfig { conid: string; @@ -30,6 +33,7 @@ export interface PerspectiveDataLoadProps { export class PerspectiveDataProvider { constructor(public cache: PerspectiveCache, public loader: PerspectiveDataLoader) {} async loadData(props: PerspectiveDataLoadProps): Promise<{ rows: any[]; incomplete: boolean }> { + dbg('load data', props); // console.log('LOAD DATA', props); if (props.bindingColumns) { return this.loadDataNested(props); @@ -69,15 +73,17 @@ export class PerspectiveDataProvider { for (; groupIndex < props.bindingValues.length; groupIndex++) { const groupValues = props.bindingValues[groupIndex]; const group = tableCache.getBindingGroup(groupValues); + let loadCalled = false; if (!group.loadedAll) { // wee need to load next data await this.loadNextGroup(props, groupIndex); + loadCalled = true; } // console.log('GRP', groupValues, group); rows.push(...group.loadedRows); - if (rows.length >= props.topCount) { + if (rows.length >= props.topCount || loadCalled) { return { rows: rows.slice(0, props.topCount), incomplete: props.topCount < rows.length || !group.loadedAll || groupIndex < props.bindingValues.length - 1, diff --git a/packages/web/src/tabs/PerspectiveTab.svelte b/packages/web/src/tabs/PerspectiveTab.svelte index fb136fad..38cbbf0d 100644 --- a/packages/web/src/tabs/PerspectiveTab.svelte +++ b/packages/web/src/tabs/PerspectiveTab.svelte @@ -57,6 +57,7 @@ cache.clear(); } config.update(value); + // loadedCounts.set({}); }} {cache} {loadedCounts} From 2b4120435b524906819d700be1299924ac34e762 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 31 Jul 2022 16:56:09 +0200 Subject: [PATCH 078/132] perspectives support views --- packages/datalib/src/PerspectiveTreeNode.ts | 73 ++++++++++++++++--- .../src/getPerspectiveDefaultColumns.ts | 6 +- .../src/appobj/DatabaseObjectAppObject.svelte | 12 +-- .../src/perspectives/PerspectiveView.svelte | 3 + 4 files changed, 75 insertions(+), 19 deletions(-) diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index 1a50422f..efc19c4d 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -1,4 +1,4 @@ -import { ColumnInfo, DatabaseInfo, ForeignKeyInfo, RangeDefinition, TableInfo } from 'dbgate-types'; +import { ColumnInfo, DatabaseInfo, ForeignKeyInfo, RangeDefinition, TableInfo, ViewInfo } from 'dbgate-types'; import { clearConfigCache } from 'prettier'; import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveConfigColumns } from './PerspectiveConfig'; import _isEqual from 'lodash/isEqual'; @@ -185,7 +185,7 @@ export abstract class PerspectiveTreeNode { }; } - getOrderBy(table: TableInfo): PerspectiveDataLoadProps['orderBy'] { + getOrderBy(table: TableInfo | ViewInfo): PerspectiveDataLoadProps['orderBy'] { const res = _compact( this.childNodes.map(node => { const sort = this.config?.sort?.[node?.parentNode?.uniqueName]?.find(x => x.uniqueName == node.uniqueName); @@ -199,7 +199,7 @@ export abstract class PerspectiveTreeNode { ); return res.length > 0 ? res - : table?.primaryKey?.columns.map(x => ({ columnName: x.columnName, order: 'ASC' })) || [ + : (table as TableInfo)?.primaryKey?.columns.map(x => ({ columnName: x.columnName, order: 'ASC' })) || [ { columnName: table?.columns[0].columnName, order: 'ASC' }, ]; } @@ -210,7 +210,7 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode { refTable: TableInfo; constructor( public column: ColumnInfo, - public table: TableInfo, + public table: TableInfo | ViewInfo, public db: DatabaseInfo, config: PerspectiveConfig, setConfig: ChangePerspectiveConfigFunc, @@ -223,9 +223,9 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode { this.defaultChecked = defaultChecked; - this.foreignKey = - table.foreignKeys && - table.foreignKeys.find(fk => fk.columns.length == 1 && fk.columns[0].columnName == column.columnName); + this.foreignKey = (table as TableInfo)?.foreignKeys?.find( + fk => fk.columns.length == 1 && fk.columns[0].columnName == column.columnName + ); this.refTable = db.tables.find( x => x.pureName == this.foreignKey?.refTableName && x.schemaName == this.foreignKey?.refSchemaName @@ -382,6 +382,59 @@ export class PerspectiveTableNode extends PerspectiveTreeNode { } } +export class PerspectiveViewNode extends PerspectiveTreeNode { + constructor( + public view: ViewInfo, + public db: DatabaseInfo, + config: PerspectiveConfig, + setConfig: ChangePerspectiveConfigFunc, + public dataProvider: PerspectiveDataProvider, + databaseConfig: PerspectiveDatabaseConfig, + parentNode: PerspectiveTreeNode + ) { + super(config, setConfig, parentNode, dataProvider, databaseConfig); + } + + getNodeLoadProps(parentRows: any[]): PerspectiveDataLoadProps { + return { + schemaName: this.view.schemaName, + pureName: this.view.pureName, + dataColumns: this.getDataLoadColumns(), + databaseConfig: this.databaseConfig, + orderBy: this.getOrderBy(this.view), + condition: this.getChildrenCondition(), + }; + } + + get codeName() { + return this.view.schemaName ? `${this.view.schemaName}:${this.view.pureName}` : this.view.pureName; + } + + get title() { + return this.view.pureName; + } + + get isExpandable() { + return true; + } + + get childNodes(): PerspectiveTreeNode[] { + return getTableChildPerspectiveNodes( + this.view, + this.db, + this.config, + this.setConfig, + this.dataProvider, + this.databaseConfig, + this + ); + } + + get icon() { + return 'img table'; + } +} + export class PerspectiveTableReferenceNode extends PerspectiveTableNode { constructor( public foreignKey: ForeignKeyInfo, @@ -434,7 +487,7 @@ export class PerspectiveTableReferenceNode extends PerspectiveTableNode { } export function getTableChildPerspectiveNodes( - table: TableInfo, + table: TableInfo | ViewInfo, db: DatabaseInfo, config: PerspectiveConfig, setConfig: ChangePerspectiveConfigFunc, @@ -463,8 +516,8 @@ export function getTableChildPerspectiveNodes( ) ) ); - if (db && table.dependencies) { - for (const fk of table.dependencies) { + if (db && (table as TableInfo)?.dependencies) { + for (const fk of (table as TableInfo)?.dependencies) { const tbl = db.tables.find(x => x.pureName == fk.pureName && x.schemaName == fk.schemaName); if (tbl) res.push( diff --git a/packages/datalib/src/getPerspectiveDefaultColumns.ts b/packages/datalib/src/getPerspectiveDefaultColumns.ts index d3ede947..1eabe08e 100644 --- a/packages/datalib/src/getPerspectiveDefaultColumns.ts +++ b/packages/datalib/src/getPerspectiveDefaultColumns.ts @@ -1,7 +1,7 @@ import { findForeignKeyForColumn } from 'dbgate-tools'; -import { DatabaseInfo, TableInfo } from 'dbgate-types'; +import { DatabaseInfo, TableInfo, ViewInfo } from 'dbgate-types'; -export function getPerspectiveDefaultColumns(table: TableInfo, db: DatabaseInfo): string[] { +export function getPerspectiveDefaultColumns(table: TableInfo | ViewInfo, db: DatabaseInfo): string[] { const columns = table.columns.map(x => x.columnName); const predicates = [ x => x.toLowerCase() == 'name', @@ -9,7 +9,7 @@ export function getPerspectiveDefaultColumns(table: TableInfo, db: DatabaseInfo) x => x.toLowerCase().includes('name'), x => x.toLowerCase().includes('title'), x => x.dataType?.toLowerCase()?.includes('char'), - x => findForeignKeyForColumn(table, x)?.columns?.length == 1, + x => findForeignKeyForColumn(table as TableInfo, x)?.columns?.length == 1, ]; for (const predicate of predicates) { diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte index a4a2364d..7fe147aa 100644 --- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte +++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte @@ -142,6 +142,12 @@ tab: 'TableStructureTab', icon: 'img view-structure', }, + { + label: 'Open perspective', + tab: 'PerspectiveTab', + forceNewTab: true, + icon: 'img perspective', + }, { label: 'Drop view', isDrop: true, @@ -193,12 +199,6 @@ dropViews: true, }, }, - { - label: 'Create perspective', - tab: 'PerspectiveTab', - forceNewTab: true, - icon: 'img perspective', - }, ], matviews: [ { diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 50e3ecb4..19745a4e 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -5,6 +5,7 @@ PerspectiveDataProvider, PerspectiveTableColumnNode, PerspectiveTableNode, + PerspectiveViewNode, } from 'dbgate-datalib'; import _ from 'lodash'; @@ -60,6 +61,8 @@ $: loader = new PerspectiveDataLoader(apiCall); $: root = $tableInfo ? new PerspectiveTableNode($tableInfo, $dbInfo, config, setConfig, dataProvider, { conid, database }, null) + : $viewInfo + ? new PerspectiveViewNode($viewInfo, $dbInfo, config, setConfig, dataProvider, { conid, database }, null) : null; // $: console.log('CONFIG', config); From 091e91556d2d6d5bb501c7d107d8805b06c688fe Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 31 Jul 2022 20:09:48 +0200 Subject: [PATCH 079/132] custom join dialog --- packages/datalib/src/PerspectiveConfig.ts | 15 + packages/datalib/src/PerspectiveTreeNode.ts | 26 ++ packages/web/src/icons/FontIcon.svelte | 1 + .../src/impexp/FormConnectionSelect.svelte | 2 +- .../src/perspectives/CustomJoinModal.svelte | 343 ++++++++++++++++++ .../src/perspectives/PerspectiveTable.svelte | 3 + .../src/perspectives/PerspectiveView.svelte | 32 ++ packages/web/src/tabs/PerspectiveTab.svelte | 1 + 8 files changed, 422 insertions(+), 1 deletion(-) create mode 100644 packages/web/src/perspectives/CustomJoinModal.svelte diff --git a/packages/datalib/src/PerspectiveConfig.ts b/packages/datalib/src/PerspectiveConfig.ts index 2067c818..a3e836d0 100644 --- a/packages/datalib/src/PerspectiveConfig.ts +++ b/packages/datalib/src/PerspectiveConfig.ts @@ -4,6 +4,19 @@ export interface PerspectiveConfigColumns { uncheckedColumns: string[]; } +export interface PerspectiveCustomJoinConfig { + joinid: string; + joinName: string; + baseUniqueName: string; + conid?: string; + database?: string; + refSchemaName?: string; + refTableName: string; + columns: { + baseColumnName: string; + refColumnName: string; + }[]; +} export interface PerspectiveConfig extends PerspectiveConfigColumns { filters: { [uniqueName: string]: string }; sort: { @@ -12,6 +25,7 @@ export interface PerspectiveConfig extends PerspectiveConfigColumns { order: 'ASC' | 'DESC'; }[]; }; + customJoins: PerspectiveCustomJoinConfig[]; } export function createPerspectiveConfig(): PerspectiveConfig { @@ -19,6 +33,7 @@ export function createPerspectiveConfig(): PerspectiveConfig { expandedColumns: [], checkedColumns: [], uncheckedColumns: [], + customJoins: [], filters: {}, sort: {}, }; diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index efc19c4d..960b3326 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -203,6 +203,20 @@ export abstract class PerspectiveTreeNode { { columnName: table?.columns[0].columnName, order: 'ASC' }, ]; } + + getBaseTables() { + const res = []; + const table = this.getBaseTableFromThis(); + if (table) res.push({ table, node: this }); + for (const child of this.childNodes) { + if (!child.isChecked) continue; + res.push(...child.getBaseTables()); + } + return res; + } + getBaseTableFromThis() { + return null; + } } export class PerspectiveTableColumnNode extends PerspectiveTreeNode { @@ -311,6 +325,10 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode { ); } + getBaseTableFromThis() { + return this.refTable; + } + parseFilterCondition() { const filter = this.getFilter(); if (!filter) return null; @@ -380,6 +398,10 @@ export class PerspectiveTableNode extends PerspectiveTreeNode { get icon() { return 'img table'; } + + getBaseTableFromThis() { + return this.table; + } } export class PerspectiveViewNode extends PerspectiveTreeNode { @@ -433,6 +455,10 @@ export class PerspectiveViewNode extends PerspectiveTreeNode { get icon() { return 'img table'; } + + getBaseTableFromThis() { + return this.view; + } } export class PerspectiveTableReferenceNode extends PerspectiveTableNode { diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index dedaa49f..96ddeaf0 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -94,6 +94,7 @@ 'icon add': 'mdi mdi-plus-circle', 'icon json': 'mdi mdi-code-json', 'icon lock': 'mdi mdi-lock', + 'icon custom-join': 'mdi mdi-arrow-left-right-bold', 'icon run': 'mdi mdi-play', 'icon chevron-down': 'mdi mdi-chevron-down', diff --git a/packages/web/src/impexp/FormConnectionSelect.svelte b/packages/web/src/impexp/FormConnectionSelect.svelte index c87d144c..0f71c992 100644 --- a/packages/web/src/impexp/FormConnectionSelect.svelte +++ b/packages/web/src/impexp/FormConnectionSelect.svelte @@ -12,7 +12,7 @@ ...(allowChooseModel ? [{ label: '(DB Model)', value: '__model' }] : []), ..._.sortBy( ($connections || []) - .filter(conn => (direction == 'target' ? !conn.isReadOnly : true)) + .filter(conn => !conn.unsaved && (direction == 'target' ? !conn.isReadOnly : true)) .map(conn => ({ value: conn._id, label: getConnectionLabel(conn), diff --git a/packages/web/src/perspectives/CustomJoinModal.svelte b/packages/web/src/perspectives/CustomJoinModal.svelte new file mode 100644 index 00000000..d7747b66 --- /dev/null +++ b/packages/web/src/perspectives/CustomJoinModal.svelte @@ -0,0 +1,343 @@ + + + + + Define custom join + +
+
+
Join name
+
+ { + joinName = e.target['value']; + }} + /> +
+
+ +
+
Base table
+
+ { + if (e.detail) { + fromUniuqeName = e.detail; + } + }} + /> +
+
+ +
+
Connection
+
+ { + conidOverride = e.detail; + }} + /> +
+
+ +
+
Database
+
+ { + databaseOverride = e.detail; + }} + /> +
+
+ + + +
+
Referenced table
+
+ { + if (e.detail) { + const name = fullNameFromString(e.detail); + refTableName = name.pureName; + refSchemaName = name.schemaName; + const refTable = $refDbInfo?.tables?.find( + x => x.pureName == refTableName && x.schemaName == refSchemaName + ); + columns = refTable?.primaryKey?.columns?.map(col => ({ + refColumnName: col.columnName, + })); + } + }} + /> +
+
+ +
+
+ Base column - {fromTableInfo?.pureName} +
+
+ Ref column - {refTableName || '(table not set)'} +
+
+ + {#each columns as column, index} +
+
+ {#key column.columnName} + ({ + label: col.columnName, + value: col.columnName, + }))} + on:change={e => { + if (e.detail) { + columns = columns.map((col, i) => (i == index ? { ...col, columnName: e.detail } : col)); + } + }} + /> + {/key} +
+
+ {#key column.refColumnName} + ({ + label: col.columnName, + value: col.columnName, + }))} + on:change={e => { + if (e.detail) { + columns = columns.map((col, i) => (i == index ? { ...col, refColumnName: e.detail } : col)); + } + }} + /> + {/key} +
+
+ { + const x = [...columns]; + x.splice(index, 1); + columns = x; + }} + /> +
+
+ {/each} + + { + columns = [...columns, {}]; + }} + /> +
+ + + { + setConfig(cfg => ({ + ...cfg, + customJoins: [ + ...(cfg.customJoins || []), + { + baseUniqueName: fromUniuqeName, + refTableName, + refSchemaName, + columns: columns.map(col => ({ + baseColumnName: col.columnName, + refColumnName: col.refColumnName, + })), + }, + ], + })); + closeCurrentModal(); + }} + /> + + + +
+
+ + diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index c6909aa6..ed7c7e18 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -155,6 +155,9 @@ { command: 'perspective.openJson', }, + { + command: 'perspective.customJoin', + }, ]; } diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 19745a4e..6e63d14d 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -1,3 +1,18 @@ + + -
+
+ import { ChangeConfigFunc, ChangePerspectiveConfigFunc, GridConfig, PerspectiveConfig } from 'dbgate-datalib'; + import PerspectiveNodeRow from './PerspectiveNodeRow.svelte'; export let root; + export let config: PerspectiveConfig; + export let setConfig: ChangePerspectiveConfigFunc; + export let conid; + export let database; function processFlatColumns(res, columns) { for (const col of columns) { @@ -20,5 +26,5 @@ {#each getFlatColumns(root) as node} - + {/each} diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 6e63d14d..c8b96744 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -15,7 +15,11 @@ + + + {#each allFilterNames as uniqueName} + + setConfig(cfg => ({ + ...cfg, + filters: { + ...cfg.filters, + [uniqueName]: value, + }, + }))} + onRemoveFilter={value => + setConfig(cfg => ({ + ...cfg, + filters: _.omit(cfg.filters, [uniqueName]), + filterInfos: _.omit(cfg.filterInfos, [uniqueName]), + }))} + /> + {/each} + diff --git a/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte b/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte new file mode 100644 index 00000000..3e8d015e --- /dev/null +++ b/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte @@ -0,0 +1,24 @@ + + +
+
+ {columnName} + + + +
+ +
diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index c8b96744..518cc16f 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -49,6 +49,8 @@ import registerCommand from '../commands/registerCommand'; import { showModal } from '../modals/modalTools'; import CustomJoinModal from './CustomJoinModal.svelte'; + import JsonViewFilters from '../jsonview/JsonViewFilters.svelte'; + import PerspectiveFilters from './PerspectiveFilters.svelte'; const dbg = debug('dbgate:PerspectiveView'); @@ -114,6 +116,10 @@ {/if} + + + +
From 97dc92e413b180c36216d2bae8b804e65f3b9a09 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 4 Aug 2022 08:26:35 +0200 Subject: [PATCH 087/132] perspectives:add to filter ctx menu --- packages/datalib/src/PerspectiveConfig.ts | 1 + packages/datalib/src/PerspectiveTreeNode.ts | 51 ++++++++++++------- .../perspectives/PerspectiveFilters.svelte | 3 +- .../PerspectiveFiltersColumn.svelte | 9 ++-- .../perspectives/PerspectiveNodeRow.svelte | 12 +++++ .../src/perspectives/PerspectiveTable.svelte | 4 +- 6 files changed, 53 insertions(+), 27 deletions(-) diff --git a/packages/datalib/src/PerspectiveConfig.ts b/packages/datalib/src/PerspectiveConfig.ts index bf7d2eea..0d8baad8 100644 --- a/packages/datalib/src/PerspectiveConfig.ts +++ b/packages/datalib/src/PerspectiveConfig.ts @@ -21,6 +21,7 @@ export interface PerspectiveCustomJoinConfig { export interface PerspectiveFilterColumnInfo { columnName: string; filterType: string; + tableName: string; } export interface PerspectiveConfig extends PerspectiveConfigColumns { filters: { [uniqueName: string]: string }; diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index 7a463ed4..06b6c8e4 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -5,6 +5,7 @@ import { PerspectiveConfig, PerspectiveConfigColumns, PerspectiveCustomJoinConfig, + PerspectiveFilterColumnInfo, } from './PerspectiveConfig'; import _isEqual from 'lodash/isEqual'; import _cloneDeep from 'lodash/cloneDeep'; @@ -152,25 +153,25 @@ export abstract class PerspectiveTreeNode { } } - setFilter(value) { - this.setConfig( - cfg => ({ - ...cfg, - filters: { - ...cfg.filters, - [this.uniqueName]: value, - }, - filterInfos: { - ...cfg.filterInfos, - [this.uniqueName]: { - columnName: this.columnName, - filterType: this.filterType, - }, - }, - }), - true - ); - } + // setFilter(value) { + // this.setConfig( + // cfg => ({ + // ...cfg, + // filters: { + // ...cfg.filters, + // [this.uniqueName]: value, + // }, + // filterInfos: { + // ...cfg.filterInfos, + // [this.uniqueName]: { + // columnName: this.columnName, + // filterType: this.filterType, + // }, + // }, + // }), + // true + // ); + // } getFilter() { return this.config.filters[this.uniqueName]; @@ -232,6 +233,10 @@ export abstract class PerspectiveTreeNode { getBaseTableFromThis() { return null; } + + get filterInfo(): PerspectiveFilterColumnInfo { + return null; + } } export class PerspectiveTableColumnNode extends PerspectiveTreeNode { @@ -344,6 +349,14 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode { return this.refTable; } + get filterInfo(): PerspectiveFilterColumnInfo { + return { + columnName: this.columnName, + filterType: this.filterType, + tableName: this.column.pureName, + }; + } + parseFilterCondition() { const filter = this.getFilter(); if (!filter) return null; diff --git a/packages/web/src/perspectives/PerspectiveFilters.svelte b/packages/web/src/perspectives/PerspectiveFilters.svelte index 9b02568b..6f3e4f85 100644 --- a/packages/web/src/perspectives/PerspectiveFilters.svelte +++ b/packages/web/src/perspectives/PerspectiveFilters.svelte @@ -16,10 +16,9 @@ {#each allFilterNames as uniqueName} setConfig(cfg => ({ ...cfg, diff --git a/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte b/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte index 3e8d015e..c15a3618 100644 --- a/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte +++ b/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte @@ -5,20 +5,21 @@ import InlineButton from '../buttons/InlineButton.svelte'; import FontIcon from '../icons/FontIcon.svelte'; import { getFilterType } from 'dbgate-filterparser'; + import { PerspectiveFilterColumnInfo } from 'dbgate-datalib'; + + export let filterInfo: PerspectiveFilterColumnInfo; export let filter; export let onSetFilter; export let onRemoveFilter; - export let filterType; - export let columnName;
- {columnName} + {filterInfo.columnName} ({filterInfo.tableName})
- +
diff --git a/packages/web/src/perspectives/PerspectiveNodeRow.svelte b/packages/web/src/perspectives/PerspectiveNodeRow.svelte index 4f6c55bd..5147893e 100644 --- a/packages/web/src/perspectives/PerspectiveNodeRow.svelte +++ b/packages/web/src/perspectives/PerspectiveNodeRow.svelte @@ -17,7 +17,19 @@ function createMenu() { const customJoin = node.customJoinConfig; + const filterInfo = node.filterInfo; return [ + filterInfo && { + text: 'Add to filter', + onClick: () => + setConfig(cfg => ({ + ...cfg, + filterInfos: { + ...cfg.filterInfos, + [node.uniqueName]: filterInfo, + }, + })), + }, customJoin && { text: 'Remove custom join', onClick: () => diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index 0012e08a..ecf7323a 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -282,7 +282,7 @@ {/each} {/each} -
+ {#each display.rows as row} From 80fea3b01ba0734169c9f167cc3ee20cd0b256f5 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 4 Aug 2022 21:32:06 +0200 Subject: [PATCH 088/132] style --- packages/web/src/perspectives/PerspectiveView.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 518cc16f..8b3bac6e 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -109,7 +109,7 @@
- + {#if root} @@ -117,7 +117,7 @@ - + From 7dc7af0cdbd2e1b870ebc2dc2e64dd9f5bfee2db Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 4 Aug 2022 21:32:20 +0200 Subject: [PATCH 089/132] v5.0.10-beta.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3132e27e..251d1ec4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "5.0.10-beta.9", + "version": "5.0.10-beta.10", "name": "dbgate-all", "workspaces": [ "packages/*", From 25d2c129cd4769836326ddb8909b8f9fbe2b658a Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 5 Aug 2022 19:55:14 +0200 Subject: [PATCH 090/132] perspective ctx menu --- .../src/perspectives/PerspectiveCell.svelte | 3 +- .../PerspectiveHeaderControl.svelte | 1 + .../perspectives/PerspectiveNodeRow.svelte | 44 ++++------------ .../src/perspectives/PerspectiveTable.svelte | 44 +++++++++++----- .../src/perspectives/PerspectiveView.svelte | 2 +- .../web/src/perspectives/perspectiveMenu.ts | 51 +++++++++++++++++++ 6 files changed, 96 insertions(+), 49 deletions(-) create mode 100644 packages/web/src/perspectives/perspectiveMenu.ts diff --git a/packages/web/src/perspectives/PerspectiveCell.svelte b/packages/web/src/perspectives/PerspectiveCell.svelte index 8304fc4c..8bde09d2 100644 --- a/packages/web/src/perspectives/PerspectiveCell.svelte +++ b/packages/web/src/perspectives/PerspectiveCell.svelte @@ -4,9 +4,10 @@ export let value; export let rowSpan; export let rowData; + export let columnIndex; -
{/if} {#if column.showParent(columnLevel)} @@ -116,11 +58,6 @@ .wrap { display: flex; } - .menuButton { - position: absolute; - right: 0; - bottom: 0; - } .label { flex-wrap: nowrap; } @@ -143,12 +80,6 @@ align-self: center; font-size: 18px; } - /* .resizer { - background-color: var(--theme-border); - width: 2px; - cursor: col-resize; - z-index: 1; - } */ .grouping { color: var(--theme-font-alt); white-space: nowrap; diff --git a/packages/web/src/perspectives/perspectiveMenu.ts b/packages/web/src/perspectives/perspectiveMenu.ts index e4fea761..36fb9016 100644 --- a/packages/web/src/perspectives/perspectiveMenu.ts +++ b/packages/web/src/perspectives/perspectiveMenu.ts @@ -1,4 +1,5 @@ import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveTreeNode } from 'dbgate-datalib'; +import _ from 'lodash'; import { showModal } from '../modals/modalTools'; import CustomJoinModal from './CustomJoinModal.svelte'; @@ -15,7 +16,63 @@ export function getPerspectiveNodeMenu(props: PerspectiveNodeMenuProps) { const { node, conid, database, root, config, setConfig } = props; const customJoin = node.customJoinConfig; const filterInfo = node.filterInfo; + + const parentUniqueName = node?.parentNode?.uniqueName || ''; + const uniqueName = node.uniqueName; + const order = config.sort?.[parentUniqueName]?.find(x => x.uniqueName == uniqueName)?.order; + const orderIndex = + config.sort?.[parentUniqueName]?.length > 1 + ? _.findIndex(config.sort?.[parentUniqueName], x => x.uniqueName == uniqueName) + : -1; + const isSortDefined = config.sort?.[parentUniqueName]?.length > 0; + + const setSort = order => { + setConfig( + cfg => ({ + ...cfg, + sort: { + ...cfg.sort, + [parentUniqueName]: [{ uniqueName, order }], + }, + }), + true + ); + }; + + const addToSort = order => { + setConfig( + cfg => ({ + ...cfg, + sort: { + ...cfg.sort, + [parentUniqueName]: [...(cfg.sort?.[parentUniqueName] || []), { uniqueName, order }], + }, + }), + true + ); + }; + + const clearSort = () => { + setConfig( + cfg => ({ + ...cfg, + sort: { + ...cfg.sort, + [parentUniqueName]: [], + }, + }), + true + ); + }; + return [ + { onClick: () => setSort('ASC'), text: 'Sort ascending' }, + { onClick: () => setSort('DESC'), text: 'Sort descending' }, + isSortDefined && !order && { onClick: () => addToSort('ASC'), text: 'Add to sort - ascending' }, + isSortDefined && !order && { onClick: () => addToSort('DESC'), text: 'Add to sort - descending' }, + order && { onClick: () => clearSort(), text: 'Clear sort criteria' }, + { divider: true }, + filterInfo && { text: 'Add to filter', onClick: () => From ae6c486db568fd14ec39ca73b239eef8eed18768 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 6 Aug 2022 11:37:44 +0200 Subject: [PATCH 093/132] perspective load fix --- packages/datalib/src/PerspectiveDataProvider.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/datalib/src/PerspectiveDataProvider.ts b/packages/datalib/src/PerspectiveDataProvider.ts index 4842b20e..a6eb955c 100644 --- a/packages/datalib/src/PerspectiveDataProvider.ts +++ b/packages/datalib/src/PerspectiveDataProvider.ts @@ -70,20 +70,25 @@ export class PerspectiveDataProvider { // console.log('CACHE', tableCache.bindingGroups); let groupIndex = 0; + let loadCalled = false; + let shouldReturn = false; for (; groupIndex < props.bindingValues.length; groupIndex++) { const groupValues = props.bindingValues[groupIndex]; const group = tableCache.getBindingGroup(groupValues); - let loadCalled = false; if (!group.loadedAll) { - // wee need to load next data - await this.loadNextGroup(props, groupIndex); - loadCalled = true; + if (loadCalled) { + shouldReturn = true; + } else { + // we need to load next data + await this.loadNextGroup(props, groupIndex); + loadCalled = true; + } } // console.log('GRP', groupValues, group); rows.push(...group.loadedRows); - if (rows.length >= props.topCount || loadCalled) { + if (rows.length >= props.topCount || shouldReturn) { return { rows: rows.slice(0, props.topCount), incomplete: props.topCount < rows.length || !group.loadedAll || groupIndex < props.bindingValues.length - 1, From c6dbb3174854057d8dcbae44e79784227696b156 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 6 Aug 2022 13:24:51 +0200 Subject: [PATCH 094/132] perspective filters supports lookup --- packages/datalib/src/PerspectiveConfig.ts | 6 ++++- packages/datalib/src/PerspectiveTreeNode.ts | 4 +++- packages/filterparser/src/filterTool.ts | 2 +- .../src/elements/ManagerInnerContainer.svelte | 2 +- .../perspectives/PerspectiveFilters.svelte | 9 +++++++- .../PerspectiveFiltersColumn.svelte | 23 ++++++++++++++++--- .../src/perspectives/PerspectiveView.svelte | 3 ++- packages/web/src/tabs/PerspectiveTab.svelte | 7 ++++++ 8 files changed, 47 insertions(+), 9 deletions(-) diff --git a/packages/datalib/src/PerspectiveConfig.ts b/packages/datalib/src/PerspectiveConfig.ts index 0d8baad8..aafebbcd 100644 --- a/packages/datalib/src/PerspectiveConfig.ts +++ b/packages/datalib/src/PerspectiveConfig.ts @@ -1,3 +1,5 @@ +import { ForeignKeyInfo } from "dbgate-types"; + export interface PerspectiveConfigColumns { expandedColumns: string[]; checkedColumns: string[]; @@ -21,7 +23,9 @@ export interface PerspectiveCustomJoinConfig { export interface PerspectiveFilterColumnInfo { columnName: string; filterType: string; - tableName: string; + pureName: string; + schemaName: string; + foreignKey: ForeignKeyInfo; } export interface PerspectiveConfig extends PerspectiveConfigColumns { filters: { [uniqueName: string]: string }; diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index 06b6c8e4..6c7a0be6 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -353,7 +353,9 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode { return { columnName: this.columnName, filterType: this.filterType, - tableName: this.column.pureName, + pureName: this.column.pureName, + schemaName: this.column.schemaName, + foreignKey: this.foreignKey, }; } diff --git a/packages/filterparser/src/filterTool.ts b/packages/filterparser/src/filterTool.ts index af50bf38..552f37bf 100644 --- a/packages/filterparser/src/filterTool.ts +++ b/packages/filterparser/src/filterTool.ts @@ -3,7 +3,7 @@ import moment from 'moment'; export type FilterMultipleValuesMode = 'is' | 'is_not' | 'contains' | 'begins' | 'ends'; -export function getFilterValueExpression(value, dataType) { +export function getFilterValueExpression(value, dataType?) { if (value == null) return 'NULL'; if (isTypeDateTime(dataType)) return moment(value).format('YYYY-MM-DD HH:mm:ss'); if (value === true) return 'TRUE'; diff --git a/packages/web/src/elements/ManagerInnerContainer.svelte b/packages/web/src/elements/ManagerInnerContainer.svelte index fba5bf99..503a72f2 100644 --- a/packages/web/src/elements/ManagerInnerContainer.svelte +++ b/packages/web/src/elements/ManagerInnerContainer.svelte @@ -1,6 +1,6 @@
diff --git a/packages/web/src/perspectives/PerspectiveFilters.svelte b/packages/web/src/perspectives/PerspectiveFilters.svelte index aa0dbb6e..559649a1 100644 --- a/packages/web/src/perspectives/PerspectiveFilters.svelte +++ b/packages/web/src/perspectives/PerspectiveFilters.svelte @@ -4,13 +4,17 @@ import _ from 'lodash'; import ManagerInnerContainer from '../elements/ManagerInnerContainer.svelte'; -import FontIcon from '../icons/FontIcon.svelte'; + import FontIcon from '../icons/FontIcon.svelte'; import PerspectiveFiltersColumn from './PerspectiveFiltersColumn.svelte'; export let managerSize; export let config: PerspectiveConfig; export let setConfig: ChangePerspectiveConfigFunc; + export let conid; + export let database; + export let driver; + $: allFilterNames = _.keys(config.filterInfos || {}); @@ -25,6 +29,9 @@ import FontIcon from '../icons/FontIcon.svelte'; setConfig(cfg => ({ diff --git a/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte b/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte index c15a3618..a89cce50 100644 --- a/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte +++ b/packages/web/src/perspectives/PerspectiveFiltersColumn.svelte @@ -4,22 +4,39 @@ import ColumnLabel from '../elements/ColumnLabel.svelte'; import InlineButton from '../buttons/InlineButton.svelte'; import FontIcon from '../icons/FontIcon.svelte'; - import { getFilterType } from 'dbgate-filterparser'; + import { getFilterType, getFilterValueExpression } from 'dbgate-filterparser'; import { PerspectiveFilterColumnInfo } from 'dbgate-datalib'; + import { showModal } from '../modals/modalTools'; + import DictionaryLookupModal from '../modals/DictionaryLookupModal.svelte'; + import ValueLookupModal from '../modals/ValueLookupModal.svelte'; export let filterInfo: PerspectiveFilterColumnInfo; export let filter; export let onSetFilter; export let onRemoveFilter; + + export let conid; + export let database; + export let driver;
- {filterInfo.columnName} ({filterInfo.tableName}) + {filterInfo.columnName} ({filterInfo.pureName})
- +
diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 088d7f72..7093b688 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -58,6 +58,7 @@ export let database; export let schemaName; export let pureName; + export let driver; export let config: PerspectiveConfig; export let setConfig: ChangePerspectiveConfigFunc; @@ -118,7 +119,7 @@ - +
diff --git a/packages/web/src/tabs/PerspectiveTab.svelte b/packages/web/src/tabs/PerspectiveTab.svelte index 3d45a0f1..c23d2dda 100644 --- a/packages/web/src/tabs/PerspectiveTab.svelte +++ b/packages/web/src/tabs/PerspectiveTab.svelte @@ -26,6 +26,9 @@ import createActivator, { getActiveComponent } from '../utility/createActivator'; import ToolStripContainer from '../buttons/ToolStripContainer.svelte'; import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte'; + import { findEngineDriver } from 'dbgate-tools'; + import { useConnectionInfo } from '../utility/metadataLoaders'; + import { extensions } from '../stores'; export let tabid; export let conid; @@ -35,6 +38,9 @@ export const activator = createActivator('PerspectiveTab', true); + $: connection = useConnectionInfo({ conid }); + $: driver = findEngineDriver($connection, $extensions); + const config = usePerspectiveConfig(tabid); const cache = new PerspectiveCache(); const loadedCounts = writable({}); @@ -51,6 +57,7 @@ {database} {schemaName} {pureName} + {driver} config={$config} setConfig={(value, reload) => { if (reload) { From f77cc1023b376fdd553228b2dfa61b8ad2b36e90 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 6 Aug 2022 13:49:05 +0200 Subject: [PATCH 095/132] perspective column filter --- packages/web/src/elements/SearchInput.svelte | 1 + .../src/perspectives/PerspectiveTree.svelte | 36 ++++++++++++------- .../src/perspectives/PerspectiveView.svelte | 12 +++++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/packages/web/src/elements/SearchInput.svelte b/packages/web/src/elements/SearchInput.svelte index da5afed8..94524bf7 100644 --- a/packages/web/src/elements/SearchInput.svelte +++ b/packages/web/src/elements/SearchInput.svelte @@ -36,6 +36,7 @@ input { flex: 1; min-width: 10px; + min-height: 22px; width: 10px; border: none; } diff --git a/packages/web/src/perspectives/PerspectiveTree.svelte b/packages/web/src/perspectives/PerspectiveTree.svelte index 9f1b6669..1abf3b04 100644 --- a/packages/web/src/perspectives/PerspectiveTree.svelte +++ b/packages/web/src/perspectives/PerspectiveTree.svelte @@ -1,5 +1,12 @@ -{#each getFlatColumns(root) as node} +{#each getFlatColumns(root, filter) as node} {/each} diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 7093b688..49fb925f 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -51,6 +51,9 @@ import CustomJoinModal from './CustomJoinModal.svelte'; import JsonViewFilters from '../jsonview/JsonViewFilters.svelte'; import PerspectiveFilters from './PerspectiveFilters.svelte'; + import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte'; + import SearchInput from '../elements/SearchInput.svelte'; + import CloseSearchButton from '../buttons/CloseSearchButton.svelte'; const dbg = debug('dbgate:PerspectiveView'); @@ -67,7 +70,7 @@ export let cache; let managerSize; - let nextCacheRef = createRef(null); + let filter; export const activator = createActivator('PerspectiveView', true); @@ -111,9 +114,14 @@
+ + + + + {#if root} - + {/if} From 090ffa064dafcddb7e499e6f73d0bec6cd7ac1b0 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 6 Aug 2022 14:05:18 +0200 Subject: [PATCH 096/132] perspective: open table ctx menu --- packages/datalib/src/PerspectiveDisplay.ts | 4 ++++ packages/datalib/src/PerspectiveTreeNode.ts | 24 +++++++++++++++++++ .../PerspectiveHeaderControl.svelte | 16 ++++++------- .../src/perspectives/PerspectiveTable.svelte | 23 ++++++++++++++++++ 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/packages/datalib/src/PerspectiveDisplay.ts b/packages/datalib/src/PerspectiveDisplay.ts index b10f3155..db3d1eb5 100644 --- a/packages/datalib/src/PerspectiveDisplay.ts +++ b/packages/datalib/src/PerspectiveDisplay.ts @@ -47,6 +47,10 @@ export class PerspectiveDisplayColumn { return this.parentNodes[level]?.title; } + getParentDataAttributes(level) { + return this.parentNodes[level]?.headerDataAttributes; + } + // hasParentNode(node: PerspectiveTreeNode) { // return this.parentNodes.includes(node); // } diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index 6c7a0be6..2d5bc54c 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -68,6 +68,9 @@ export abstract class PerspectiveTreeNode { get fieldName() { return this.codeName; } + get headerDataAttributes() { + return {}; + } get dataField() { return this.codeName; } @@ -375,6 +378,18 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode { return condition; } + + get headerDataAttributes() { + if (this.foreignKey) { + return { + schemaName: this.foreignKey.refSchemaName, + pureName: this.foreignKey.refTableName, + conid: this.databaseConfig.conid, + database: this.databaseConfig.database, + }; + } + return null; + } } export class PerspectiveTableNode extends PerspectiveTreeNode { @@ -432,6 +447,15 @@ export class PerspectiveTableNode extends PerspectiveTreeNode { getBaseTableFromThis() { return this.table; } + + get headerDataAttributes() { + return { + schemaName: this.table.schemaName, + pureName: this.table.pureName, + conid: this.databaseConfig.conid, + database: this.databaseConfig.database, + }; + } } export class PerspectiveViewNode extends PerspectiveTreeNode { diff --git a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte index eba3c5c9..e581d01c 100644 --- a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte +++ b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte @@ -1,6 +1,6 @@ {#if column.isVisible(columnLevel)} -
{/if} {#if column.showParent(columnLevel)} - + {/if}
{ dbg('load next', row.incompleteRowsIndicator); loadedCounts.update(counts => { const res = { ...counts }; for (const id of row.incompleteRowsIndicator) { - res[id] = (res[id] || 100) + 100; + res[id] = (res[id] || PERSPECTIVE_PAGE_SIZE) + PERSPECTIVE_PAGE_SIZE; } return res; }); From ac07b7e1ba3ffb460b7f0f22b06cc58241d5ba80 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 31 Jul 2022 15:30:06 +0200 Subject: [PATCH 076/132] code cleanup --- packages/datalib/src/PerspectiveDisplay.ts | 1 - .../PerspectiveIntersectionObserver.svelte | 34 ----------------- .../src/perspectives/PerspectiveTable.svelte | 38 +++++-------------- 3 files changed, 9 insertions(+), 64 deletions(-) delete mode 100644 packages/web/src/perspectives/PerspectiveIntersectionObserver.svelte diff --git a/packages/datalib/src/PerspectiveDisplay.ts b/packages/datalib/src/PerspectiveDisplay.ts index 70249dc7..b10f3155 100644 --- a/packages/datalib/src/PerspectiveDisplay.ts +++ b/packages/datalib/src/PerspectiveDisplay.ts @@ -76,7 +76,6 @@ export class PerspectiveDisplayRow { rowCellSkips: boolean[] = null; rowJoinIds: number[] = []; - // incompleteRowsIndicator: string[] = null; } export class PerspectiveDisplay { diff --git a/packages/web/src/perspectives/PerspectiveIntersectionObserver.svelte b/packages/web/src/perspectives/PerspectiveIntersectionObserver.svelte deleted file mode 100644 index 06ae0d4e..00000000 --- a/packages/web/src/perspectives/PerspectiveIntersectionObserver.svelte +++ /dev/null @@ -1,34 +0,0 @@ - - -
... data to be loaded {incompleteRowsIndicator.join(',')}
diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index 7ddfca54..c6909aa6 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -16,7 +16,6 @@ import _, { values } from 'lodash'; import { onMount, tick } from 'svelte'; import resizeObserver from '../utility/resizeObserver'; - import PerspectiveIntersectionObserver from './PerspectiveIntersectionObserver.svelte'; import debug from 'debug'; import contextMenu from '../utility/contextMenu'; import DataFilterControl from '../datagrid/DataFilterControl.svelte'; @@ -257,34 +256,15 @@
{ - dbg('load next', row.incompleteRowsIndicator); - loadedCounts.update(counts => { - const res = { ...counts }; - for (const id of row.incompleteRowsIndicator) { - res[id] = (res[id] || PERSPECTIVE_PAGE_SIZE) + PERSPECTIVE_PAGE_SIZE; - } - return res; - }); - }} - />
+ {#if value !== undefined} {/if} diff --git a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte index 8601a2cd..fae412f8 100644 --- a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte +++ b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte @@ -74,6 +74,7 @@ (mouseIn = true)} on:mouseleave={() => (mouseIn = false)} > diff --git a/packages/web/src/perspectives/PerspectiveNodeRow.svelte b/packages/web/src/perspectives/PerspectiveNodeRow.svelte index 5147893e..7a7b2b29 100644 --- a/packages/web/src/perspectives/PerspectiveNodeRow.svelte +++ b/packages/web/src/perspectives/PerspectiveNodeRow.svelte @@ -7,6 +7,7 @@ import { showModal } from '../modals/modalTools'; import contextMenu from '../utility/contextMenu'; import CustomJoinModal from './CustomJoinModal.svelte'; + import { getPerspectiveNodeMenu } from './perspectiveMenu'; export let conid; export let database; @@ -16,41 +17,14 @@ export let setConfig: ChangePerspectiveConfigFunc; function createMenu() { - const customJoin = node.customJoinConfig; - const filterInfo = node.filterInfo; - return [ - filterInfo && { - text: 'Add to filter', - onClick: () => - setConfig(cfg => ({ - ...cfg, - filterInfos: { - ...cfg.filterInfos, - [node.uniqueName]: filterInfo, - }, - })), - }, - customJoin && { - text: 'Remove custom join', - onClick: () => - setConfig(cfg => ({ - ...cfg, - customJoins: (cfg.customJoins || []).filter(x => x.joinid != customJoin.joinid), - })), - }, - customJoin && { - text: 'Edit custom join', - onClick: () => - showModal(CustomJoinModal, { - config, - setConfig, - conid, - database, - root, - editValue: customJoin, - }), - }, - ]; + return getPerspectiveNodeMenu({ + conid, + database, + node, + root, + config, + setConfig, + }); } diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index ecf7323a..576df50f 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -29,6 +29,7 @@ import PerspectiveLoadingIndicator from './PerspectiveLoadingIndicator.svelte'; import PerspectiveHeaderControl from './PerspectiveHeaderControl.svelte'; import createRef from '../utility/createRef'; + import { getPerspectiveNodeMenu } from './perspectiveMenu'; const dbg = debug('dbgate:PerspectivaTable'); export const activator = createActivator('PerspectiveTable', true); @@ -37,6 +38,8 @@ export let loadedCounts; export let config; export let setConfig; + export let conid; + export let database; let dataRows; let domWrapper; @@ -151,18 +154,34 @@ checkLoadAdditionalData(); } - function buildMenu() { - return [ - { - command: 'perspective.refresh', - }, - { - command: 'perspective.openJson', - }, - { - command: 'perspective.customJoin', - }, - ]; + function buildMenu({ targetElement }) { + const res = []; + const td = targetElement.closest('td') || targetElement.closest('th'); + + if (td) { + const columnIndex = td.getAttribute('data-column'); + const column = display?.columns?.[columnIndex]; + if (column) + res.push( + getPerspectiveNodeMenu({ + config, + conid, + database, + node: column.dataNode, + root, + setConfig, + }) + ); + } + + res.push([ + { divider: true }, + { command: 'perspective.refresh' }, + { command: 'perspective.openJson' }, + { command: 'perspective.customJoin' }, + ]); + + return res; } function getLastVisibleRowIndex() { @@ -301,6 +320,7 @@ {#each display.columns as column} {#if !row.rowCellSkips[column.columnIndex]} - + diff --git a/packages/web/src/perspectives/perspectiveMenu.ts b/packages/web/src/perspectives/perspectiveMenu.ts new file mode 100644 index 00000000..e4fea761 --- /dev/null +++ b/packages/web/src/perspectives/perspectiveMenu.ts @@ -0,0 +1,51 @@ +import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveTreeNode } from 'dbgate-datalib'; +import { showModal } from '../modals/modalTools'; +import CustomJoinModal from './CustomJoinModal.svelte'; + +interface PerspectiveNodeMenuProps { + node: PerspectiveTreeNode; + conid: string; + database: string; + root: PerspectiveTreeNode; + config: PerspectiveConfig; + setConfig: ChangePerspectiveConfigFunc; +} + +export function getPerspectiveNodeMenu(props: PerspectiveNodeMenuProps) { + const { node, conid, database, root, config, setConfig } = props; + const customJoin = node.customJoinConfig; + const filterInfo = node.filterInfo; + return [ + filterInfo && { + text: 'Add to filter', + onClick: () => + setConfig(cfg => ({ + ...cfg, + filterInfos: { + ...cfg.filterInfos, + [node.uniqueName]: filterInfo, + }, + })), + }, + customJoin && { + text: 'Remove custom join', + onClick: () => + setConfig(cfg => ({ + ...cfg, + customJoins: (cfg.customJoins || []).filter(x => x.joinid != customJoin.joinid), + })), + }, + customJoin && { + text: 'Edit custom join', + onClick: () => + showModal(CustomJoinModal, { + config, + setConfig, + conid, + database, + root, + editValue: customJoin, + }), + }, + ]; +} From 1ed01e98398f5f38ef356af47f178c12dde0aa24 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 5 Aug 2022 20:17:49 +0200 Subject: [PATCH 091/132] perspective cell highlight --- packages/web/src/modals/DropDownMenu.svelte | 21 +++++++++++++++---- .../src/perspectives/PerspectiveCell.svelte | 4 ++++ .../PerspectiveHeaderControl.svelte | 5 +++++ .../src/perspectives/PerspectiveTable.svelte | 6 +++++- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/packages/web/src/modals/DropDownMenu.svelte b/packages/web/src/modals/DropDownMenu.svelte index 5633fcf1..49b1b7bc 100644 --- a/packages/web/src/modals/DropDownMenu.svelte +++ b/packages/web/src/modals/DropDownMenu.svelte @@ -59,6 +59,19 @@ let submenuOffset; const dispatch = createEventDispatcher(); + let closeHandlers = []; + + function dispatchClose() { + dispatch('close'); + for (const handler of closeHandlers) { + handler(); + } + closeHandlers = []; + } + + function registerCloseHandler(handler) { + closeHandlers.push(handler); + } function handleClick(e, item) { if (item.disabled) return; @@ -70,7 +83,7 @@ submenuOffset = hoverOffset; return; } - dispatch('close'); + dispatchClose(); if (onCloseParent) onCloseParent(); if (item.onClick) item.onClick(); } @@ -84,13 +97,13 @@ submenuOffset = hoverOffset; }, 500); - $: preparedItems = prepareMenuItems(items, { targetElement }, $commandsCustomized); + $: preparedItems = prepareMenuItems(items, { targetElement, registerCloseHandler }, $commandsCustomized); const handleClickOutside = event => { // if (element && !element.contains(event.target) && !event.defaultPrevented) { if (event.target.closest('ul.dropDownMenuMarker')) return; - dispatch('close'); + dispatchClose(); }; onMount(() => { @@ -134,7 +147,7 @@ {...submenuOffset} onCloseParent={() => { if (onCloseParent) onCloseParent(); - dispatch('close'); + dispatchClose(); }} /> {/if} diff --git a/packages/web/src/perspectives/PerspectiveCell.svelte b/packages/web/src/perspectives/PerspectiveCell.svelte index 8bde09d2..01ca6aa4 100644 --- a/packages/web/src/perspectives/PerspectiveCell.svelte +++ b/packages/web/src/perspectives/PerspectiveCell.svelte @@ -25,4 +25,8 @@ border-bottom: 1px solid var(--theme-border); border-right: 1px solid var(--theme-border); } + td:global(.highlight) { + border: 3px solid var(--theme-icon-blue); + padding: 0px; + } diff --git a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte index fae412f8..773964fa 100644 --- a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte +++ b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte @@ -179,4 +179,9 @@ th.columnHeader { position: relative; } + + th:global(.highlight) { + border: 3px solid var(--theme-icon-blue); + padding: 0px; + } diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index 576df50f..6a0c1885 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -154,7 +154,7 @@ checkLoadAdditionalData(); } - function buildMenu({ targetElement }) { + function buildMenu({ targetElement, registerCloseHandler }) { const res = []; const td = targetElement.closest('td') || targetElement.closest('th'); @@ -172,6 +172,10 @@ setConfig, }) ); + td.classList.add('highlight'); + registerCloseHandler(() => { + td.classList.remove('highlight'); + }); } res.push([ From 9a2c12d55806b9c66d9f452d4ef15438de5fb8dc Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 5 Aug 2022 20:55:04 +0200 Subject: [PATCH 092/132] perspective context menu --- .../src/elements/ManagerInnerContainer.svelte | 7 +- .../perspectives/PerspectiveFilters.svelte | 60 ++++++++++------ .../PerspectiveHeaderControl.svelte | 69 ------------------- .../web/src/perspectives/perspectiveMenu.ts | 57 +++++++++++++++ 4 files changed, 101 insertions(+), 92 deletions(-) diff --git a/packages/web/src/elements/ManagerInnerContainer.svelte b/packages/web/src/elements/ManagerInnerContainer.svelte index 33fedb63..fba5bf99 100644 --- a/packages/web/src/elements/ManagerInnerContainer.svelte +++ b/packages/web/src/elements/ManagerInnerContainer.svelte @@ -1,8 +1,9 @@ -
+
@@ -12,4 +13,8 @@ overflow-y: auto; overflow-x: auto; } + + div.isFlex { + display: flex; + } diff --git a/packages/web/src/perspectives/PerspectiveFilters.svelte b/packages/web/src/perspectives/PerspectiveFilters.svelte index 6f3e4f85..aa0dbb6e 100644 --- a/packages/web/src/perspectives/PerspectiveFilters.svelte +++ b/packages/web/src/perspectives/PerspectiveFilters.svelte @@ -4,6 +4,7 @@ import _ from 'lodash'; import ManagerInnerContainer from '../elements/ManagerInnerContainer.svelte'; +import FontIcon from '../icons/FontIcon.svelte'; import PerspectiveFiltersColumn from './PerspectiveFiltersColumn.svelte'; export let managerSize; @@ -13,26 +14,41 @@ $: allFilterNames = _.keys(config.filterInfos || {}); - - {#each allFilterNames as uniqueName} - - setConfig(cfg => ({ - ...cfg, - filters: { - ...cfg.filters, - [uniqueName]: value, - }, - }))} - onRemoveFilter={value => - setConfig(cfg => ({ - ...cfg, - filters: _.omit(cfg.filters, [uniqueName]), - filterInfos: _.omit(cfg.filterInfos, [uniqueName]), - }))} - /> - {/each} + + {#if allFilterNames.length == 0} +
+
No Filters defined
+
Use context menu, command "Add to filter" in table or in tree
+
+ {:else} + {#each allFilterNames as uniqueName} + + setConfig(cfg => ({ + ...cfg, + filters: { + ...cfg.filters, + [uniqueName]: value, + }, + }))} + onRemoveFilter={value => + setConfig(cfg => ({ + ...cfg, + filters: _.omit(cfg.filters, [uniqueName]), + filterInfos: _.omit(cfg.filterInfos, [uniqueName]), + }))} + /> + {/each} + {/if}
+ + diff --git a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte index 773964fa..eba3c5c9 100644 --- a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte +++ b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte @@ -9,8 +9,6 @@ export let config: PerspectiveConfig; export let setConfig: ChangePerspectiveConfigFunc; - let mouseIn; - $: parentUniqueName = column.dataNode?.parentNode?.uniqueName || ''; $: uniqueName = column.dataNode.uniqueName; $: order = config.sort?.[parentUniqueName]?.find(x => x.uniqueName == uniqueName)?.order; @@ -20,54 +18,6 @@ : -1; $: isSortDefined = config.sort?.[parentUniqueName]?.length > 0; - const setSort = order => { - setConfig( - cfg => ({ - ...cfg, - sort: { - ...cfg.sort, - [parentUniqueName]: [{ uniqueName, order }], - }, - }), - true - ); - }; - - const addToSort = order => { - setConfig( - cfg => ({ - ...cfg, - sort: { - ...cfg.sort, - [parentUniqueName]: [...(cfg.sort?.[parentUniqueName] || []), { uniqueName, order }], - }, - }), - true - ); - }; - - const clearSort = () => { - setConfig( - cfg => ({ - ...cfg, - sort: { - ...cfg.sort, - [parentUniqueName]: [], - }, - }), - true - ); - }; - - function getMenu() { - return [ - { onClick: () => setSort('ASC'), text: 'Sort ascending' }, - { onClick: () => setSort('DESC'), text: 'Sort descending' }, - isSortDefined && !order && { onClick: () => addToSort('ASC'), text: 'Add to sort - ascending' }, - isSortDefined && !order && { onClick: () => addToSort('DESC'), text: 'Add to sort - descending' }, - order && { onClick: () => clearSort(), text: 'Clear sort criteria' }, - ]; - } {#if column.isVisible(columnLevel)} @@ -75,8 +25,6 @@ rowspan={column.rowSpan} class="columnHeader" data-column={column.columnIndex} - on:mouseenter={() => (mouseIn = true)} - on:mouseleave={() => (mouseIn = false)} >
@@ -100,12 +48,6 @@ {/if}
- - {#if mouseIn} - - {/if}
+
{column.title} @@ -51,7 +46,12 @@
{column.getParentName(columnLevel)} `data-${k}`)} + >{column.getParentName(columnLevel)}