query design columns

This commit is contained in:
Jan Prochazka
2021-03-19 16:57:00 +01:00
parent 9c1227273c
commit f7c4bbc708
5 changed files with 210 additions and 23 deletions

View File

@@ -16,6 +16,7 @@
export let targetDragColumn$;
export let onCreateReference;
export let onAddReferenceByColumn;
export let onSelectColumn;
$: designerColumn = (designer.columns || []).find(
x => x.designerId == designerId && x.columnName == column.columnName
@@ -84,13 +85,18 @@
class:isDragTarget={$targetDragColumn$ &&
$targetDragColumn$.designerId == designerId &&
$targetDragColumn$.columnName == column.columnName}
on:mousedown={e =>
onSelectColumn({
...column,
designerId,
})}
use:contextMenu={createMenu}
>
<CheckboxField
checked={!!(designer.columns || []).find(
x => x.designerId == designerId && x.columnName == column.columnName && x.isOutput
)}
onChange={e => {
on:change={e => {
if (e.target.checked) {
onChangeColumn(
{

View File

@@ -28,7 +28,7 @@
export let targetDragColumn$;
export let domCanvas;
export let domTablesRef;
// export let domTablesRef;
export let designer;
export let onMoveReferences;
@@ -104,6 +104,7 @@
class="wrapper"
style={`left: ${movingPosition ? movingPosition.left : left}px; top:${movingPosition ? movingPosition.top : top}px`}
bind:this={domWrapper}
on:mousedown={() => onBringToFront(table)}
>
<div
class="header"
@@ -125,6 +126,7 @@
{designer}
{designerId}
{onChangeColumn}
{onSelectColumn}
{sourceDragColumn$}
{targetDragColumn$}
{onCreateReference}

View File

@@ -0,0 +1,136 @@
<script lang="ts" 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 lang="ts">
import { map } from 'lodash';
import DataFilterControl from '../datagrid/DataFilterControl.svelte';
import { findDesignerFilterType } from '../designer/designerTools';
import CheckboxField from '../forms/CheckboxField.svelte';
import SelectField from '../forms/SelectField.svelte';
import TextField from '../forms/TextField.svelte';
import InlineButton from './InlineButton.svelte';
import TableControl from './TableControl.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),
}));
};
$: columns = value?.columns;
$: tables = value?.tables;
$: hasGroupedColumn = !!(columns || []).find(x => x.isGrouped);
</script>
<TableControl
rows={columns || []}
columns={[
{ fieldName: 'columnName', 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 },
hasGroupedColumn && { fieldName: 'groupFilter', header: 'Group filter', slot: 6 },
{ fieldName: 'actions', header: '', slot: 7 },
]}
>
<svelte:fragment slot="0" let:row>
<CheckboxField
checked={row.isOutput}
onChange={e => {
if (e.target.checked) changeColumn({ ...row, isOutput: true });
else changeColumn({ ...row, isOutput: false });
}}
/>
</svelte:fragment>
<svelte:fragment slot="1" let:row>
<TextField
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
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
value={row.sortOrder}
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' },
]}
/>
</svelte:fragment>
<svelte:fragment slot="5" let:row>
<DataFilterControl
filterType={findDesignerFilterType(row, value)}
filter={row.filter}
setFilter={filter => {
changeColumn({ ...row, filter });
}}
/>
</svelte:fragment>
<svelte:fragment slot="6" let:row>
<DataFilterControl
filterType={findDesignerFilterType(row, value)}
filter={row.groupFilter}
setFilter={groupFilter => {
changeColumn({ ...row, groupFilter });
}}
/>
</svelte:fragment>
<svelte:fragment slot="7" let:row>
<InlineButton on:click={() => removeColumn(row)}>Remove</InlineButton>
</svelte:fragment>
</TableControl>

View File

@@ -1,4 +1,6 @@
<script lang="ts">
import _ from 'lodash';
interface TabDef {
label: string;
slot?: number;
@@ -20,7 +22,7 @@
<div class="main">
<div class="tabs">
{#each tabs as tab, index}
{#each _.compact(tabs) as tab, index}
<div class="tab-item" class:selected={value == index} on:click={() => (value = index)}>
<span class="ml-2">
{tab.label}
@@ -30,7 +32,7 @@
</div>
<div class="content-container">
{#each tabs as tab, index}
{#each _.compact(tabs) as tab, index}
<div class="container" class:isInline class:tabVisible={index == value}>
<svelte:component this={tab.component} {...tab.props} />
{#if tab.slot != null}

View File

@@ -42,6 +42,9 @@
import createReducer from '../utility/createReducer';
import createUndoReducer from '../utility/createUndoReducer';
import _ from 'lodash';
import { findEngineDriver } from 'dbgate-tools';
import { generateDesignedQuery } from '../designer/designerTools';
import QueryDesignColumns from '../elements/QueryDesignColumns.svelte';
export let tabid;
export let conid;
@@ -60,6 +63,7 @@
let domEditor;
$: connection = useConnectionInfo({ conid });
$: engine = findEngineDriver($connection, $extensions);
$: effect = useEffect(() => {
return onSession(sessionId);
@@ -85,6 +89,10 @@
invalidateCommands();
}
$: setEditorData($modelState.value);
$: generatePreview($modelState.value, engine);
export function canKill() {
return !!sessionId;
}
@@ -132,6 +140,12 @@
return $editorState.value || '';
}
const generatePreview = (value, engine) => {
if (!engine || !value) return;
const sql = generateDesignedQuery(value, engine);
sqlPreview = sqlFormatter.format(sql);
};
const handleSessionDone = () => {
busy = false;
// timerLabel.stop();
@@ -152,8 +166,6 @@
},
});
$: setEditorData($modelState.value);
const [modelState, dispatchModel] = createUndoReducer({
tables: [],
references: [],
@@ -169,21 +181,50 @@
// )}
</script>
<QueryDesigner
value={$modelState.value || {}}
{conid}
{database}
engine={$connection && $connection.engine}
onChange={handleChange}
/>
<!--
<VerticalSplitter initialValue="70%">
<ResultTabs {sessionId} {executeNumber}>
<TabPage label="Columns" key="columns">
<QueryDesignColumns value={modelState.value || {}} onChange={handleChange} />
</TabPage>
<TabPage label="SQL" key="sql">
<SqlEditor value={sqlPreview} {engine} readOnly />
</TabPage>
</ResultTabs>
</VerticalSplitter> -->
<svelte:fragment slot="1">
<QueryDesigner
value={$modelState.value || {}}
{conid}
{database}
engine={$connection && $connection.engine}
onChange={handleChange}
/>
</svelte:fragment>
<svelte:fragment slot="2">
<ResultTabs
tabs={[
{
label: 'Columns',
component: QueryDesignColumns,
props: {
value: $modelState.value || {},
onChange: handleChange,
},
},
{
label: 'SQL',
component: SqlEditor,
props: {
engine: $connection && $connection.engine,
readOnly: true,
value: sqlPreview,
},
},
visibleResultTabs && { label: 'Messages', slot: 0 },
]}
{sessionId}
{executeNumber}
>
<svelte:fragment slot="0">
<SocketMessageView
eventName={sessionId ? `session-info-${sessionId}` : null}
{executeNumber}
showProcedure
showLine
/>
</svelte:fragment>
</ResultTabs>
</svelte:fragment>
</VerticalSplitter>