mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 00:16:00 +00:00
perspective custom join editing & removing
This commit is contained in:
@@ -1,6 +1,11 @@
|
|||||||
import { ColumnInfo, DatabaseInfo, ForeignKeyInfo, RangeDefinition, TableInfo, ViewInfo } from 'dbgate-types';
|
import { ColumnInfo, DatabaseInfo, ForeignKeyInfo, RangeDefinition, TableInfo, ViewInfo } from 'dbgate-types';
|
||||||
import { clearConfigCache } from 'prettier';
|
import { clearConfigCache } from 'prettier';
|
||||||
import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveConfigColumns } from './PerspectiveConfig';
|
import {
|
||||||
|
ChangePerspectiveConfigFunc,
|
||||||
|
PerspectiveConfig,
|
||||||
|
PerspectiveConfigColumns,
|
||||||
|
PerspectiveCustomJoinConfig,
|
||||||
|
} from './PerspectiveConfig';
|
||||||
import _isEqual from 'lodash/isEqual';
|
import _isEqual from 'lodash/isEqual';
|
||||||
import _cloneDeep from 'lodash/cloneDeep';
|
import _cloneDeep from 'lodash/cloneDeep';
|
||||||
import _compact from 'lodash/compact';
|
import _compact from 'lodash/compact';
|
||||||
@@ -98,6 +103,9 @@ export abstract class PerspectiveTreeNode {
|
|||||||
get columnName() {
|
get columnName() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
get customJoinConfig(): PerspectiveCustomJoinConfig {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
getChildMatchColumns() {
|
getChildMatchColumns() {
|
||||||
return [];
|
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(
|
export function getTableChildPerspectiveNodes(
|
||||||
table: TableInfo | ViewInfo,
|
table: TableInfo | ViewInfo,
|
||||||
db: DatabaseInfo,
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useConnectionList, useDatabaseInfo, useDatabaseList, useTableInfo } from '../utility/metadataLoaders';
|
import { useConnectionList, useDatabaseInfo, useDatabaseList, useTableInfo } from '../utility/metadataLoaders';
|
||||||
import { onMount, tick } from 'svelte';
|
import { onMount, tick } from 'svelte';
|
||||||
import TargetApplicationSelect from '../forms/TargetApplicationSelect.svelte';
|
import {
|
||||||
import { apiCall } from '../utility/api';
|
ChangePerspectiveConfigFunc,
|
||||||
import { saveDbToApp } from '../utility/appTools';
|
PerspectiveConfig,
|
||||||
import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveTreeNode } from 'dbgate-datalib';
|
PerspectiveCustomJoinConfig,
|
||||||
import FormConnectionSelect from '../impexp/FormConnectionSelect.svelte';
|
PerspectiveTreeNode,
|
||||||
import FormDatabaseSelect from '../impexp/FormDatabaseSelect.svelte';
|
} from 'dbgate-datalib';
|
||||||
import getConnectionLabel from '../utility/getConnectionLabel';
|
import getConnectionLabel from '../utility/getConnectionLabel';
|
||||||
import uuidv1 from 'uuid/v1';
|
import uuidv1 from 'uuid/v1';
|
||||||
import TextField from '../forms/TextField.svelte';
|
import TextField from '../forms/TextField.svelte';
|
||||||
@@ -25,15 +25,16 @@
|
|||||||
export let root: PerspectiveTreeNode;
|
export let root: PerspectiveTreeNode;
|
||||||
export let setConfig: ChangePerspectiveConfigFunc;
|
export let setConfig: ChangePerspectiveConfigFunc;
|
||||||
export let config: PerspectiveConfig;
|
export let config: PerspectiveConfig;
|
||||||
|
export let editValue: PerspectiveCustomJoinConfig = null;
|
||||||
|
|
||||||
let conidOverride = null;
|
let conidOverride = editValue?.conid || null;
|
||||||
let databaseOverride = null;
|
let databaseOverride = editValue?.database || null;
|
||||||
let joinid = uuidv1();
|
let joinid = editValue?.joinid || uuidv1();
|
||||||
|
|
||||||
$: fromDbInfo = useDatabaseInfo({
|
// $: fromDbInfo = useDatabaseInfo({
|
||||||
conid,
|
// conid,
|
||||||
database,
|
// database,
|
||||||
});
|
// });
|
||||||
// $: fromTableInfo = useTableInfo({
|
// $: fromTableInfo = useTableInfo({
|
||||||
// conid: conidOverride || conid,
|
// conid: conidOverride || conid,
|
||||||
// database: databaseOverride || database,
|
// database: databaseOverride || database,
|
||||||
@@ -52,15 +53,16 @@
|
|||||||
pureName: refTableName,
|
pureName: refTableName,
|
||||||
});
|
});
|
||||||
|
|
||||||
let columns = [];
|
let columns = editValue?.columns || [];
|
||||||
// let fromTableName = pureName;
|
// let fromTableName = pureName;
|
||||||
// let fromSchemaName = schemaName;
|
// let fromSchemaName = schemaName;
|
||||||
let fromUniuqeName = root.uniqueName;
|
let fromUniuqeName = editValue?.baseUniqueName || root.uniqueName;
|
||||||
let refTableName = null;
|
let refTableName = editValue?.refTableName || null;
|
||||||
let refSchemaName = null;
|
let refSchemaName = editValue?.refSchemaName || null;
|
||||||
let joinName;
|
let joinName = editValue?.joinName || '';
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
if (editValue) return;
|
||||||
let index = 1;
|
let index = 1;
|
||||||
while (config.customJoins?.find(x => x.joinName == `Custom join ${index}`)) {
|
while (config.customJoins?.find(x => x.joinName == `Custom join ${index}`)) {
|
||||||
index += 1;
|
index += 1;
|
||||||
@@ -240,9 +242,9 @@
|
|||||||
{#each columns as column, index}
|
{#each columns as column, index}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-5 mr-1">
|
<div class="col-5 mr-1">
|
||||||
{#key column.columnName}
|
{#key column.baseColumnName}
|
||||||
<SelectField
|
<SelectField
|
||||||
value={column.columnName}
|
value={column.baseColumnName}
|
||||||
isNative
|
isNative
|
||||||
notSelected
|
notSelected
|
||||||
options={(fromTableInfo?.columns || []).map(col => ({
|
options={(fromTableInfo?.columns || []).map(col => ({
|
||||||
@@ -251,7 +253,7 @@
|
|||||||
}))}
|
}))}
|
||||||
on:change={e => {
|
on:change={e => {
|
||||||
if (e.detail) {
|
if (e.detail) {
|
||||||
columns = columns.map((col, i) => (i == index ? { ...col, columnName: e.detail } : col));
|
columns = columns.map((col, i) => (i == index ? { ...col, baseColumnName: e.detail } : col));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -292,7 +294,13 @@
|
|||||||
type="button"
|
type="button"
|
||||||
value="Add column"
|
value="Add column"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
columns = [...columns, {}];
|
columns = [
|
||||||
|
...columns,
|
||||||
|
{
|
||||||
|
baseColumnName: '',
|
||||||
|
refColumnName: '',
|
||||||
|
},
|
||||||
|
];
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -301,20 +309,19 @@
|
|||||||
<FormSubmit
|
<FormSubmit
|
||||||
value={'Save'}
|
value={'Save'}
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
|
const newJoin = {
|
||||||
|
joinid,
|
||||||
|
joinName,
|
||||||
|
baseUniqueName: fromUniuqeName,
|
||||||
|
refTableName,
|
||||||
|
refSchemaName,
|
||||||
|
columns,
|
||||||
|
};
|
||||||
setConfig(cfg => ({
|
setConfig(cfg => ({
|
||||||
...cfg,
|
...cfg,
|
||||||
customJoins: [
|
customJoins: editValue
|
||||||
...(cfg.customJoins || []),
|
? cfg.customJoins.map(x => (x.joinid == editValue.joinid ? newJoin : x))
|
||||||
{
|
: [...(cfg.customJoins || []), newJoin],
|
||||||
baseUniqueName: fromUniuqeName,
|
|
||||||
refTableName,
|
|
||||||
refSchemaName,
|
|
||||||
columns: columns.map(col => ({
|
|
||||||
baseColumnName: col.columnName,
|
|
||||||
refColumnName: col.refColumnName,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}));
|
}));
|
||||||
closeCurrentModal();
|
closeCurrentModal();
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,14 +1,48 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PerspectiveTreeNode } from 'dbgate-datalib';
|
import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveTreeNode } from 'dbgate-datalib';
|
||||||
|
|
||||||
import ColumnLabel from '../elements/ColumnLabel.svelte';
|
import ColumnLabel from '../elements/ColumnLabel.svelte';
|
||||||
import { plusExpandIcon } from '../icons/expandIcons';
|
import { plusExpandIcon } from '../icons/expandIcons';
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
|
import { showModal } from '../modals/modalTools';
|
||||||
|
import contextMenu from '../utility/contextMenu';
|
||||||
|
import CustomJoinModal from './CustomJoinModal.svelte';
|
||||||
|
|
||||||
|
export let conid;
|
||||||
|
export let database;
|
||||||
export let node: PerspectiveTreeNode;
|
export let node: PerspectiveTreeNode;
|
||||||
|
export let root: PerspectiveTreeNode;
|
||||||
|
export let config: PerspectiveConfig;
|
||||||
|
export let setConfig: ChangePerspectiveConfigFunc;
|
||||||
|
|
||||||
|
function createMenu() {
|
||||||
|
const customJoin = node.customJoinConfig;
|
||||||
|
return [
|
||||||
|
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,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row" use:contextMenu={createMenu}>
|
||||||
<span class="expandColumnIcon" style={`margin-right: ${5 + node.level * 10}px`}>
|
<span class="expandColumnIcon" style={`margin-right: ${5 + node.level * 10}px`}>
|
||||||
<FontIcon
|
<FontIcon
|
||||||
icon={node.isExpandable ? plusExpandIcon(node.isExpanded) : 'icon invisible-box'}
|
icon={node.isExpandable ? plusExpandIcon(node.isExpanded) : 'icon invisible-box'}
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { ChangeConfigFunc, ChangePerspectiveConfigFunc, GridConfig, PerspectiveConfig } from 'dbgate-datalib';
|
||||||
|
|
||||||
import PerspectiveNodeRow from './PerspectiveNodeRow.svelte';
|
import PerspectiveNodeRow from './PerspectiveNodeRow.svelte';
|
||||||
|
|
||||||
export let root;
|
export let root;
|
||||||
|
export let config: PerspectiveConfig;
|
||||||
|
export let setConfig: ChangePerspectiveConfigFunc;
|
||||||
|
export let conid;
|
||||||
|
export let database;
|
||||||
|
|
||||||
function processFlatColumns(res, columns) {
|
function processFlatColumns(res, columns) {
|
||||||
for (const col of columns) {
|
for (const col of columns) {
|
||||||
@@ -20,5 +26,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each getFlatColumns(root) as node}
|
{#each getFlatColumns(root) as node}
|
||||||
<PerspectiveNodeRow {node} />
|
<PerspectiveNodeRow {node} {config} {setConfig} {root} {conid} {database} />
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -15,7 +15,11 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
|
ChangeConfigFunc,
|
||||||
|
ChangePerspectiveConfigFunc,
|
||||||
getTableChildPerspectiveNodes,
|
getTableChildPerspectiveNodes,
|
||||||
|
GridConfig,
|
||||||
|
PerspectiveConfig,
|
||||||
PerspectiveDataLoadProps,
|
PerspectiveDataLoadProps,
|
||||||
PerspectiveDataProvider,
|
PerspectiveDataProvider,
|
||||||
PerspectiveTableColumnNode,
|
PerspectiveTableColumnNode,
|
||||||
@@ -53,8 +57,8 @@
|
|||||||
export let schemaName;
|
export let schemaName;
|
||||||
export let pureName;
|
export let pureName;
|
||||||
|
|
||||||
export let config;
|
export let config: PerspectiveConfig;
|
||||||
export let setConfig;
|
export let setConfig: ChangePerspectiveConfigFunc;
|
||||||
export let loadedCounts;
|
export let loadedCounts;
|
||||||
|
|
||||||
export let cache;
|
export let cache;
|
||||||
@@ -106,7 +110,7 @@
|
|||||||
<WidgetColumnBarItem title="Choose data" name="perspectiveTree" height="45%">
|
<WidgetColumnBarItem title="Choose data" name="perspectiveTree" height="45%">
|
||||||
<ManagerInnerContainer width={managerSize}>
|
<ManagerInnerContainer width={managerSize}>
|
||||||
{#if root}
|
{#if root}
|
||||||
<PerspectiveTree {root} />
|
<PerspectiveTree {root} {config} {setConfig} {conid} {database} />
|
||||||
{/if}
|
{/if}
|
||||||
</ManagerInnerContainer>
|
</ManagerInnerContainer>
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
|
|||||||
Reference in New Issue
Block a user