mirror of
https://github.com/dbgate/dbgate
synced 2024-11-08 04:35:58 +00:00
JSONL data editor supports data types
This commit is contained in:
parent
32ebd86171
commit
2232a7bab1
@ -61,10 +61,13 @@ class ParseStream extends stream.Transform {
|
|||||||
if (update.document) {
|
if (update.document) {
|
||||||
obj = update.document;
|
obj = update.document;
|
||||||
} else {
|
} else {
|
||||||
obj = {
|
obj = _.omitBy(
|
||||||
...obj,
|
{
|
||||||
...update.fields,
|
...obj,
|
||||||
};
|
...update.fields,
|
||||||
|
},
|
||||||
|
(v, k) => v.$$undefined$$
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,6 +457,8 @@
|
|||||||
|
|
||||||
export const activator = createActivator('DataGridCore', false);
|
export const activator = createActivator('DataGridCore', false);
|
||||||
|
|
||||||
|
export let dataEditorTypesBehaviourOverride = null;
|
||||||
|
|
||||||
const wheelRowCount = 5;
|
const wheelRowCount = 5;
|
||||||
const tabVisible: any = getContext('tabVisible');
|
const tabVisible: any = getContext('tabVisible');
|
||||||
|
|
||||||
@ -829,13 +831,13 @@
|
|||||||
|
|
||||||
showModal(EditCellDataModal, {
|
showModal(EditCellDataModal, {
|
||||||
value: cellData,
|
value: cellData,
|
||||||
dataEditorTypesBehaviour: display?.driver?.dataEditorTypesBehaviour,
|
dataEditorTypesBehaviour: getEditorTypes(),
|
||||||
onSave: value => grider.setCellValue(currentCell[0], realColumnUniqueNames[currentCell[1]], value),
|
onSave: value => grider.setCellValue(currentCell[0], realColumnUniqueNames[currentCell[1]], value),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEditorTypes() {
|
export function getEditorTypes() {
|
||||||
return display?.driver?.dataEditorTypesBehaviour;
|
return dataEditorTypesBehaviourOverride ?? display?.driver?.dataEditorTypesBehaviour;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addJsonDocumentEnabled() {
|
export function addJsonDocumentEnabled() {
|
||||||
@ -1268,7 +1270,7 @@
|
|||||||
const cellData = rowData[realColumnUniqueNames[cell[1]]];
|
const cellData = rowData[realColumnUniqueNames[cell[1]]];
|
||||||
if (shouldOpenMultilineDialog(cellData)) {
|
if (shouldOpenMultilineDialog(cellData)) {
|
||||||
showModal(EditCellDataModal, {
|
showModal(EditCellDataModal, {
|
||||||
dataEditorTypesBehaviour: display?.driver?.dataEditorTypesBehaviour,
|
dataEditorTypesBehaviour: getEditorTypes(),
|
||||||
value: cellData,
|
value: cellData,
|
||||||
onSave: value => grider.setCellValue(cell[0], realColumnUniqueNames[cell[1]], value),
|
onSave: value => grider.setCellValue(cell[0], realColumnUniqueNames[cell[1]], value),
|
||||||
});
|
});
|
||||||
@ -1580,7 +1582,7 @@
|
|||||||
}
|
}
|
||||||
let colIndex = startCol;
|
let colIndex = startCol;
|
||||||
for (const cell of rowData) {
|
for (const cell of rowData) {
|
||||||
setCellValue([rowIndex, colIndex], parseCellValue(cell, display?.driver?.dataEditorTypesBehaviour));
|
setCellValue([rowIndex, colIndex], parseCellValue(cell, getEditorTypes()));
|
||||||
colIndex += 1;
|
colIndex += 1;
|
||||||
}
|
}
|
||||||
rowIndex += 1;
|
rowIndex += 1;
|
||||||
@ -1965,6 +1967,7 @@
|
|||||||
{dispatchInsplaceEditor}
|
{dispatchInsplaceEditor}
|
||||||
{frameSelection}
|
{frameSelection}
|
||||||
onSetFormView={formViewAvailable && display?.baseTable?.primaryKey ? handleSetFormView : null}
|
onSetFormView={formViewAvailable && display?.baseTable?.primaryKey ? handleSetFormView : null}
|
||||||
|
{dataEditorTypesBehaviourOverride}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
export let database;
|
export let database;
|
||||||
export let driver;
|
export let driver;
|
||||||
|
|
||||||
|
export let dataEditorTypesBehaviourOverride = null;
|
||||||
|
|
||||||
$: rowData = grider.getRowData(rowIndex);
|
$: rowData = grider.getRowData(rowIndex);
|
||||||
$: rowStatus = grider.getRowStatus(rowIndex);
|
$: rowStatus = grider.getRowStatus(rowIndex);
|
||||||
|
|
||||||
@ -59,11 +61,12 @@
|
|||||||
{inplaceEditorState}
|
{inplaceEditorState}
|
||||||
{dispatchInsplaceEditor}
|
{dispatchInsplaceEditor}
|
||||||
cellValue={rowData[col.uniqueName]}
|
cellValue={rowData[col.uniqueName]}
|
||||||
options="{col.options}"
|
options={col.options}
|
||||||
canSelectMultipleOptions="{col.canSelectMultipleOptions}"
|
canSelectMultipleOptions={col.canSelectMultipleOptions}
|
||||||
onSetValue={value => grider.setCellValue(rowIndex, col.uniqueName, value)}
|
onSetValue={value => grider.setCellValue(rowIndex, col.uniqueName, value)}
|
||||||
{driver}
|
{driver}
|
||||||
/>
|
{dataEditorTypesBehaviourOverride}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<DataGridCell
|
<DataGridCell
|
||||||
{rowIndex}
|
{rowIndex}
|
||||||
@ -71,7 +74,7 @@
|
|||||||
{col}
|
{col}
|
||||||
{conid}
|
{conid}
|
||||||
{database}
|
{database}
|
||||||
editorTypes={driver?.dataEditorTypesBehaviour}
|
editorTypes={dataEditorTypesBehaviourOverride ?? driver?.dataEditorTypesBehaviour}
|
||||||
allowHintField={hintFieldsAllowed?.includes(col.uniqueName)}
|
allowHintField={hintFieldsAllowed?.includes(col.uniqueName)}
|
||||||
isSelected={frameSelection ? false : cellIsSelected(rowIndex, col.colIndex, selectedCells)}
|
isSelected={frameSelection ? false : cellIsSelected(rowIndex, col.colIndex, selectedCells)}
|
||||||
isCurrentCell={col.colIndex == currentCellColumn}
|
isCurrentCell={col.colIndex == currentCellColumn}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
export let options;
|
export let options;
|
||||||
export let canSelectMultipleOptions;
|
export let canSelectMultipleOptions;
|
||||||
export let driver;
|
export let driver;
|
||||||
|
export let dataEditorTypesBehaviourOverride = null;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<td class="editor">
|
<td class="editor">
|
||||||
@ -23,6 +24,7 @@
|
|||||||
{options}
|
{options}
|
||||||
{canSelectMultipleOptions}
|
{canSelectMultipleOptions}
|
||||||
{driver}
|
{driver}
|
||||||
|
{dataEditorTypesBehaviourOverride}
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<InplaceInput
|
<InplaceInput
|
||||||
@ -32,6 +34,7 @@
|
|||||||
{cellValue}
|
{cellValue}
|
||||||
{onSetValue}
|
{onSetValue}
|
||||||
{driver}
|
{driver}
|
||||||
|
{dataEditorTypesBehaviourOverride}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
export let cellValue;
|
export let cellValue;
|
||||||
export let driver;
|
export let driver;
|
||||||
|
|
||||||
|
export let dataEditorTypesBehaviourOverride = null;
|
||||||
|
|
||||||
let domEditor;
|
let domEditor;
|
||||||
let showEditorButton = true;
|
let showEditorButton = true;
|
||||||
|
|
||||||
@ -23,7 +25,7 @@
|
|||||||
|
|
||||||
const isChangedRef = createRef(!!inplaceEditorState.text);
|
const isChangedRef = createRef(!!inplaceEditorState.text);
|
||||||
|
|
||||||
$: editorTypes = driver?.dataEditorTypesBehaviour;
|
$: editorTypes = dataEditorTypesBehaviourOverride ?? driver?.dataEditorTypesBehaviour;
|
||||||
|
|
||||||
function handleKeyDown(event) {
|
function handleKeyDown(event) {
|
||||||
showEditorButton = false;
|
showEditorButton = false;
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
export let canSelectMultipleOptions;
|
export let canSelectMultipleOptions;
|
||||||
export let driver;
|
export let driver;
|
||||||
|
|
||||||
|
export let dataEditorTypesBehaviourOverride = null;
|
||||||
|
|
||||||
let value;
|
let value;
|
||||||
let valueInit;
|
let valueInit;
|
||||||
let optionsData;
|
let optionsData;
|
||||||
@ -20,7 +22,12 @@
|
|||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
value =
|
value =
|
||||||
inplaceEditorState.text || stringifyCellValue(cellValue, 'inlineEditorIntent', driver?.dataEditorTypesBehaviour).value;
|
inplaceEditorState.text ||
|
||||||
|
stringifyCellValue(
|
||||||
|
cellValue,
|
||||||
|
'inlineEditorIntent',
|
||||||
|
dataEditorTypesBehaviourOverride ?? driver?.dataEditorTypesBehaviour
|
||||||
|
).value;
|
||||||
valueInit = value;
|
valueInit = value;
|
||||||
|
|
||||||
const optionsSelected = value.split(',');
|
const optionsSelected = value.split(',');
|
||||||
|
@ -99,5 +99,22 @@
|
|||||||
preprocessLoadedRow={changeSetState?.value?.dataUpdateCommands
|
preprocessLoadedRow={changeSetState?.value?.dataUpdateCommands
|
||||||
? row => processJsonDataUpdateCommands(row, changeSetState?.value?.dataUpdateCommands)
|
? row => processJsonDataUpdateCommands(row, changeSetState?.value?.dataUpdateCommands)
|
||||||
: null}
|
: 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}
|
{/key}
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
export let macroPreview;
|
export let macroPreview;
|
||||||
export let macroValues;
|
export let macroValues;
|
||||||
export let onPublishedCellsChanged
|
export let onPublishedCellsChanged;
|
||||||
export const activator = createActivator('JslDataGridCore', false);
|
export const activator = createActivator('JslDataGridCore', false);
|
||||||
|
|
||||||
export let setLoadedRows;
|
export let setLoadedRows;
|
||||||
@ -201,7 +201,7 @@
|
|||||||
bind:this={domGrid}
|
bind:this={domGrid}
|
||||||
{...$$props}
|
{...$$props}
|
||||||
setLoadedRows={handleSetLoadedRows}
|
setLoadedRows={handleSetLoadedRows}
|
||||||
onPublishedCellsChanged={value => {
|
onPublishedCellsChanged={value => {
|
||||||
publishedCells = value;
|
publishedCells = value;
|
||||||
if (onPublishedCellsChanged) {
|
if (onPublishedCellsChanged) {
|
||||||
onPublishedCellsChanged(value);
|
onPublishedCellsChanged(value);
|
||||||
|
@ -210,6 +210,7 @@
|
|||||||
export let rowCountNotAvailable;
|
export let rowCountNotAvailable;
|
||||||
// export let formDisplay;
|
// export let formDisplay;
|
||||||
export let onNavigate;
|
export let onNavigate;
|
||||||
|
export let dataEditorTypesBehaviourOverride = null;
|
||||||
|
|
||||||
let wrapperHeight = 1;
|
let wrapperHeight = 1;
|
||||||
let wrapperWidth = 1;
|
let wrapperWidth = 1;
|
||||||
@ -652,6 +653,7 @@
|
|||||||
driver={display?.driver}
|
driver={display?.driver}
|
||||||
inplaceEditorState={$inplaceEditorState}
|
inplaceEditorState={$inplaceEditorState}
|
||||||
{dispatchInsplaceEditor}
|
{dispatchInsplaceEditor}
|
||||||
|
{dataEditorTypesBehaviourOverride}
|
||||||
cellValue={rowData[col.uniqueName]}
|
cellValue={rowData[col.uniqueName]}
|
||||||
options={col.options}
|
options={col.options}
|
||||||
canSelectMultipleOptions={col.canSelectMultipleOptions}
|
canSelectMultipleOptions={col.canSelectMultipleOptions}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
import { changeSetContainsChanges, createChangeSet } from 'dbgate-datalib';
|
import { changeSetContainsChanges, createChangeSet } from 'dbgate-datalib';
|
||||||
import localforage from 'localforage';
|
import localforage from 'localforage';
|
||||||
import { onMount, tick } from 'svelte';
|
import { onMount, tick } from 'svelte';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte';
|
import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte';
|
||||||
import ToolStripCommandSplitButton from '../buttons/ToolStripCommandSplitButton.svelte';
|
import ToolStripCommandSplitButton from '../buttons/ToolStripCommandSplitButton.svelte';
|
||||||
@ -129,7 +130,13 @@
|
|||||||
await apiCall('archive/modify-file', {
|
await apiCall('archive/modify-file', {
|
||||||
folder: archiveFolder,
|
folder: archiveFolder,
|
||||||
file: archiveFile,
|
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();
|
await afterSaveChangeSet();
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
...changeSet,
|
...changeSet,
|
||||||
updates: changeSet.updates.map(update => ({
|
updates: changeSet.updates.map(update => ({
|
||||||
...update,
|
...update,
|
||||||
fields: _.mapValues(update.fields, (v, k) => (v === undefined ? { $undefined: true } : v)),
|
fields: _.mapValues(update.fields, (v, k) => (v === undefined ? { $$undefined$$: true } : v)),
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -330,10 +330,10 @@ const driver = {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const resdoc = await collection.updateOne(convertObjectId(update.condition), {
|
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(
|
$unset: _.fromPairs(
|
||||||
Object.keys(update.fields)
|
Object.keys(update.fields)
|
||||||
.filter((k) => update.fields[k]?.$undefined)
|
.filter((k) => update.fields[k]?.$$undefined$$)
|
||||||
.map((k) => [k, ''])
|
.map((k) => [k, ''])
|
||||||
),
|
),
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user