From 1f821fc6549c70626c6d6548f82e97c87ec9c32a Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 13 Nov 2021 11:08:24 +0100 Subject: [PATCH] define description modal --- .../src/datagrid/ColumnHeaderControl.svelte | 2 +- .../web/src/datagrid/DataFilterControl.svelte | 24 +++- packages/web/src/datagrid/DataGridCore.svelte | 3 + .../web/src/elements/DropDownButton.svelte | 3 +- packages/web/src/elements/InlineButton.svelte | 7 +- packages/web/src/icons/FontIcon.svelte | 2 + .../DefineDictionaryDescriptionModal.svelte | 103 ++++++++++++++++++ .../src/modals/DictionaryLookupModal.svelte | 46 ++++++++ .../src/utility/dictionaryDescriptionTools.ts | 75 +++++++++++++ packages/web/src/utility/openArchiveFolder.ts | 1 + 10 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 packages/web/src/modals/DefineDictionaryDescriptionModal.svelte create mode 100644 packages/web/src/modals/DictionaryLookupModal.svelte create mode 100644 packages/web/src/utility/dictionaryDescriptionTools.ts diff --git a/packages/web/src/datagrid/ColumnHeaderControl.svelte b/packages/web/src/datagrid/ColumnHeaderControl.svelte index 715925ef..762ed303 100644 --- a/packages/web/src/datagrid/ColumnHeaderControl.svelte +++ b/packages/web/src/datagrid/ColumnHeaderControl.svelte @@ -72,7 +72,7 @@ {/if} - +
diff --git a/packages/web/src/datagrid/DataFilterControl.svelte b/packages/web/src/datagrid/DataFilterControl.svelte index 32eaddeb..f17b163f 100644 --- a/packages/web/src/datagrid/DataFilterControl.svelte +++ b/packages/web/src/datagrid/DataFilterControl.svelte @@ -12,6 +12,9 @@ import keycodes from '../utility/keycodes'; import DropDownButton from '../elements/DropDownButton.svelte'; + import InlineButton from '../elements/InlineButton.svelte'; + import FontIcon from '../icons/FontIcon.svelte'; + import DictionaryLookupModal from '../modals/DictionaryLookupModal.svelte'; export let isReadOnly = false; export let filterType; @@ -20,6 +23,9 @@ export let showResizeSplitter = false; export let onFocusGrid; export let onGetReference; + export let foreignKey = null; + export let conid = null; + export let database = null; let value; let isError; @@ -190,6 +196,15 @@ } } + function handleShowDictionary() { + showModal(DictionaryLookupModal, { + conid, + database, + pureName: foreignKey.refTableName, + schemaName: foreignKey.refSchemaName, + }); + } + $: value = filter; $: { @@ -226,9 +241,14 @@ on:paste={handlePaste} class:isError class:isOk - placeholder='Filter' + placeholder="Filter" /> - + {#if foreignKey && conid && database} + + + + {/if} + {#if showResizeSplitter}
{/if} diff --git a/packages/web/src/datagrid/DataGridCore.svelte b/packages/web/src/datagrid/DataGridCore.svelte index 45bae5a1..9b699505 100644 --- a/packages/web/src/datagrid/DataGridCore.svelte +++ b/packages/web/src/datagrid/DataGridCore.svelte @@ -1234,6 +1234,9 @@ > (domFilterControlsRef.get()[col.uniqueName] = value)} + foreignKey={col.foreignKey} + {conid} + {database} filterType={col.filterType || getFilterType(col.dataType)} filter={display.getFilter(col.uniqueName)} setFilter={value => display.setFilter(col.uniqueName, value)} diff --git a/packages/web/src/elements/DropDownButton.svelte b/packages/web/src/elements/DropDownButton.svelte index ab35a63a..e7be5adc 100644 --- a/packages/web/src/elements/DropDownButton.svelte +++ b/packages/web/src/elements/DropDownButton.svelte @@ -7,6 +7,7 @@ export let icon = 'icon chevron-down'; export let menu; + export let narrow = false; let domButton; function handleClick() { @@ -17,6 +18,6 @@ } - + diff --git a/packages/web/src/elements/InlineButton.svelte b/packages/web/src/elements/InlineButton.svelte index 2ea2a908..a3579d8d 100644 --- a/packages/web/src/elements/InlineButton.svelte +++ b/packages/web/src/elements/InlineButton.svelte @@ -1,6 +1,7 @@ -
+
@@ -34,6 +35,10 @@ display: flex; } + .narrow { + padding: 3px 1px; + } + .outer.disabled { color: var(--theme-font-3); } diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index dcb024cf..2625fc69 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -66,6 +66,8 @@ 'icon check-all': 'mdi mdi-check-all', 'icon checkbox-blank': 'mdi mdi-checkbox-blank-outline', 'icon checkbox-marked': 'mdi mdi-checkbox-marked-outline', + 'icon dots-horizontal': 'mdi mdi-dots-horizontal', + 'icon dots-vertical': 'mdi mdi-dots-vertical', 'icon run': 'mdi mdi-play', 'icon chevron-down': 'mdi mdi-chevron-down', diff --git a/packages/web/src/modals/DefineDictionaryDescriptionModal.svelte b/packages/web/src/modals/DefineDictionaryDescriptionModal.svelte new file mode 100644 index 00000000..12e3e9ef --- /dev/null +++ b/packages/web/src/modals/DefineDictionaryDescriptionModal.svelte @@ -0,0 +1,103 @@ + + + + + Define description + +
+ + { + $values = { + ...$values, + columns: changeDelimitedColumnList($values.columns, row.columnName, e.target.checked), + }; + }} + /> + +
+ + + + + + + + + { + closeCurrentModal(); + saveDictionaryDescription( + $tableInfo, + conid, + database, + $values.columns, + $values.delimiter, + $values.useForAllDatabases + ); + onConfirm(); + }} + /> + + +
+
+ + diff --git a/packages/web/src/modals/DictionaryLookupModal.svelte b/packages/web/src/modals/DictionaryLookupModal.svelte new file mode 100644 index 00000000..28b3b3dc --- /dev/null +++ b/packages/web/src/modals/DictionaryLookupModal.svelte @@ -0,0 +1,46 @@ + + + + + Lookup from {pureName} + + {pureName} + + + { + closeCurrentModal(); + onConfirm(); + }} + /> + + + + + diff --git a/packages/web/src/utility/dictionaryDescriptionTools.ts b/packages/web/src/utility/dictionaryDescriptionTools.ts new file mode 100644 index 00000000..84b0e684 --- /dev/null +++ b/packages/web/src/utility/dictionaryDescriptionTools.ts @@ -0,0 +1,75 @@ +import { TableInfo } from 'dbgate-types'; +import _ from 'lodash'; +import { getLocalStorage, setLocalStorage, removeLocalStorage } from './storageCache'; + +interface DictionaryDescription { + expression: string; + columns: string[]; + delimiter: string; +} + +function checkDescription(desc: DictionaryDescription, table: TableInfo) { + return desc.columns.length > 0 && desc.columns.every(x => table.columns.find(y => y.columnName == x)); +} + +export function getDictionaryDescription(table: TableInfo, conid: string, database: string): DictionaryDescription { + const keySpecific = `dictionary_spec_${table.schemaName}||${table.pureName}||${conid}||${database}`; + const keyCommon = `dictionary_spec_${table.schemaName}||${table.pureName}`; + + const cachedSpecific = getLocalStorage(keySpecific); + const cachedCommon = getLocalStorage(keyCommon); + + if (cachedSpecific && checkDescription(cachedSpecific, table)) return cachedSpecific; + if (cachedCommon && checkDescription(cachedCommon, table)) return cachedCommon; + + const descColumn = table.columns.find(x => x?.dataType?.toLowerCase()?.includes('char')); + if (descColumn) { + return { + columns: [descColumn.columnName], + delimiter: null, + expression: descColumn.columnName, + }; + } + + return null; +} + +export function parseDelimitedColumnList(columns) { + return _.compact((columns || '').split(',').map(x => x.trim())); +} + +export function changeDelimitedColumnList(columns, columnName, isChecked) { + const parsed = parseDelimitedColumnList(columns); + const includes = parsed.includes(columnName); + if (includes == isChecked) return columns; + if (isChecked) parsed.push(columnName); + else _.remove(parsed, x => x == columnName); + return parsed.join(','); +} + +export function saveDictionaryDescription( + table: TableInfo, + conid: string, + database: string, + expression: string, + delimiter: string, + useForAllDatabases: boolean +) { + const keySpecific = `dictionary_spec_${table.schemaName}||${table.pureName}||${conid}||${database}`; + const keyCommon = `dictionary_spec_${table.schemaName}||${table.pureName}`; + + removeLocalStorage(keySpecific); + if (useForAllDatabases) removeLocalStorage(keyCommon); + + const description = { + columns: parseDelimitedColumnList(expression), + expression, + delimiter, + }; + + if (useForAllDatabases) { + setLocalStorage(keyCommon, description); + } else { + setLocalStorage(keySpecific, description); + } +} diff --git a/packages/web/src/utility/openArchiveFolder.ts b/packages/web/src/utility/openArchiveFolder.ts index 7bc7cbe8..e2ae05fb 100644 --- a/packages/web/src/utility/openArchiveFolder.ts +++ b/packages/web/src/utility/openArchiveFolder.ts @@ -10,5 +10,6 @@ export function openArchiveFolder() { properties: ['openDirectory'], }); const linkedFolder = filePaths && filePaths[0]; + if (!linkedFolder) return; axiosInstance.post('archive/create-link', { linkedFolder }); }