multiline json editing

This commit is contained in:
Jan Prochazka
2022-09-25 09:29:38 +02:00
parent 7fc8b2901b
commit 3fe7d652b2
4 changed files with 71 additions and 16 deletions

View File

@@ -6,6 +6,7 @@
export let type = 'button';
export let disabled = false;
export let value;
export let title = null;
function handleClick() {
if (!disabled) dispatch('click');
@@ -18,7 +19,7 @@
}
</script>
<input {type} {value} class:disabled {...$$restProps} on:click={handleClick} bind:this={domButton} />
<input {type} {value} {title} class:disabled {...$$restProps} on:click={handleClick} bind:this={domButton} />
<style>
input {

View File

@@ -335,7 +335,7 @@
import { isCtrlOrCommandKey, isMac } from '../utility/common';
import { selectionCouldBeShownOnMap } from '../elements/MapView.svelte';
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
import EditCellDataModal from '../modals/EditCellDataModal.svelte';
import EditCellDataModal, { shouldOpenMultilineDialog } from '../modals/EditCellDataModal.svelte';
export let onLoadNextData = undefined;
export let grider = undefined;
@@ -1105,7 +1105,7 @@
const rowData = grider.getRowData(cell[0]);
if (!rowData) return null;
const cellData = rowData[realColumnUniqueNames[cell[1]]];
if (_.isString(cellData) && cellData.includes('\n')) {
if (shouldOpenMultilineDialog(cellData)) {
showModal(EditCellDataModal, {
value: cellData,
onSave: value => grider.setCellValue(cell[0], realColumnUniqueNames[cell[1]], value),

View File

@@ -173,7 +173,7 @@
import { plusExpandIcon } from '../icons/expandIcons';
import FontIcon from '../icons/FontIcon.svelte';
import DictionaryLookupModal from '../modals/DictionaryLookupModal.svelte';
import EditCellDataModal from '../modals/EditCellDataModal.svelte';
import EditCellDataModal, { shouldOpenMultilineDialog } from '../modals/EditCellDataModal.svelte';
import { showModal } from '../modals/modalTools';
import { apiCall } from '../utility/api';
@@ -445,7 +445,7 @@
if (!cell) return false;
const column = getCellColumn(cell);
const cellData = rowData[column.uniqueName];
if (_.isString(cellData) && cellData.includes('\n')) {
if (shouldOpenMultilineDialog(cellData)) {
showModal(EditCellDataModal, {
value: cellData,
onSave: value => former.setCellValue(column.uniqueName, value),

View File

@@ -1,3 +1,18 @@
<script lang="ts" context="module">
export function shouldOpenMultilineDialog(value) {
if (_.isString(value)) {
if (value.includes('\n')) {
return true;
}
const parsed = safeJsonParse(value);
if (parsed && (_.isPlainObject(parsed) || _.isArray(parsed))) {
return true;
}
}
return false;
}
</script>
<script lang="ts">
import { onMount } from 'svelte';
@@ -5,19 +20,26 @@
import FormProvider from '../forms/FormProvider.svelte';
import AceEditor from '../query/AceEditor.svelte';
import keycodes from '../utility/keycodes';
import _ from 'lodash';
import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools';
import { closeCurrentModal, showModal } from './modalTools';
import SelectField from '../forms/SelectField.svelte';
import { safeJsonParse } from 'dbgate-tools';
import { showSnackbarError } from '../utility/snackbar';
import ErrorMessageModal from './ErrorMessageModal.svelte';
export let onSave;
export let value;
let editor;
let syntaxMode = 'text';
let textValue = value?.toString() || '';
onMount(() => {
editor.getEditor().focus();
if (safeJsonParse(textValue)) syntaxMode = 'json';
});
function handleKeyDown(ev) {
@@ -26,6 +48,15 @@
closeCurrentModal();
}
}
function handleFormatJson() {
const parsed = safeJsonParse(textValue);
if (parsed) {
textValue = JSON.stringify(parsed, null, 2);
} else {
showModal(ErrorMessageModal, { message: 'Not valid JSON' });
}
}
</script>
<FormProvider>
@@ -33,12 +64,14 @@
<div slot="header">Edit cell value</div>
<div class="editor">
<AceEditor bind:value={textValue} bind:this={editor} onKeyDown={handleKeyDown} />
<AceEditor bind:value={textValue} bind:this={editor} onKeyDown={handleKeyDown} mode={syntaxMode} />
</div>
<div slot="footer">
<div slot="footer" class="footer">
<div>
<FormStyledButton
value="OK"
title="Ctrl+Enter"
on:click={() => {
onSave(textValue);
closeCurrentModal();
@@ -46,6 +79,22 @@
/>
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
</div>
<div>
<FormStyledButton type="button" value="Format JSON" on:click={handleFormatJson} />
Code highlighting:
<SelectField
isNative
value={syntaxMode}
on:change={e => (syntaxMode = e.detail)}
options={[
{ value: 'text', label: 'None (raw text)' },
{ value: 'json', label: 'JSON' },
]}
/>
</div>
</div>
</ModalBase>
</FormProvider>
@@ -55,4 +104,9 @@
height: 30vh;
width: 40vw;
}
.footer {
display: flex;
justify-content: space-between;
}
</style>