edit json document

This commit is contained in:
Jan Prochazka
2021-04-05 20:08:23 +02:00
parent e4e01c6e1e
commit d43304792a
11 changed files with 137 additions and 16 deletions

View File

@@ -78,7 +78,6 @@ export function setChangeSetValue(
definition: ChangeSetFieldDefinition, definition: ChangeSetFieldDefinition,
value: string value: string
): ChangeSet { ): ChangeSet {
console.log('SET', changeSet, definition, value);
if (!changeSet || !definition) return changeSet; if (!changeSet || !definition) return changeSet;
let [fieldName, existingItem] = findExistingChangeSetItem(changeSet, definition); let [fieldName, existingItem] = findExistingChangeSetItem(changeSet, definition);
if (fieldName == 'deletes') { if (fieldName == 'deletes') {
@@ -119,6 +118,43 @@ export function setChangeSetValue(
}; };
} }
export function setChangeSetRowData(changeSet: ChangeSet, definition: ChangeSetRowDefinition, document: any): ChangeSet {
if (!changeSet || !definition) return changeSet;
let [fieldName, existingItem] = findExistingChangeSetItem(changeSet, definition);
if (fieldName == 'deletes') {
changeSet = revertChangeSetRowChanges(changeSet, definition);
[fieldName, existingItem] = findExistingChangeSetItem(changeSet, definition);
}
if (existingItem) {
return {
...changeSet,
[fieldName]: changeSet[fieldName].map(item =>
item == existingItem
? {
...item,
fields: {},
document,
}
: item
),
};
}
return {
...changeSet,
[fieldName]: [
...changeSet[fieldName],
{
pureName: definition.pureName,
schemaName: definition.schemaName,
condition: definition.condition,
insertedRowIndex: definition.insertedRowIndex,
document,
},
],
};
}
// export function batchUpdateChangeSet( // export function batchUpdateChangeSet(
// changeSet: ChangeSet, // changeSet: ChangeSet,
// rowDefinitions: ChangeSetRowDefinition[], // rowDefinitions: ChangeSetRowDefinition[],

View File

