mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
perspective custom join editing & removing
This commit is contained in:
parent
091e91556d
commit
b05d260caa
@ -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;
|
||||
}
|
||||
|
@ -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}
|
||||
<div class="row">
|
||||
<div class="col-5 mr-1">
|
||||
{#key column.columnName}
|
||||
{#key column.baseColumnName}
|
||||
<SelectField
|
||||
value={column.columnName}
|
||||
value={column.baseColumnName}
|
||||
isNative
|
||||
notSelected
|
||||
options={(fromTableInfo?.columns || []).map(col => ({
|
||||
@ -251,7 +253,7 @@
|
||||
}))}
|
||||
on:change={e => {
|
||||
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"
|
||||
value="Add column"
|
||||
on:click={() => {
|
||||
columns = [...columns, {}];
|
||||
columns = [
|
||||
...columns,
|
||||
{
|
||||
baseColumnName: '',
|
||||
refColumnName: '',
|
||||
},
|
||||
];
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@ -301,20 +309,19 @@
|
||||
<FormSubmit
|
||||
value={'Save'}
|
||||
on:click={async () => {
|
||||
const newJoin = {
|
||||
joinid,
|
||||
joinName,
|
||||
baseUniqueName: fromUniuqeName,
|
||||
refTableName,
|
||||
refSchemaName,
|
||||
columns,
|
||||
};
|
||||
setConfig(cfg => ({
|
||||
...cfg,
|
||||
customJoins: [
|
||||
...(cfg.customJoins || []),
|
||||
{
|
||||
baseUniqueName: fromUniuqeName,
|
||||
refTableName,
|
||||
refSchemaName,
|
||||
columns: columns.map(col => ({
|
||||
baseColumnName: col.columnName,
|
||||
refColumnName: col.refColumnName,
|
||||
})),
|
||||
},
|
||||
],
|
||||
customJoins: editValue
|
||||
? cfg.customJoins.map(x => (x.joinid == editValue.joinid ? newJoin : x))
|
||||
: [...(cfg.customJoins || []), newJoin],
|
||||
}));
|
||||
closeCurrentModal();
|
||||
}}
|
||||
|
@ -1,14 +1,48 @@
|
||||
<script lang="ts">
|
||||
import { PerspectiveTreeNode } from 'dbgate-datalib';
|
||||
import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveTreeNode } from 'dbgate-datalib';
|
||||
|
||||
import ColumnLabel from '../elements/ColumnLabel.svelte';
|
||||
import { plusExpandIcon } from '../icons/expandIcons';
|
||||
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 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>
|
||||
|
||||
<div class="row">
|
||||
<div class="row" use:contextMenu={createMenu}>
|
||||
<span class="expandColumnIcon" style={`margin-right: ${5 + node.level * 10}px`}>
|
||||
<FontIcon
|
||||
icon={node.isExpandable ? plusExpandIcon(node.isExpanded) : 'icon invisible-box'}
|
||||
|
@ -1,7 +1,13 @@
|
||||
<script lang="ts">
|
||||
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 @@
|
||||
</script>
|
||||
|
||||
{#each getFlatColumns(root) as node}
|
||||
<PerspectiveNodeRow {node} />
|
||||
<PerspectiveNodeRow {node} {config} {setConfig} {root} {conid} {database} />
|
||||
{/each}
|
||||
|
@ -15,7 +15,11 @@
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
ChangeConfigFunc,
|
||||
ChangePerspectiveConfigFunc,
|
||||
getTableChildPerspectiveNodes,
|
||||
GridConfig,
|
||||
PerspectiveConfig,
|
||||
PerspectiveDataLoadProps,
|
||||
PerspectiveDataProvider,
|
||||
PerspectiveTableColumnNode,
|
||||
@ -53,8 +57,8 @@
|
||||
export let schemaName;
|
||||
export let pureName;
|
||||
|
||||
export let config;
|
||||
export let setConfig;
|
||||
export let config: PerspectiveConfig;
|
||||
export let setConfig: ChangePerspectiveConfigFunc;
|
||||
export let loadedCounts;
|
||||
|
||||
export let cache;
|
||||
@ -106,7 +110,7 @@
|
||||
<WidgetColumnBarItem title="Choose data" name="perspectiveTree" height="45%">
|
||||
<ManagerInnerContainer width={managerSize}>
|
||||
{#if root}
|
||||
<PerspectiveTree {root} />
|
||||
<PerspectiveTree {root} {config} {setConfig} {conid} {database} />
|
||||
{/if}
|
||||
</ManagerInnerContainer>
|
||||
</WidgetColumnBarItem>
|
||||
|
Loading…
Reference in New Issue
Block a user