diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index 960b3326..b5971fa9 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -1,6 +1,11 @@ import { ColumnInfo, DatabaseInfo, ForeignKeyInfo, RangeDefinition, TableInfo, ViewInfo } from 'dbgate-types'; import { clearConfigCache } from 'prettier'; -import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveConfigColumns } from './PerspectiveConfig'; +import { + ChangePerspectiveConfigFunc, + PerspectiveConfig, + PerspectiveConfigColumns, + PerspectiveCustomJoinConfig, +} from './PerspectiveConfig'; import _isEqual from 'lodash/isEqual'; import _cloneDeep from 'lodash/cloneDeep'; import _compact from 'lodash/compact'; @@ -98,6 +103,9 @@ export abstract class PerspectiveTreeNode { get columnName() { return null; } + get customJoinConfig(): PerspectiveCustomJoinConfig { + return null; + } getChildMatchColumns() { return []; @@ -512,6 +520,77 @@ export class PerspectiveTableReferenceNode extends PerspectiveTableNode { } } +export class PerspectiveCustomJoinTreeNode extends PerspectiveTableNode { + constructor( + public customJoin: PerspectiveCustomJoinConfig, + db: DatabaseInfo, + config: PerspectiveConfig, + setConfig: ChangePerspectiveConfigFunc, + public dataProvider: PerspectiveDataProvider, + databaseConfig: PerspectiveDatabaseConfig, + parentNode: PerspectiveTreeNode + ) { + super( + db.tables.find(x => x.pureName == customJoin.refTableName && x.schemaName == customJoin.refSchemaName), + db, + config, + setConfig, + dataProvider, + databaseConfig, + parentNode + ); + } + + matchChildRow(parentRow: any, childRow: any): boolean { + for (const column of this.customJoin.columns) { + if (parentRow[column.baseColumnName] != childRow[column.refColumnName]) { + return false; + } + } + return true; + } + + getChildMatchColumns() { + return this.customJoin.columns.map(x => x.refColumnName); + } + + getParentMatchColumns() { + return this.customJoin.columns.map(x => x.baseColumnName); + } + + getNodeLoadProps(parentRows: any[]): PerspectiveDataLoadProps { + return { + schemaName: this.table.schemaName, + pureName: this.table.pureName, + bindingColumns: this.getChildMatchColumns(), + bindingValues: _uniqBy( + parentRows.map(row => this.customJoin.columns.map(x => row[x.baseColumnName])), + stableStringify + ), + dataColumns: this.getDataLoadColumns(), + databaseConfig: this.databaseConfig, + orderBy: this.getOrderBy(this.table), + condition: this.getChildrenCondition(), + }; + } + + get title() { + return this.customJoin.joinName; + } + + get icon() { + return 'icon custom-join'; + } + + get codeName() { + return this.customJoin.joinid; + } + + get customJoinConfig(): PerspectiveCustomJoinConfig { + return this.customJoin; + } +} + export function getTableChildPerspectiveNodes( table: TableInfo | ViewInfo, db: DatabaseInfo, @@ -551,5 +630,14 @@ export function getTableChildPerspectiveNodes( ); } } + + for (const join of config.customJoins || []) { + if (join.baseUniqueName == parentColumn.uniqueName) { + res.push( + new PerspectiveCustomJoinTreeNode(join, db, config, setConfig, dataProvider, databaseConfig, parentColumn) + ); + } + } + return res; } diff --git a/packages/web/src/perspectives/CustomJoinModal.svelte b/packages/web/src/perspectives/CustomJoinModal.svelte index d7747b66..ae0ee531 100644 --- a/packages/web/src/perspectives/CustomJoinModal.svelte +++ b/packages/web/src/perspectives/CustomJoinModal.svelte @@ -10,12 +10,12 @@ import _ from 'lodash'; import { useConnectionList, useDatabaseInfo, useDatabaseList, useTableInfo } from '../utility/metadataLoaders'; import { onMount, tick } from 'svelte'; - import TargetApplicationSelect from '../forms/TargetApplicationSelect.svelte'; - import { apiCall } from '../utility/api'; - import { saveDbToApp } from '../utility/appTools'; - import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveTreeNode } from 'dbgate-datalib'; - import FormConnectionSelect from '../impexp/FormConnectionSelect.svelte'; - import FormDatabaseSelect from '../impexp/FormDatabaseSelect.svelte'; + import { + ChangePerspectiveConfigFunc, + PerspectiveConfig, + PerspectiveCustomJoinConfig, + PerspectiveTreeNode, + } from 'dbgate-datalib'; import getConnectionLabel from '../utility/getConnectionLabel'; import uuidv1 from 'uuid/v1'; import TextField from '../forms/TextField.svelte'; @@ -25,15 +25,16 @@ export let root: PerspectiveTreeNode; export let setConfig: ChangePerspectiveConfigFunc; export let config: PerspectiveConfig; + export let editValue: PerspectiveCustomJoinConfig = null; - let conidOverride = null; - let databaseOverride = null; - let joinid = uuidv1(); + let conidOverride = editValue?.conid || null; + let databaseOverride = editValue?.database || null; + let joinid = editValue?.joinid || uuidv1(); - $: fromDbInfo = useDatabaseInfo({ - conid, - database, - }); + // $: fromDbInfo = useDatabaseInfo({ + // conid, + // database, + // }); // $: fromTableInfo = useTableInfo({ // conid: conidOverride || conid, // database: databaseOverride || database, @@ -52,15 +53,16 @@ pureName: refTableName, }); - let columns = []; + let columns = editValue?.columns || []; // let fromTableName = pureName; // let fromSchemaName = schemaName; - let fromUniuqeName = root.uniqueName; - let refTableName = null; - let refSchemaName = null; - let joinName; + let fromUniuqeName = editValue?.baseUniqueName || root.uniqueName; + let refTableName = editValue?.refTableName || null; + let refSchemaName = editValue?.refSchemaName || null; + let joinName = editValue?.joinName || ''; onMount(() => { + if (editValue) return; let index = 1; while (config.customJoins?.find(x => x.joinName == `Custom join ${index}`)) { index += 1; @@ -240,9 +242,9 @@ {#each columns as column, index}