mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-25 17:46:00 +00:00
handle JSON in text cells
This commit is contained in:
@@ -44,3 +44,18 @@ export function stringifyCellValue(value) {
|
|||||||
if (_isPlainObject(value) || _isArray(value)) return JSON.stringify(value);
|
if (_isPlainObject(value) || _isArray(value)) return JSON.stringify(value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function safeJsonParse(json, defaultValue?, logError = false) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(json);
|
||||||
|
} catch (err) {
|
||||||
|
if (logError) {
|
||||||
|
console.error(`Error parsing JSON value "${json}"`, err);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isJsonLikeLongString(value) {
|
||||||
|
return _isString(value) && value.length > 100 && value.match(/^\s*\{.*\}\s*$|^\s*\[.*\]\s*$/);
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import ShowFormButton from '../formview/ShowFormButton.svelte';
|
import ShowFormButton from '../formview/ShowFormButton.svelte';
|
||||||
import { getBoolSettingsValue } from '../settings/settingsTools';
|
import { getBoolSettingsValue } from '../settings/settingsTools';
|
||||||
import { arrayToHexString } from 'dbgate-tools';
|
import { arrayToHexString, isJsonLikeLongString, safeJsonParse } from 'dbgate-tools';
|
||||||
import { showModal } from '../modals/modalTools';
|
import { showModal } from '../modals/modalTools';
|
||||||
import DictionaryLookupModal from '../modals/DictionaryLookupModal.svelte';
|
import DictionaryLookupModal from '../modals/DictionaryLookupModal.svelte';
|
||||||
import { openJsonDocument } from '../tabs/JsonTab.svelte';
|
import { openJsonDocument } from '../tabs/JsonTab.svelte';
|
||||||
@@ -84,6 +84,7 @@
|
|||||||
$: style = computeStyle(maxWidth, col);
|
$: style = computeStyle(maxWidth, col);
|
||||||
|
|
||||||
$: isJson = _.isPlainObject(value) && !(value?.type == 'Buffer' && _.isArray(value.data)) && !value.$oid;
|
$: isJson = _.isPlainObject(value) && !(value?.type == 'Buffer' && _.isArray(value.data)) && !value.$oid;
|
||||||
|
$: jsonParsedValue = isJsonLikeLongString(value) ? safeJsonParse(value) : null;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<td
|
<td
|
||||||
@@ -114,7 +115,7 @@
|
|||||||
<span class="value">false</span>
|
<span class="value">false</span>
|
||||||
{:else if _.isNumber(value)}
|
{:else if _.isNumber(value)}
|
||||||
<span class="value">{formatNumber(value)}</span>
|
<span class="value">{formatNumber(value)}</span>
|
||||||
{:else if _.isString(value)}
|
{:else if _.isString(value) && !jsonParsedValue}
|
||||||
{#if dateTimeRegex.test(value)}
|
{#if dateTimeRegex.test(value)}
|
||||||
<span class="value">
|
<span class="value">
|
||||||
{formatDateTime(value)}
|
{formatDateTime(value)}
|
||||||
@@ -134,6 +135,10 @@
|
|||||||
<span class="null" title={JSON.stringify(value, undefined, 2)}>(JSON)</span>
|
<span class="null" title={JSON.stringify(value, undefined, 2)}>(JSON)</span>
|
||||||
{:else if _.isArray(value)}
|
{:else if _.isArray(value)}
|
||||||
<span class="null">[{value.length} items]</span>
|
<span class="null">[{value.length} items]</span>
|
||||||
|
{:else if _.isPlainObject(jsonParsedValue)}
|
||||||
|
<span class="null" title={JSON.stringify(jsonParsedValue, undefined, 2)}>(JSON)</span>
|
||||||
|
{:else if _.isArray(jsonParsedValue)}
|
||||||
|
<span class="null">[{jsonParsedValue.length} items]</span>
|
||||||
{:else}
|
{:else}
|
||||||
{value.toString()}
|
{value.toString()}
|
||||||
{/if}
|
{/if}
|
||||||
@@ -156,7 +161,11 @@
|
|||||||
<ShowFormButton icon="icon open-in-new" on:click={() => openJsonDocument(value, undefined, true)} />
|
<ShowFormButton icon="icon open-in-new" on:click={() => openJsonDocument(value, undefined, true)} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if _.isArray(value)}
|
{#if jsonParsedValue && _.isPlainObject(jsonParsedValue)}
|
||||||
|
<ShowFormButton icon="icon open-in-new" on:click={() => openJsonDocument(jsonParsedValue, undefined, true)} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if _.isArray(jsonParsedValue || value)}
|
||||||
<ShowFormButton
|
<ShowFormButton
|
||||||
icon="icon open-in-new"
|
icon="icon open-in-new"
|
||||||
on:click={() =>
|
on:click={() =>
|
||||||
@@ -169,7 +178,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
editor: {
|
editor: {
|
||||||
rows: value,
|
rows: jsonParsedValue || value,
|
||||||
structure: { __isDynamicStructure: true, columns: [] },
|
structure: { __isDynamicStructure: true, columns: [] },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { SeriesSizes } from './SeriesSizes';
|
|||||||
import { CellAddress } from './selection';
|
import { CellAddress } from './selection';
|
||||||
import { GridDisplay } from 'dbgate-datalib';
|
import { GridDisplay } from 'dbgate-datalib';
|
||||||
import Grider from './Grider';
|
import Grider from './Grider';
|
||||||
|
import { isJsonLikeLongString, safeJsonParse } from 'dbgate-tools';
|
||||||
|
|
||||||
export function countColumnSizes(grider: Grider, columns, containerWidth, display: GridDisplay) {
|
export function countColumnSizes(grider: Grider, columns, containerWidth, display: GridDisplay) {
|
||||||
const columnSizes = new SeriesSizes();
|
const columnSizes = new SeriesSizes();
|
||||||
@@ -68,6 +69,7 @@ export function countColumnSizes(grider: Grider, columns, containerWidth, displa
|
|||||||
let text = value;
|
let text = value;
|
||||||
if (_.isArray(value)) text = `[${value.length} items]`;
|
if (_.isArray(value)) text = `[${value.length} items]`;
|
||||||
else if (value?.$oid) text = `ObjectId("${value.$oid}")`;
|
else if (value?.$oid) text = `ObjectId("${value.$oid}")`;
|
||||||
|
else if (isJsonLikeLongString(value) && safeJsonParse(value)) text = '(JSON)';
|
||||||
const width = context.measureText(text).width + 8;
|
const width = context.measureText(text).width + 8;
|
||||||
// console.log('colName', colName, text, width);
|
// console.log('colName', colName, text, width);
|
||||||
columnSizes.putSizeOverride(colIndex, width);
|
columnSizes.putSizeOverride(colIndex, width);
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import { writable, derived, readable } from 'svelte/store';
|
|||||||
import { ExtensionsDirectory } from 'dbgate-types';
|
import { ExtensionsDirectory } from 'dbgate-types';
|
||||||
import invalidateCommands from './commands/invalidateCommands';
|
import invalidateCommands from './commands/invalidateCommands';
|
||||||
import getElectron from './utility/getElectron';
|
import getElectron from './utility/getElectron';
|
||||||
import { GlobalCommand } from './commands/registerCommand';
|
|
||||||
import { useConfig, useSettings } from './utility/metadataLoaders';
|
import { useConfig, useSettings } from './utility/metadataLoaders';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { safeJsonParse } from 'dbgate-tools';
|
||||||
|
|
||||||
export interface TabDefinition {
|
export interface TabDefinition {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -18,18 +18,9 @@ export interface TabDefinition {
|
|||||||
tabOrder?: number;
|
tabOrder?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function safeJsonParse(json, defaultValue) {
|
|
||||||
try {
|
|
||||||
return JSON.parse(json);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error parsing JSON value "${json}"`, err);
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function writableWithStorage<T>(defaultValue: T, storageName) {
|
export function writableWithStorage<T>(defaultValue: T, storageName) {
|
||||||
const init = localStorage.getItem(storageName);
|
const init = localStorage.getItem(storageName);
|
||||||
const res = writable<T>(init ? safeJsonParse(init, defaultValue) : defaultValue);
|
const res = writable<T>(init ? safeJsonParse(init, defaultValue, true) : defaultValue);
|
||||||
res.subscribe(value => {
|
res.subscribe(value => {
|
||||||
localStorage.setItem(storageName, JSON.stringify(value));
|
localStorage.setItem(storageName, JSON.stringify(value));
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user