mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-25 13:16:00 +00:00
multiline json editing
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
export let type = 'button';
|
export let type = 'button';
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
export let value;
|
export let value;
|
||||||
|
export let title = null;
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
if (!disabled) dispatch('click');
|
if (!disabled) dispatch('click');
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</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>
|
<style>
|
||||||
input {
|
input {
|
||||||
|
|||||||
@@ -335,7 +335,7 @@
|
|||||||
import { isCtrlOrCommandKey, isMac } from '../utility/common';
|
import { isCtrlOrCommandKey, isMac } from '../utility/common';
|
||||||
import { selectionCouldBeShownOnMap } from '../elements/MapView.svelte';
|
import { selectionCouldBeShownOnMap } from '../elements/MapView.svelte';
|
||||||
import ErrorMessageModal from '../modals/ErrorMessageModal.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 onLoadNextData = undefined;
|
||||||
export let grider = undefined;
|
export let grider = undefined;
|
||||||
@@ -1105,7 +1105,7 @@
|
|||||||
const rowData = grider.getRowData(cell[0]);
|
const rowData = grider.getRowData(cell[0]);
|
||||||
if (!rowData) return null;
|
if (!rowData) return null;
|
||||||
const cellData = rowData[realColumnUniqueNames[cell[1]]];
|
const cellData = rowData[realColumnUniqueNames[cell[1]]];
|
||||||
if (_.isString(cellData) && cellData.includes('\n')) {
|
if (shouldOpenMultilineDialog(cellData)) {
|
||||||
showModal(EditCellDataModal, {
|
showModal(EditCellDataModal, {
|
||||||
value: cellData,
|
value: cellData,
|
||||||
onSave: value => grider.setCellValue(cell[0], realColumnUniqueNames[cell[1]], value),
|
onSave: value => grider.setCellValue(cell[0], realColumnUniqueNames[cell[1]], value),
|
||||||
|
|||||||
@@ -173,7 +173,7 @@
|
|||||||
import { plusExpandIcon } from '../icons/expandIcons';
|
import { plusExpandIcon } from '../icons/expandIcons';
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
import DictionaryLookupModal from '../modals/DictionaryLookupModal.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 { showModal } from '../modals/modalTools';
|
||||||
import { apiCall } from '../utility/api';
|
import { apiCall } from '../utility/api';
|
||||||
|
|
||||||
@@ -445,7 +445,7 @@
|
|||||||
if (!cell) return false;
|
if (!cell) return false;
|
||||||
const column = getCellColumn(cell);
|
const column = getCellColumn(cell);
|
||||||
const cellData = rowData[column.uniqueName];
|
const cellData = rowData[column.uniqueName];
|
||||||
if (_.isString(cellData) && cellData.includes('\n')) {
|
if (shouldOpenMultilineDialog(cellData)) {
|
||||||
showModal(EditCellDataModal, {
|
showModal(EditCellDataModal, {
|
||||||
value: cellData,
|
value: cellData,
|
||||||
onSave: value => former.setCellValue(column.uniqueName, value),
|
onSave: value => former.setCellValue(column.uniqueName, value),
|
||||||
|
|||||||
@@ -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">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
@@ -5,19 +20,26 @@
|
|||||||
import FormProvider from '../forms/FormProvider.svelte';
|
import FormProvider from '../forms/FormProvider.svelte';
|
||||||
import AceEditor from '../query/AceEditor.svelte';
|
import AceEditor from '../query/AceEditor.svelte';
|
||||||
import keycodes from '../utility/keycodes';
|
import keycodes from '../utility/keycodes';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
import ModalBase from './ModalBase.svelte';
|
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 onSave;
|
||||||
export let value;
|
export let value;
|
||||||
|
|
||||||
let editor;
|
let editor;
|
||||||
|
let syntaxMode = 'text';
|
||||||
|
|
||||||
let textValue = value?.toString() || '';
|
let textValue = value?.toString() || '';
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
editor.getEditor().focus();
|
editor.getEditor().focus();
|
||||||
|
if (safeJsonParse(textValue)) syntaxMode = 'json';
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleKeyDown(ev) {
|
function handleKeyDown(ev) {
|
||||||
@@ -26,6 +48,15 @@
|
|||||||
closeCurrentModal();
|
closeCurrentModal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleFormatJson() {
|
||||||
|
const parsed = safeJsonParse(textValue);
|
||||||
|
if (parsed) {
|
||||||
|
textValue = JSON.stringify(parsed, null, 2);
|
||||||
|
} else {
|
||||||
|
showModal(ErrorMessageModal, { message: 'Not valid JSON' });
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FormProvider>
|
<FormProvider>
|
||||||
@@ -33,12 +64,14 @@
|
|||||||
<div slot="header">Edit cell value</div>
|
<div slot="header">Edit cell value</div>
|
||||||
|
|
||||||
<div class="editor">
|
<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>
|
||||||
|
|
||||||
<div slot="footer">
|
<div slot="footer" class="footer">
|
||||||
|
<div>
|
||||||
<FormStyledButton
|
<FormStyledButton
|
||||||
value="OK"
|
value="OK"
|
||||||
|
title="Ctrl+Enter"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
onSave(textValue);
|
onSave(textValue);
|
||||||
closeCurrentModal();
|
closeCurrentModal();
|
||||||
@@ -46,6 +79,22 @@
|
|||||||
/>
|
/>
|
||||||
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
|
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
|
||||||
</div>
|
</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>
|
</ModalBase>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
|
|
||||||
@@ -55,4 +104,9 @@
|
|||||||
height: 30vh;
|
height: 30vh;
|
||||||
width: 40vw;
|
width: 40vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user