@@ -11,11 +11,23 @@ import {
MacroSelectedCell, MacroSelectedCell,
revertChangeSetRowChanges, revertChangeSetRowChanges,
setChangeSetValue, setChangeSetValue,
setChangeSetRowData,
compileMacroFunction, compileMacroFunction,
runMacroOnValue, runMacroOnValue,
} from 'dbgate-datalib'; } from 'dbgate-datalib';
import Grider, { GriderRowStatus } from './Grider'; import Grider, { GriderRowStatus } from './Grider';
function getRowFromItem(row, matchedChangeSetItem) {
return matchedChangeSetItem.document
? {
...matchedChangeSetItem.document,
...matchedChangeSetItem.fields,
}
: {
...row,
...matchedChangeSetItem.fields,
};
}
export default class ChangeSetGrider extends Grider { export default class ChangeSetGrider extends Grider {
public insertedRows: any[]; public insertedRows: any[];
public changeSet: ChangeSet; public changeSet: ChangeSet;
@@ -71,7 +83,7 @@ export default class ChangeSetGrider extends Grider {
const rowDefinition = this.display?.getChangeSetRow(row, insertedRowIndex); const rowDefinition = this.display?.getChangeSetRow(row, insertedRowIndex);
const [matchedField, matchedChangeSetItem] = findExistingChangeSetItem(this.changeSet, rowDefinition); const [matchedField, matchedChangeSetItem] = findExistingChangeSetItem(this.changeSet, rowDefinition);
const rowUpdated = matchedChangeSetItem const rowUpdated = matchedChangeSetItem
? { ...row, ...matchedChangeSetItem.fields } ? getRowFromItem(row, matchedChangeSetItem)
: this.compiledMacroFunc : this.compiledMacroFunc
? { ...row } ? { ...row }
: row; : row;
@@ -143,6 +155,12 @@ export default class ChangeSetGrider extends Grider {
this.applyModification(chs => setChangeSetValue(chs, definition, value)); this.applyModification(chs => setChangeSetValue(chs, definition, value));
} }
setRowData(index: number, document: any) {
const row = this.getRowSource(index);
const definition = this.display.getChangeSetRow(row, this.getInsertedRowIndex(index));
this.applyModification(chs => setChangeSetRowData(chs, definition, document));
}
deleteRow(index: number) { deleteRow(index: number) {
this.requireRowCache(index); this.requireRowCache(index);
this.applyModification(chs => deleteChangeSetRows(chs, this.rowDefinitionsCache[index])); this.applyModification(chs => deleteChangeSetRows(chs, this.rowDefinitionsCache[index]));

View File

@@ -140,6 +140,14 @@
onClick: () => getCurrentDataGrid().switchToJson(), onClick: () => getCurrentDataGrid().switchToJson(),
}); });
registerCommand({
id: 'dataGrid.editJsonDocument',
category: 'Data grid',
name: 'Edit row as JSON document',
testEnabled: () => getCurrentDataGrid()?.editJsonEnabled(),
onClick: () => getCurrentDataGrid().editJsonDocument(),
});
registerCommand({ registerCommand({
id: 'dataGrid.filterSelected', id: 'dataGrid.filterSelected',
category: 'Data grid', category: 'Data grid',
@@ -256,6 +264,7 @@
import ErrorInfo from '../elements/ErrorInfo.svelte'; import ErrorInfo from '../elements/ErrorInfo.svelte';
import { dataGridRowHeight } from './DataGridRowHeightMeter.svelte'; import { dataGridRowHeight } from './DataGridRowHeightMeter.svelte';
import FormStyledButton from '../elements/FormStyledButton.svelte'; import FormStyledButton from '../elements/FormStyledButton.svelte';
import { editJsonRowDocument } from '../jsonview/CollectionJsonRow.svelte';
export let onLoadNextData = undefined; export let onLoadNextData = undefined;
export let grider = undefined; export let grider = undefined;
@@ -502,6 +511,15 @@
); );
} }
export function editJsonEnabled() {
return grider.editable && isDynamicStructure && _.uniq(selectedCells.map(x => x[0])).length == 1;
}
export function editJsonDocument() {
const rowIndex = selectedCells[0][0];
editJsonRowDocument(grider, rowIndex);
}
// export function getGeneralAllowSave() { // export function getGeneralAllowSave() {
// return generalAllowSave; // return generalAllowSave;
// } // }
@@ -1029,6 +1047,7 @@
{ command: 'dataGrid.export' }, { command: 'dataGrid.export' },
{ command: 'dataGrid.switchToForm' }, { command: 'dataGrid.switchToForm' },
{ command: 'dataGrid.switchToJson' }, { command: 'dataGrid.switchToJson' },
{ command: 'dataGrid.editJsonDocument' },
{ divider: true }, { divider: true },
{ command: 'dataGrid.save' }, { command: 'dataGrid.save' },
{ command: 'dataGrid.revertRowChanges' }, { command: 'dataGrid.revertRowChanges' },

View File

@@ -24,6 +24,6 @@
</script> </script>
<div class="flex"> <div class="flex">
<TextField {...$$restProps} value={$values[name]} onClick={handleBrowse} readOnly {disabled} /> <TextField {...$$restProps} value={$values[name]} on:click={handleBrowse} readOnly {disabled} />
<InlineButton on:click={handleBrowse} {disabled}>Browse</InlineButton> <InlineButton on:click={handleBrowse} {disabled}>Browse</InlineButton>
</div> </div>

View File

@@ -1,5 +1,25 @@
<script lang="ts" context="module">
export function editJsonRowDocument(grider, rowIndex) {
const rowData = grider.getRowData(rowIndex);
showModal(EditJsonModal, {
json: rowData,
onSave: value => {
if (value._id != rowData._id) {
showModal(ErrorMessageModal, { message: '_id attribute cannot be changed' });
return false;
}
grider.setRowData(rowIndex, value);
return true;
},
});
}
</script>
<script lang="ts"> <script lang="ts">
import JSONTree from '../jsontree/JSONTree.svelte'; import JSONTree from '../jsontree/JSONTree.svelte';
import EditJsonModal from '../modals/EditJsonModal.svelte';
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
import { showModal } from '../modals/modalTools';
export let rowIndex; export let rowIndex;
export let grider; export let grider;
@@ -7,12 +27,25 @@
$: rowData = grider.getRowData(rowIndex); $: rowData = grider.getRowData(rowIndex);
$: rowStatus = grider.getRowStatus(rowIndex); $: rowStatus = grider.getRowStatus(rowIndex);
function handleEditDocument() {
editJsonRowDocument(grider, rowIndex);
}
function createMenu() {
return [
...commonMenu,
{ text: 'Edit document', onClick: handleEditDocument },
{ text: 'Delete document', onClick: () => grider.deleteRow(rowIndex) },
{ text: 'Revert row changes', onClick: () => grider.revertRowChanges(rowIndex) },
];
}
</script> </script>
<JSONTree <JSONTree
value={rowData} value={rowData}
labelOverride="({rowIndex + 1}) " labelOverride="({rowIndex + 1}) "
menu={commonMenu} menu={createMenu}
isModified={rowStatus.status == 'updated'} isModified={rowStatus.status == 'updated'}
isInserted={rowStatus.status == 'inserted'} isInserted={rowStatus.status == 'inserted'}
isDeleted={rowStatus.status == 'deleted'} isDeleted={rowStatus.status == 'deleted'}

