From 2232a7bab1d582e255231bc6d011972a87910b1e Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Mon, 26 Aug 2024 14:26:38 +0200 Subject: [PATCH] JSONL data editor supports data types --- packages/api/src/shell/modifyJsonLinesReader.js | 11 +++++++---- packages/web/src/datagrid/DataGridCore.svelte | 11 +++++++---- packages/web/src/datagrid/DataGridRow.svelte | 11 +++++++---- packages/web/src/datagrid/InplaceEditor.svelte | 3 +++ packages/web/src/datagrid/InplaceInput.svelte | 4 +++- packages/web/src/datagrid/InplaceSelect.svelte | 9 ++++++++- packages/web/src/datagrid/JslDataGrid.svelte | 17 +++++++++++++++++ .../web/src/datagrid/JslDataGridCore.svelte | 4 ++-- packages/web/src/formview/FormView.svelte | 2 ++ packages/web/src/tabs/ArchiveFileTab.svelte | 9 ++++++++- packages/web/src/tabs/CollectionDataTab.svelte | 2 +- .../dbgate-plugin-mongo/src/backend/driver.js | 4 ++-- 12 files changed, 67 insertions(+), 20 deletions(-) diff --git a/packages/api/src/shell/modifyJsonLinesReader.js b/packages/api/src/shell/modifyJsonLinesReader.js index acffb32f..7aa00736 100644 --- a/packages/api/src/shell/modifyJsonLinesReader.js +++ b/packages/api/src/shell/modifyJsonLinesReader.js @@ -61,10 +61,13 @@ class ParseStream extends stream.Transform { if (update.document) { obj = update.document; } else { - obj = { - ...obj, - ...update.fields, - }; + obj = _.omitBy( + { + ...obj, + ...update.fields, + }, + (v, k) => v.$$undefined$$ + ); } } diff --git a/packages/web/src/datagrid/DataGridCore.svelte b/packages/web/src/datagrid/DataGridCore.svelte index a608cff9..5a96ad8f 100644 --- a/packages/web/src/datagrid/DataGridCore.svelte +++ b/packages/web/src/datagrid/DataGridCore.svelte @@ -457,6 +457,8 @@ export const activator = createActivator('DataGridCore', false); + export let dataEditorTypesBehaviourOverride = null; + const wheelRowCount = 5; const tabVisible: any = getContext('tabVisible'); @@ -829,13 +831,13 @@ showModal(EditCellDataModal, { value: cellData, - dataEditorTypesBehaviour: display?.driver?.dataEditorTypesBehaviour, + dataEditorTypesBehaviour: getEditorTypes(), onSave: value => grider.setCellValue(currentCell[0], realColumnUniqueNames[currentCell[1]], value), }); } export function getEditorTypes() { - return display?.driver?.dataEditorTypesBehaviour; + return dataEditorTypesBehaviourOverride ?? display?.driver?.dataEditorTypesBehaviour; } export function addJsonDocumentEnabled() { @@ -1268,7 +1270,7 @@ const cellData = rowData[realColumnUniqueNames[cell[1]]]; if (shouldOpenMultilineDialog(cellData)) { showModal(EditCellDataModal, { - dataEditorTypesBehaviour: display?.driver?.dataEditorTypesBehaviour, + dataEditorTypesBehaviour: getEditorTypes(), value: cellData, onSave: value => grider.setCellValue(cell[0], realColumnUniqueNames[cell[1]], value), }); @@ -1580,7 +1582,7 @@ } let colIndex = startCol; for (const cell of rowData) { - setCellValue([rowIndex, colIndex], parseCellValue(cell, display?.driver?.dataEditorTypesBehaviour)); + setCellValue([rowIndex, colIndex], parseCellValue(cell, getEditorTypes())); colIndex += 1; } rowIndex += 1; @@ -1965,6 +1967,7 @@ {dispatchInsplaceEditor} {frameSelection} onSetFormView={formViewAvailable && display?.baseTable?.primaryKey ? handleSetFormView : null} + {dataEditorTypesBehaviourOverride} /> {/each} diff --git a/packages/web/src/datagrid/DataGridRow.svelte b/packages/web/src/datagrid/DataGridRow.svelte index f41f86a9..d7acaaf1 100644 --- a/packages/web/src/datagrid/DataGridRow.svelte +++ b/packages/web/src/datagrid/DataGridRow.svelte @@ -27,6 +27,8 @@ export let database; export let driver; + export let dataEditorTypesBehaviourOverride = null; + $: rowData = grider.getRowData(rowIndex); $: rowStatus = grider.getRowStatus(rowIndex); @@ -59,11 +61,12 @@ {inplaceEditorState} {dispatchInsplaceEditor} cellValue={rowData[col.uniqueName]} - options="{col.options}" - canSelectMultipleOptions="{col.canSelectMultipleOptions}" + options={col.options} + canSelectMultipleOptions={col.canSelectMultipleOptions} onSetValue={value => grider.setCellValue(rowIndex, col.uniqueName, value)} {driver} - /> + {dataEditorTypesBehaviourOverride} + /> {:else} @@ -23,6 +24,7 @@ {options} {canSelectMultipleOptions} {driver} + {dataEditorTypesBehaviourOverride} /> {:else} {/if} diff --git a/packages/web/src/datagrid/InplaceInput.svelte b/packages/web/src/datagrid/InplaceInput.svelte index 4160816d..de2ab375 100644 --- a/packages/web/src/datagrid/InplaceInput.svelte +++ b/packages/web/src/datagrid/InplaceInput.svelte @@ -16,6 +16,8 @@ export let cellValue; export let driver; + export let dataEditorTypesBehaviourOverride = null; + let domEditor; let showEditorButton = true; @@ -23,7 +25,7 @@ const isChangedRef = createRef(!!inplaceEditorState.text); - $: editorTypes = driver?.dataEditorTypesBehaviour; + $: editorTypes = dataEditorTypesBehaviourOverride ?? driver?.dataEditorTypesBehaviour; function handleKeyDown(event) { showEditorButton = false; diff --git a/packages/web/src/datagrid/InplaceSelect.svelte b/packages/web/src/datagrid/InplaceSelect.svelte index b95254fc..dbc3a024 100644 --- a/packages/web/src/datagrid/InplaceSelect.svelte +++ b/packages/web/src/datagrid/InplaceSelect.svelte @@ -13,6 +13,8 @@ export let canSelectMultipleOptions; export let driver; + export let dataEditorTypesBehaviourOverride = null; + let value; let valueInit; let optionsData; @@ -20,7 +22,12 @@ onMount(() => { value = - inplaceEditorState.text || stringifyCellValue(cellValue, 'inlineEditorIntent', driver?.dataEditorTypesBehaviour).value; + inplaceEditorState.text || + stringifyCellValue( + cellValue, + 'inlineEditorIntent', + dataEditorTypesBehaviourOverride ?? driver?.dataEditorTypesBehaviour + ).value; valueInit = value; const optionsSelected = value.split(','); diff --git a/packages/web/src/datagrid/JslDataGrid.svelte b/packages/web/src/datagrid/JslDataGrid.svelte index 72e62a8d..da9acad6 100644 --- a/packages/web/src/datagrid/JslDataGrid.svelte +++ b/packages/web/src/datagrid/JslDataGrid.svelte @@ -99,5 +99,22 @@ preprocessLoadedRow={changeSetState?.value?.dataUpdateCommands ? row => processJsonDataUpdateCommands(row, changeSetState?.value?.dataUpdateCommands) : null} + dataEditorTypesBehaviourOverride={{ + parseJsonNull: true, + parseJsonBoolean: true, + parseNumber: true, + parseJsonArray: true, + parseJsonObject: true, + + explicitDataType: true, + + supportNumberType: true, + supportStringType: true, + supportBooleanType: true, + supportNullType: true, + supportJsonType: true, + + supportFieldRemoval: true, + }} /> {/key} diff --git a/packages/web/src/datagrid/JslDataGridCore.svelte b/packages/web/src/datagrid/JslDataGridCore.svelte index f089fe0b..c25164e6 100644 --- a/packages/web/src/datagrid/JslDataGridCore.svelte +++ b/packages/web/src/datagrid/JslDataGridCore.svelte @@ -69,7 +69,7 @@ export let macroPreview; export let macroValues; - export let onPublishedCellsChanged + export let onPublishedCellsChanged; export const activator = createActivator('JslDataGridCore', false); export let setLoadedRows; @@ -201,7 +201,7 @@ bind:this={domGrid} {...$$props} setLoadedRows={handleSetLoadedRows} - onPublishedCellsChanged={value => { + onPublishedCellsChanged={value => { publishedCells = value; if (onPublishedCellsChanged) { onPublishedCellsChanged(value); diff --git a/packages/web/src/formview/FormView.svelte b/packages/web/src/formview/FormView.svelte index 7dce3496..2493db23 100644 --- a/packages/web/src/formview/FormView.svelte +++ b/packages/web/src/formview/FormView.svelte @@ -210,6 +210,7 @@ export let rowCountNotAvailable; // export let formDisplay; export let onNavigate; + export let dataEditorTypesBehaviourOverride = null; let wrapperHeight = 1; let wrapperWidth = 1; @@ -652,6 +653,7 @@ driver={display?.driver} inplaceEditorState={$inplaceEditorState} {dispatchInsplaceEditor} + {dataEditorTypesBehaviourOverride} cellValue={rowData[col.uniqueName]} options={col.options} canSelectMultipleOptions={col.canSelectMultipleOptions} diff --git a/packages/web/src/tabs/ArchiveFileTab.svelte b/packages/web/src/tabs/ArchiveFileTab.svelte index 1756d748..f7391a58 100644 --- a/packages/web/src/tabs/ArchiveFileTab.svelte +++ b/packages/web/src/tabs/ArchiveFileTab.svelte @@ -30,6 +30,7 @@ import { changeSetContainsChanges, createChangeSet } from 'dbgate-datalib'; import localforage from 'localforage'; import { onMount, tick } from 'svelte'; + import _ from 'lodash'; import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte'; import ToolStripCommandSplitButton from '../buttons/ToolStripCommandSplitButton.svelte'; @@ -129,7 +130,13 @@ await apiCall('archive/modify-file', { folder: archiveFolder, file: archiveFile, - changeSet: $changeSetStore.value, + changeSet: { + ...$changeSetStore.value, + updates: $changeSetStore.value.updates.map(update => ({ + ...update, + fields: _.mapValues(update.fields, (v, k) => (v === undefined ? { $$undefined$$: true } : v)), + })), + }, }); await afterSaveChangeSet(); } diff --git a/packages/web/src/tabs/CollectionDataTab.svelte b/packages/web/src/tabs/CollectionDataTab.svelte index 4417742d..e684aad2 100644 --- a/packages/web/src/tabs/CollectionDataTab.svelte +++ b/packages/web/src/tabs/CollectionDataTab.svelte @@ -125,7 +125,7 @@ ...changeSet, updates: changeSet.updates.map(update => ({ ...update, - fields: _.mapValues(update.fields, (v, k) => (v === undefined ? { $undefined: true } : v)), + fields: _.mapValues(update.fields, (v, k) => (v === undefined ? { $$undefined$$: true } : v)), })), }, }); diff --git a/plugins/dbgate-plugin-mongo/src/backend/driver.js b/plugins/dbgate-plugin-mongo/src/backend/driver.js index 58f0a5b6..d9f4c5c4 100644 --- a/plugins/dbgate-plugin-mongo/src/backend/driver.js +++ b/plugins/dbgate-plugin-mongo/src/backend/driver.js @@ -330,10 +330,10 @@ const driver = { } } else { const resdoc = await collection.updateOne(convertObjectId(update.condition), { - $set: convertObjectId(_.pickBy(update.fields, (v, k) => !v?.$undefined)), + $set: convertObjectId(_.pickBy(update.fields, (v, k) => !v?.$$undefined$$)), $unset: _.fromPairs( Object.keys(update.fields) - .filter((k) => update.fields[k]?.$undefined) + .filter((k) => update.fields[k]?.$$undefined$$) .map((k) => [k, '']) ),