mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-02 21:53:58 +00:00
removed obsolete query designer
This commit is contained in:
@@ -1,52 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
import Designer from './Designer.svelte';
|
|
||||||
import { isConnectedByReference, referenceIsConnecting } from './designerTools';
|
|
||||||
import QueryDesignerReference from './QueryDesignerReference.svelte';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Designer
|
|
||||||
{...$$props}
|
|
||||||
settings={{
|
|
||||||
showTableCloseButton: true,
|
|
||||||
allowColumnOperations: true,
|
|
||||||
allowCreateRefByDrag: true,
|
|
||||||
allowTableAlias: true,
|
|
||||||
allowScrollColumns: true,
|
|
||||||
canSelectColumns: true,
|
|
||||||
referenceMenu: ({ designer, reference, onChangeReference, onRemoveReference }) => {
|
|
||||||
const isConnected = isConnectedByReference(
|
|
||||||
designer,
|
|
||||||
{ designerId: reference?.sourceId },
|
|
||||||
{ designerId: reference?.targetId },
|
|
||||||
reference
|
|
||||||
);
|
|
||||||
const setJoinType = joinType => {
|
|
||||||
onChangeReference({
|
|
||||||
...reference,
|
|
||||||
joinType,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return [
|
|
||||||
{ text: 'Remove', onClick: () => onRemoveReference(reference) },
|
|
||||||
!isConnected && [
|
|
||||||
{ divider: true },
|
|
||||||
{ onClick: () => setJoinType('INNER JOIN'), text: 'Set INNER JOIN' },
|
|
||||||
{ onClick: () => setJoinType('LEFT JOIN'), text: 'Set LEFT JOIN' },
|
|
||||||
{ onClick: () => setJoinType('RIGHT JOIN'), text: 'Set RIGHT JOIN' },
|
|
||||||
{ onClick: () => setJoinType('FULL OUTER JOIN'), text: 'Set FULL OUTER JOIN' },
|
|
||||||
{ onClick: () => setJoinType('CROSS JOIN'), text: 'Set CROSS JOIN' },
|
|
||||||
{ onClick: () => setJoinType('WHERE EXISTS'), text: 'Set WHERE EXISTS' },
|
|
||||||
{ onClick: () => setJoinType('WHERE NOT EXISTS'), text: 'Set WHERE NOT EXISTS' },
|
|
||||||
],
|
|
||||||
];
|
|
||||||
},
|
|
||||||
createReferenceText: reference =>
|
|
||||||
_.snakeCase(reference?.joinType || 'CROSS JOIN')
|
|
||||||
.replace('_', '\xa0')
|
|
||||||
.replace('_', '\xa0'),
|
|
||||||
}}
|
|
||||||
referenceComponent={QueryDesignerReference}
|
|
||||||
/>
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { isConnectedByReference } from './designerTools';
|
|
||||||
import contextMenu from '../utility/contextMenu';
|
|
||||||
|
|
||||||
export let reference;
|
|
||||||
export let onRemoveReference;
|
|
||||||
export let onChangeReference;
|
|
||||||
export let designer;
|
|
||||||
export let domTables;
|
|
||||||
export let settings;
|
|
||||||
|
|
||||||
let src = null;
|
|
||||||
let dst = null;
|
|
||||||
|
|
||||||
let minpos;
|
|
||||||
let columnsY = [];
|
|
||||||
|
|
||||||
const BUSWI = 10;
|
|
||||||
const EXTWI = 25;
|
|
||||||
|
|
||||||
$: buswi = settings?.referencePaintSettings?.buswi || BUSWI;
|
|
||||||
$: extwi = settings?.referencePaintSettings?.extwi || EXTWI;
|
|
||||||
|
|
||||||
export function recomputePosition() {
|
|
||||||
const { designerId, sourceId, targetId, columns, joinType } = reference;
|
|
||||||
|
|
||||||
/** @type {DomTableRef} */
|
|
||||||
const sourceTable = domTables[sourceId];
|
|
||||||
/** @type {DomTableRef} */
|
|
||||||
const targetTable = domTables[targetId];
|
|
||||||
if (!sourceTable || !targetTable) return null;
|
|
||||||
const sourceRect = sourceTable.getRect();
|
|
||||||
const targetRect = targetTable.getRect();
|
|
||||||
if (!sourceRect || !targetRect) return null;
|
|
||||||
|
|
||||||
const possibilities = [];
|
|
||||||
possibilities.push({ xsrc: sourceRect.left - buswi, dirsrc: -1, xdst: targetRect.left - buswi, dirdst: -1 });
|
|
||||||
possibilities.push({ xsrc: sourceRect.left - buswi, dirsrc: -1, xdst: targetRect.right + buswi, dirdst: 1 });
|
|
||||||
possibilities.push({ xsrc: sourceRect.right + buswi, dirsrc: 1, xdst: targetRect.left - buswi, dirdst: -1 });
|
|
||||||
possibilities.push({ xsrc: sourceRect.right + buswi, dirsrc: 1, xdst: targetRect.right + buswi, dirdst: 1 });
|
|
||||||
|
|
||||||
minpos = _.minBy(possibilities, p => Math.abs(p.xsrc - p.xdst));
|
|
||||||
|
|
||||||
let srcY = _.mean(columns.map(x => sourceTable.getColumnY(x.source)));
|
|
||||||
let dstY = _.mean(columns.map(x => targetTable.getColumnY(x.target)));
|
|
||||||
|
|
||||||
if (columns.length == 0) {
|
|
||||||
srcY = sourceTable.getColumnY('');
|
|
||||||
dstY = targetTable.getColumnY('');
|
|
||||||
}
|
|
||||||
|
|
||||||
src = { x: minpos.xsrc, y: srcY };
|
|
||||||
dst = { x: minpos.xdst, y: dstY };
|
|
||||||
|
|
||||||
columnsY = columns.map((col, colIndex) => {
|
|
||||||
const y1 = sourceTable.getColumnY(col.source);
|
|
||||||
const y2 = targetTable.getColumnY(col.target);
|
|
||||||
return [y1, y2];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$: {
|
|
||||||
domTables;
|
|
||||||
recomputePosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMenu() {
|
|
||||||
if (settings?.referenceMenu) {
|
|
||||||
return settings?.referenceMenu({
|
|
||||||
designer,
|
|
||||||
reference,
|
|
||||||
onChangeReference,
|
|
||||||
onRemoveReference,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if src && dst && minpos}
|
|
||||||
<svg>
|
|
||||||
<polyline
|
|
||||||
points={`
|
|
||||||
${src.x},${src.y}
|
|
||||||
${src.x + extwi * minpos.dirsrc},${src.y}
|
|
||||||
${dst.x + extwi * minpos.dirdst},${dst.y}
|
|
||||||
${dst.x},${dst.y}
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
{#each columnsY as coly}
|
|
||||||
<polyline
|
|
||||||
points={`
|
|
||||||
${src.x},${src.y}
|
|
||||||
${src.x},${coly[0]}
|
|
||||||
${src.x - buswi * minpos.dirsrc},${coly[0]}
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
<polyline
|
|
||||||
points={`
|
|
||||||
${dst.x},${dst.y}
|
|
||||||
${dst.x},${coly[1]}
|
|
||||||
${dst.x - buswi * minpos.dirdst},${coly[1]}
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<div
|
|
||||||
use:contextMenu={createMenu}
|
|
||||||
class="wrapper"
|
|
||||||
style={`left: ${(src.x + extwi * minpos.dirsrc + dst.x + extwi * minpos.dirdst) / 2 - 16}px;
|
|
||||||
top: ${(src.y + dst.y) / 2 - 16}px`}
|
|
||||||
>
|
|
||||||
<div class="text">
|
|
||||||
{settings?.createReferenceText ? settings?.createReferenceText(reference) : ''}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
svg {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
polyline {
|
|
||||||
fill: none;
|
|
||||||
stroke: var(--theme-bg-4);
|
|
||||||
stroke-width: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
position: absolute;
|
|
||||||
border: 1px solid var(--theme-border);
|
|
||||||
background-color: var(--theme-bg-1);
|
|
||||||
z-index: 900;
|
|
||||||
border-radius: 10px;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
position: relative;
|
|
||||||
float: left;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
z-index: 900;
|
|
||||||
white-space: nowrap;
|
|
||||||
background-color: var(--theme-bg-1);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,274 +0,0 @@
|
|||||||
<script context="module">
|
|
||||||
function getTableDisplayName(column, tables) {
|
|
||||||
const table = (tables || []).find(x => x.designerId == column.designerId);
|
|
||||||
if (table) return table.alias || table.pureName;
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DataFilterControl from '../datagrid/DataFilterControl.svelte';
|
|
||||||
import { findDesignerFilterBehaviour } from '../designer/designerTools';
|
|
||||||
import CheckboxField from '../forms/CheckboxField.svelte';
|
|
||||||
import SelectField from '../forms/SelectField.svelte';
|
|
||||||
import TextField from '../forms/TextField.svelte';
|
|
||||||
import InlineButton from '../buttons/InlineButton.svelte';
|
|
||||||
import uuidv1 from 'uuid/v1';
|
|
||||||
|
|
||||||
import TableControl from './TableControl.svelte';
|
|
||||||
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
|
||||||
|
|
||||||
export let value;
|
|
||||||
export let onChange;
|
|
||||||
|
|
||||||
const changeColumn = col => {
|
|
||||||
onChange(current => ({
|
|
||||||
...current,
|
|
||||||
columns: (current.columns || []).map(x =>
|
|
||||||
x.designerId == col.designerId && x.columnName == col.columnName ? col : x
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeColumn = col => {
|
|
||||||
onChange(current => ({
|
|
||||||
...current,
|
|
||||||
columns: (current.columns || []).filter(x => x.designerId != col.designerId || x.columnName != col.columnName),
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const moveColumn = (col, d) => {
|
|
||||||
onChange(current => {
|
|
||||||
const index = _.findIndex(
|
|
||||||
current.columns || [],
|
|
||||||
x => col.designerId == x.designerId && col.columnName == x.columnName
|
|
||||||
);
|
|
||||||
|
|
||||||
if (index >= 0 && index + d >= 0 && index + d < current.columns?.length) {
|
|
||||||
let columns = [...current.columns];
|
|
||||||
|
|
||||||
const tmp = columns[index + d];
|
|
||||||
columns[index + d] = columns[index];
|
|
||||||
columns[index] = tmp;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...current,
|
|
||||||
columns,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return current;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const addExpressionColumn = () => {
|
|
||||||
onChange(current => ({
|
|
||||||
...current,
|
|
||||||
columns: [...(current.columns || []), { isCustomExpression: true, isOutput: true, designerId: uuidv1() }],
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const addOrCondition = () => {
|
|
||||||
onChange(current => ({
|
|
||||||
...current,
|
|
||||||
settings: {
|
|
||||||
...current?.settings,
|
|
||||||
additionalFilterCount: (current?.settings?.additionalFilterCount ?? 0) + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeOrCondition = () => {
|
|
||||||
onChange(current => ({
|
|
||||||
...current,
|
|
||||||
settings: {
|
|
||||||
...current?.settings,
|
|
||||||
additionalFilterCount: (current?.settings?.additionalFilterCount ?? 1) - 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const addGroupOrCondition = () => {
|
|
||||||
onChange(current => ({
|
|
||||||
...current,
|
|
||||||
settings: {
|
|
||||||
...current?.settings,
|
|
||||||
additionalGroupFilterCount: (current?.settings?.additionalGroupFilterCount ?? 0) + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeGroupOrCondition = () => {
|
|
||||||
onChange(current => ({
|
|
||||||
...current,
|
|
||||||
settings: {
|
|
||||||
...current?.settings,
|
|
||||||
additionalGroupFilterCount: (current?.settings?.additionalGroupFilterCount ?? 1) - 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
$: columns = value?.columns;
|
|
||||||
$: tables = value?.tables;
|
|
||||||
$: settings = value?.settings;
|
|
||||||
$: hasGroupedColumn = !!(columns || []).find(x => x.isGrouped);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="wrapper">
|
|
||||||
<TableControl
|
|
||||||
rows={columns || []}
|
|
||||||
columns={[
|
|
||||||
{ fieldName: 'columnName', slot: 8, header: 'Column/Expression' },
|
|
||||||
{ fieldName: 'tableDisplayName', header: 'Table', formatter: row => getTableDisplayName(row, tables) },
|
|
||||||
{ fieldName: 'isOutput', header: 'Output', slot: 0 },
|
|
||||||
{ fieldName: 'alias', header: 'Alias', slot: 1 },
|
|
||||||
{ fieldName: 'isGrouped', header: 'Group by', slot: 2 },
|
|
||||||
{ fieldName: 'aggregate', header: 'Aggregate', slot: 3 },
|
|
||||||
{ fieldName: 'sortOrder', header: 'Sort order', slot: 4 },
|
|
||||||
{ fieldName: 'filter', header: 'Filter', slot: 5, props: { filterField: 'filter' } },
|
|
||||||
..._.range(settings?.additionalFilterCount || 0).map(index => ({
|
|
||||||
fieldName: `additionalFilter${index + 1}`,
|
|
||||||
header: `OR Filter ${index + 2}`,
|
|
||||||
slot: 5,
|
|
||||||
props: { filterField: `additionalFilter${index + 1}` },
|
|
||||||
})),
|
|
||||||
hasGroupedColumn && {
|
|
||||||
fieldName: 'groupFilter',
|
|
||||||
header: 'Group filter',
|
|
||||||
slot: 5,
|
|
||||||
props: { filterField: 'groupFilter' },
|
|
||||||
},
|
|
||||||
..._.range(hasGroupedColumn ? settings?.additionalGroupFilterCount || 0 : 0).map(index => ({
|
|
||||||
fieldName: `additionalGroupFilter${index + 1}`,
|
|
||||||
header: `OR group filter ${index + 2}`,
|
|
||||||
slot: 5,
|
|
||||||
props: { filterField: `additionalGroupFilter${index + 1}` },
|
|
||||||
})),
|
|
||||||
{ fieldName: 'actions', header: '', slot: 7 },
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<svelte:fragment slot="8" let:row>
|
|
||||||
{#if row.isCustomExpression}
|
|
||||||
<TextField
|
|
||||||
style="min-width:calc(100% - 9px)"
|
|
||||||
value={row.customExpression}
|
|
||||||
on:input={e => {
|
|
||||||
changeColumn({ ...row, customExpression: e.target.value });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
{row.columnName}
|
|
||||||
{/if}
|
|
||||||
</svelte:fragment>
|
|
||||||
|
|
||||||
<svelte:fragment slot="0" let:row>
|
|
||||||
<CheckboxField
|
|
||||||
checked={row.isOutput}
|
|
||||||
on:change={e => {
|
|
||||||
if (e.target.checked) changeColumn({ ...row, isOutput: true });
|
|
||||||
else changeColumn({ ...row, isOutput: false });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="1" let:row>
|
|
||||||
<TextField
|
|
||||||
style="min-width:calc(100% - 9px)"
|
|
||||||
value={row.alias}
|
|
||||||
on:input={e => {
|
|
||||||
changeColumn({ ...row, alias: e.target.value });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="2" let:row>
|
|
||||||
<CheckboxField
|
|
||||||
checked={row.isGrouped}
|
|
||||||
on:change={e => {
|
|
||||||
if (e.target.checked) changeColumn({ ...row, isGrouped: true });
|
|
||||||
else changeColumn({ ...row, isGrouped: false });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="3" let:row>
|
|
||||||
{#if !row.isGrouped}
|
|
||||||
<SelectField
|
|
||||||
isNative
|
|
||||||
style="min-width:calc(100% - 9px)"
|
|
||||||
value={row.aggregate}
|
|
||||||
on:change={e => {
|
|
||||||
changeColumn({ ...row, aggregate: e.detail });
|
|
||||||
}}
|
|
||||||
options={['---', 'MIN', 'MAX', 'COUNT', 'COUNT DISTINCT', 'SUM', 'AVG'].map(x => ({ label: x, value: x }))}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="4" let:row>
|
|
||||||
<SelectField
|
|
||||||
isNative
|
|
||||||
style="min-width:calc(100% - 9px)"
|
|
||||||
value={row.sortOrder?.toString()}
|
|
||||||
on:change={e => {
|
|
||||||
changeColumn({ ...row, sortOrder: parseInt(e.detail) });
|
|
||||||
}}
|
|
||||||
options={[
|
|
||||||
{ label: '---', value: '0' },
|
|
||||||
{ label: '1st, ascending', value: '1' },
|
|
||||||
{ label: '1st, descending', value: '-1' },
|
|
||||||
{ label: '2nd, ascending', value: '2' },
|
|
||||||
{ label: '2nd, descending', value: '-2' },
|
|
||||||
{ label: '3rd, ascending', value: '3' },
|
|
||||||
{ label: '3rd, descending', value: '-3' },
|
|
||||||
{ label: '4th, ascending', value: '4' },
|
|
||||||
{ label: '4th, descending', value: '-4' },
|
|
||||||
{ label: '5th, ascending', value: '5' },
|
|
||||||
{ label: '5th, descending', value: '-5' },
|
|
||||||
{ label: '6th, ascending', value: '6' },
|
|
||||||
{ label: '6th, descending', value: '-6' },
|
|
||||||
{ label: '7th, ascending', value: '7' },
|
|
||||||
{ label: '7th, descending', value: '-7' },
|
|
||||||
{ label: '8th, ascending', value: '8' },
|
|
||||||
{ label: '8th, descending', value: '-8' },
|
|
||||||
{ label: '9th, ascending', value: '9' },
|
|
||||||
{ label: '9th, descending', value: '-9' },
|
|
||||||
{ label: '10th, ascending', value: '10' },
|
|
||||||
{ label: '10th, descending', value: '-10' },
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="5" let:row let:filterField>
|
|
||||||
<DataFilterControl
|
|
||||||
filterBehaviour={findDesignerFilterBehaviour(row, value)}
|
|
||||||
filter={row[filterField]}
|
|
||||||
setFilter={filter => {
|
|
||||||
changeColumn({ ...row, [filterField]: filter });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="7" let:row>
|
|
||||||
<div class="flex">
|
|
||||||
<InlineButton on:click={() => removeColumn(row)} square><FontIcon icon="icon delete" /></InlineButton>
|
|
||||||
<InlineButton on:click={() => moveColumn(row, -1)} square><FontIcon icon="icon arrow-up" /></InlineButton>
|
|
||||||
<InlineButton on:click={() => moveColumn(row, 1)} square><FontIcon icon="icon arrow-down" /></InlineButton>
|
|
||||||
</div>
|
|
||||||
</svelte:fragment>
|
|
||||||
</TableControl>
|
|
||||||
<FormStyledButton value="Add custom expression" on:click={addExpressionColumn} style="width:200px" />
|
|
||||||
<FormStyledButton value="Add OR condition" on:click={addOrCondition} style="width:200px" />
|
|
||||||
{#if settings?.additionalFilterCount > 0}
|
|
||||||
<FormStyledButton value="Remove OR condition" on:click={removeOrCondition} style="width:200px" />
|
|
||||||
{/if}
|
|
||||||
{#if hasGroupedColumn}
|
|
||||||
<FormStyledButton value="Add group OR condition" on:click={addGroupOrCondition} style="width:200px" />
|
|
||||||
{/if}
|
|
||||||
{#if hasGroupedColumn && settings?.additionalGroupFilterCount > 0}
|
|
||||||
<FormStyledButton value="Remove group OR condition" on:click={removeGroupOrCondition} style="width:200px" />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.wrapper {
|
|
||||||
overflow: auto;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Reference in New Issue
Block a user