View File

@@ -94,7 +94,7 @@
</div> </div>
<div class="json"> <div class="json">
{#each _.range(0, grider.rowCount) as rowIndex} {#each _.range(0, grider.rowCount) as rowIndex}
<CollectionJsonRow {grider} {rowIndex} /> <CollectionJsonRow {grider} {rowIndex} {commonMenu} />
{/each} {/each}
</div> </div>
</div> </div>

View File

@@ -27,7 +27,7 @@
onConfirm(); onConfirm();
}} }}
/> />
<FormStyledButton type="button" value="Close" onClick={closeCurrentModal} /> <FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
</div> </div>
</ModalBase> </ModalBase>
</FormProvider> </FormProvider>

View File

@@ -28,7 +28,7 @@
onConfirm(); onConfirm();
}} }}
/> />
<FormStyledButton type="button" value="Close" onClick={closeCurrentModal} /> <FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
</div> </div>
</ModalBase> </ModalBase>
</FormProvider> </FormProvider>

View File

@@ -1,14 +1,23 @@
<script> <script>
import { onMount } from 'svelte';
import FormStyledButton from '../elements/FormStyledButton.svelte'; import FormStyledButton from '../elements/FormStyledButton.svelte';
import FormProvider from '../forms/FormProvider.svelte'; import FormProvider from '../forms/FormProvider.svelte';
import FormSubmit from '../forms/FormSubmit.svelte'; import FormSubmit from '../forms/FormSubmit.svelte';
import AceEditor from '../query/AceEditor.svelte'; import AceEditor from '../query/AceEditor.svelte';
import ErrorMessageModal from './ErrorMessageModal.svelte';
import ModalBase from './ModalBase.svelte'; import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools'; import { closeCurrentModal, showModal } from './modalTools';
export let onSave; export let onSave;
export let value; export let json;
let value;
onMount(() => {
value = JSON.stringify(json, undefined, 2);
});
</script> </script>
<FormProvider> <FormProvider>
@@ -23,12 +32,18 @@
<FormSubmit <FormSubmit
value="Save" value="Save"
on:click={() => { on:click={() => {
if (onSave(value)) { try {
const parsed = JSON.parse(value);
if (onSave(parsed)) {
closeCurrentModal(); closeCurrentModal();
} }
} catch (err) {
showModal(ErrorMessageModal, { message: err.message });
return;
}
}} }}
/> />
<FormStyledButton type="button" value="Close" onClick={closeCurrentModal} /> <FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
</div> </div>
</ModalBase> </ModalBase>
</FormProvider> </FormProvider>

View File

@@ -23,7 +23,7 @@
</div> </div>
<div slot="footer"> <div slot="footer">
<FormStyledButton type="button" value="Close" onClick={closeCurrentModal} /> <FormSubmit value="Close" on:click={closeCurrentModal} />
</div> </div>
</ModalBase> </ModalBase>
</FormProvider> </FormProvider>

View File

@@ -169,12 +169,12 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormStyledButton <FormStyledButton
value="OK" value="OK"
onClick={() => { on:click={() => {
closeCurrentModal(); closeCurrentModal();
onInsert(sqlPreview); onInsert(sqlPreview);
}} }}
/> />
<FormStyledButton type="button" value="Close" onClick={closeCurrentModal} /> <FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>