sqlite-hub 0.9.12 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/frontend/js/api.js +7 -0
- package/frontend/js/app.js +75 -11
- package/frontend/js/components/modal.js +98 -1
- package/frontend/js/components/queryEditor.js +1 -8
- package/frontend/js/components/structureGraph.js +29 -1
- package/frontend/js/store.js +299 -39
- package/frontend/js/views/charts.js +2 -2
- package/frontend/js/views/data.js +39 -1
- package/frontend/js/views/editor.js +11 -6
- package/frontend/js/views/structure.js +43 -5
- package/frontend/styles/tailwind.generated.css +1 -1
- package/frontend/styles/views.css +4 -0
- package/package.json +1 -1
- package/server/routes/data.js +14 -0
- package/server/services/sqlite/dataBrowserService.js +124 -44
- package/tests/sql-identifier-safety.test.js +48 -8
package/frontend/js/api.js
CHANGED
|
@@ -385,6 +385,13 @@ export function updateDataTableRow(tableName, payload) {
|
|
|
385
385
|
});
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
+
export function previewDataTableRowUpdate(tableName, payload) {
|
|
389
|
+
return request(`/api/data/${encodeURIComponent(tableName)}/rows/preview-update`, {
|
|
390
|
+
method: "POST",
|
|
391
|
+
body: payload,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
388
395
|
export function deleteDataTableRow(tableName, payload) {
|
|
389
396
|
return request(`/api/data/${encodeURIComponent(tableName)}/rows`, {
|
|
390
397
|
method: "DELETE",
|
package/frontend/js/app.js
CHANGED
|
@@ -49,6 +49,8 @@ import {
|
|
|
49
49
|
openEditConnectionModal,
|
|
50
50
|
openCreateQueryChartModal,
|
|
51
51
|
openEditQueryChartModal,
|
|
52
|
+
openDataRowUpdatePreview,
|
|
53
|
+
openEditorRowUpdatePreview,
|
|
52
54
|
refreshCurrentRoute,
|
|
53
55
|
refreshMediaTaggingPreview,
|
|
54
56
|
removeConnection,
|
|
@@ -66,6 +68,8 @@ import {
|
|
|
66
68
|
selectStructureEntry,
|
|
67
69
|
setTableDesignerSearchQuery,
|
|
68
70
|
setTableDesignerSqlPreviewVisibility,
|
|
71
|
+
setDataTableSearchQuery,
|
|
72
|
+
setStructureTableSearchQuery,
|
|
69
73
|
toggleStructureTablesPanel,
|
|
70
74
|
setDataPage,
|
|
71
75
|
setDataPageSize,
|
|
@@ -75,12 +79,14 @@ import {
|
|
|
75
79
|
setCurrentQuery,
|
|
76
80
|
setChartsHeightPreset,
|
|
77
81
|
setChartsHistoryTab,
|
|
82
|
+
setChartsHistoryPanelVisibility,
|
|
78
83
|
setEditorPanelVisibility,
|
|
79
84
|
setEditorTab,
|
|
80
85
|
submitDeleteChartConfirmation,
|
|
81
86
|
submitCreateMediaTaggingTagTable,
|
|
82
87
|
submitCreateMediaTaggingMappingTable,
|
|
83
88
|
submitDeleteQueryHistoryConfirmation,
|
|
89
|
+
submitRowUpdatePreviewConfirmation,
|
|
84
90
|
setQueryHistoryPanelVisibility,
|
|
85
91
|
sortDataTableByColumn,
|
|
86
92
|
sortEditorResultsByColumn,
|
|
@@ -99,8 +105,6 @@ import {
|
|
|
99
105
|
submitCreateConnection,
|
|
100
106
|
createCurrentMediaTag,
|
|
101
107
|
submitDeleteRowConfirmation,
|
|
102
|
-
submitDataRowUpdate,
|
|
103
|
-
submitEditorRowUpdate,
|
|
104
108
|
submitEditConnection,
|
|
105
109
|
submitImportSql,
|
|
106
110
|
submitOpenConnection,
|
|
@@ -163,10 +167,47 @@ let pendingNewTableDesignerAutofocus = false;
|
|
|
163
167
|
let pendingQueryEditorFocus = false;
|
|
164
168
|
let pendingMediaTaggingTagSearchFocus = false;
|
|
165
169
|
|
|
170
|
+
const APP_TITLE = 'SQLite Hub';
|
|
171
|
+
const ROUTE_TITLE_SEGMENTS = {
|
|
172
|
+
connections: 'Connections',
|
|
173
|
+
overview: 'Overview',
|
|
174
|
+
data: 'Data',
|
|
175
|
+
structure: 'Structure',
|
|
176
|
+
editor: 'SQL Editor',
|
|
177
|
+
editorResults: 'SQL Editor',
|
|
178
|
+
charts: 'Charts',
|
|
179
|
+
tableDesigner: 'Table Designer',
|
|
180
|
+
mediaTaggingSetup: 'Media Tagging',
|
|
181
|
+
mediaTaggingQueue: 'Tagging Queue',
|
|
182
|
+
settings: 'Settings',
|
|
183
|
+
notFound: 'Not Found',
|
|
184
|
+
};
|
|
185
|
+
|
|
166
186
|
function invalidateMainRenderCache() {
|
|
167
187
|
lastRenderedMainMarkup = null;
|
|
168
188
|
}
|
|
169
189
|
|
|
190
|
+
function isSqlEditorRouteName(routeName) {
|
|
191
|
+
return routeName === 'editor' || routeName === 'editorResults';
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function resolveDocumentTitle(state) {
|
|
195
|
+
if (isSqlEditorRouteName(state.route.name) && state.editor.executing) {
|
|
196
|
+
return `${APP_TITLE} | Running`;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const segment = ROUTE_TITLE_SEGMENTS[state.route.name];
|
|
200
|
+
return segment ? `${APP_TITLE} | ${segment}` : APP_TITLE;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function syncDocumentTitle(state) {
|
|
204
|
+
const nextTitle = resolveDocumentTitle(state);
|
|
205
|
+
|
|
206
|
+
if (document.title !== nextTitle) {
|
|
207
|
+
document.title = nextTitle;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
170
211
|
function isMediaTaggingRouteName(routeName) {
|
|
171
212
|
return routeName === 'mediaTaggingSetup' || routeName === 'mediaTaggingQueue';
|
|
172
213
|
}
|
|
@@ -589,7 +630,7 @@ function buildChartsHistorySignature(state) {
|
|
|
589
630
|
return '';
|
|
590
631
|
}
|
|
591
632
|
|
|
592
|
-
const historyVisible = state.
|
|
633
|
+
const historyVisible = state.charts.historyPanelVisible !== false || !state.charts.selectedHistoryId;
|
|
593
634
|
|
|
594
635
|
if (!historyVisible) {
|
|
595
636
|
return 'charts-history:hidden';
|
|
@@ -691,7 +732,7 @@ function patchChartsDetailUi(state) {
|
|
|
691
732
|
return false;
|
|
692
733
|
}
|
|
693
734
|
|
|
694
|
-
const historyVisible = state.
|
|
735
|
+
const historyVisible = state.charts.historyPanelVisible !== false || !state.charts.selectedHistoryId;
|
|
695
736
|
const sidebarNode = chartsView.querySelector('.charts-view__sidebar');
|
|
696
737
|
|
|
697
738
|
if (Boolean(sidebarNode) !== historyVisible) {
|
|
@@ -1033,6 +1074,8 @@ async function handleTableDesignerCsvImport(fileInput) {
|
|
|
1033
1074
|
}
|
|
1034
1075
|
|
|
1035
1076
|
function renderApp(state) {
|
|
1077
|
+
syncDocumentTitle(state);
|
|
1078
|
+
|
|
1036
1079
|
const previousRoutePath = lastRenderedRoutePath;
|
|
1037
1080
|
const previousRouteName = lastRenderedRouteName;
|
|
1038
1081
|
const { main, panel } = resolveView(state);
|
|
@@ -1208,7 +1251,8 @@ const router = createRouter(route => {
|
|
|
1208
1251
|
|
|
1209
1252
|
async function executeEditorQueryAndNavigate() {
|
|
1210
1253
|
const success = await executeCurrentQuery();
|
|
1211
|
-
|
|
1254
|
+
const activeTab = getState().editor.activeTab;
|
|
1255
|
+
router.navigate(success && activeTab === 'results' ? '/editor/results' : '/editor');
|
|
1212
1256
|
}
|
|
1213
1257
|
|
|
1214
1258
|
async function handleAction(actionNode) {
|
|
@@ -1337,9 +1381,15 @@ async function handleAction(actionNode) {
|
|
|
1337
1381
|
}
|
|
1338
1382
|
return;
|
|
1339
1383
|
case 'toggle-query-history-panel':
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1384
|
+
if (getState().route.name === 'charts') {
|
|
1385
|
+
setChartsHistoryPanelVisibility(
|
|
1386
|
+
actionNode.dataset.nextValue ? actionNode.dataset.nextValue === 'true' : undefined,
|
|
1387
|
+
);
|
|
1388
|
+
} else {
|
|
1389
|
+
setQueryHistoryPanelVisibility(
|
|
1390
|
+
actionNode.dataset.nextValue ? actionNode.dataset.nextValue === 'true' : undefined,
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1343
1393
|
return;
|
|
1344
1394
|
case 'toggle-editor-panel':
|
|
1345
1395
|
setEditorPanelVisibility(
|
|
@@ -1357,7 +1407,8 @@ async function handleAction(actionNode) {
|
|
|
1357
1407
|
case 'run-query-history':
|
|
1358
1408
|
if (actionNode.dataset.historyId) {
|
|
1359
1409
|
const success = await runQueryHistoryItem(actionNode.dataset.historyId);
|
|
1360
|
-
|
|
1410
|
+
const activeTab = getState().editor.activeTab;
|
|
1411
|
+
router.navigate(success && activeTab === 'results' ? '/editor/results' : '/editor');
|
|
1361
1412
|
}
|
|
1362
1413
|
return;
|
|
1363
1414
|
case 'toggle-query-history-saved':
|
|
@@ -1727,6 +1778,16 @@ document.addEventListener('input', event => {
|
|
|
1727
1778
|
return;
|
|
1728
1779
|
}
|
|
1729
1780
|
|
|
1781
|
+
if (bindNode.dataset.bind === 'data-table-search') {
|
|
1782
|
+
setDataTableSearchQuery(bindNode.value);
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
if (bindNode.dataset.bind === 'structure-table-search') {
|
|
1787
|
+
setStructureTableSearchQuery(bindNode.value);
|
|
1788
|
+
return;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1730
1791
|
if (bindNode.dataset.bind === 'table-designer-search') {
|
|
1731
1792
|
setTableDesignerSearchQuery(bindNode.value);
|
|
1732
1793
|
return;
|
|
@@ -2007,6 +2068,9 @@ document.addEventListener('submit', async event => {
|
|
|
2007
2068
|
case 'delete-query-history-confirm':
|
|
2008
2069
|
await submitDeleteQueryHistoryConfirmation();
|
|
2009
2070
|
return;
|
|
2071
|
+
case 'apply-row-update-preview':
|
|
2072
|
+
await submitRowUpdatePreviewConfirmation();
|
|
2073
|
+
return;
|
|
2010
2074
|
case 'create-media-tagging-tag-table':
|
|
2011
2075
|
await submitCreateMediaTaggingTagTable();
|
|
2012
2076
|
return;
|
|
@@ -2035,7 +2099,7 @@ document.addEventListener('submit', async event => {
|
|
|
2035
2099
|
}
|
|
2036
2100
|
}
|
|
2037
2101
|
|
|
2038
|
-
await
|
|
2102
|
+
await openDataRowUpdatePreview(String(formData.get('rowIndex') ?? ''), values, rowIdentity);
|
|
2039
2103
|
return;
|
|
2040
2104
|
}
|
|
2041
2105
|
case 'save-editor-row': {
|
|
@@ -2049,7 +2113,7 @@ document.addEventListener('submit', async event => {
|
|
|
2049
2113
|
values[key.slice('field:'.length)] = String(value ?? '');
|
|
2050
2114
|
}
|
|
2051
2115
|
|
|
2052
|
-
await
|
|
2116
|
+
await openEditorRowUpdatePreview(String(formData.get('rowIndex') ?? ''), values);
|
|
2053
2117
|
return;
|
|
2054
2118
|
}
|
|
2055
2119
|
case 'save-query-history-title': {
|
|
@@ -425,6 +425,98 @@ function renderDeleteRowConfirmForm(modal) {
|
|
|
425
425
|
].join("");
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
+
function renderRowUpdatePreviewForm(modal) {
|
|
429
|
+
const preview = modal.preview ?? {};
|
|
430
|
+
const changes = preview.changes ?? [];
|
|
431
|
+
const params = preview.params ?? [];
|
|
432
|
+
const warnings = preview.warnings ?? [];
|
|
433
|
+
const changesMarkup = changes.length
|
|
434
|
+
? [
|
|
435
|
+
'<div class="overflow-hidden border border-outline-variant/10">',
|
|
436
|
+
'<table class="w-full text-left text-sm">',
|
|
437
|
+
'<thead class="bg-surface-container-highest text-[10px] font-mono uppercase tracking-[0.16em] text-on-surface-variant/55">',
|
|
438
|
+
'<tr><th class="px-3 py-2">Column</th><th class="px-3 py-2">Old</th><th class="px-3 py-2">New</th></tr>',
|
|
439
|
+
'</thead><tbody class="divide-y divide-outline-variant/10">',
|
|
440
|
+
changes
|
|
441
|
+
.map(
|
|
442
|
+
change => `
|
|
443
|
+
<tr>
|
|
444
|
+
<td class="px-3 py-2 font-mono text-xs text-primary-container">${escapeHtml(change.column)}</td>
|
|
445
|
+
<td class="px-3 py-2 text-on-surface-variant/70">${escapeHtml(change.oldValue)}</td>
|
|
446
|
+
<td class="px-3 py-2 text-on-surface">${escapeHtml(change.newValue)}</td>
|
|
447
|
+
</tr>
|
|
448
|
+
`,
|
|
449
|
+
)
|
|
450
|
+
.join(''),
|
|
451
|
+
'</tbody></table></div>',
|
|
452
|
+
].join('')
|
|
453
|
+
: '<div class="border border-outline-variant/10 bg-surface-container-low px-4 py-3 text-sm text-on-surface-variant/65">No changed values were detected.</div>';
|
|
454
|
+
const paramsMarkup = params.length
|
|
455
|
+
? `
|
|
456
|
+
<div class="space-y-2">
|
|
457
|
+
<div class="text-[10px] font-mono uppercase tracking-[0.18em] text-on-surface-variant/55">Parameters</div>
|
|
458
|
+
<div class="space-y-2">
|
|
459
|
+
${params
|
|
460
|
+
.map(
|
|
461
|
+
param => `
|
|
462
|
+
<div class="flex gap-3 border border-outline-variant/10 bg-surface-container-low px-3 py-2 text-xs">
|
|
463
|
+
<span class="font-mono text-primary-container">$${escapeHtml(param.index)}</span>
|
|
464
|
+
<span class="min-w-0 break-words text-on-surface">${escapeHtml(param.value)}</span>
|
|
465
|
+
</div>
|
|
466
|
+
`,
|
|
467
|
+
)
|
|
468
|
+
.join('')}
|
|
469
|
+
</div>
|
|
470
|
+
</div>
|
|
471
|
+
`
|
|
472
|
+
: '';
|
|
473
|
+
const warningsMarkup = warnings.length
|
|
474
|
+
? `
|
|
475
|
+
<div class="space-y-2">
|
|
476
|
+
${warnings
|
|
477
|
+
.map(
|
|
478
|
+
warning => `
|
|
479
|
+
<div class="border border-primary-container/20 bg-primary-container/10 px-4 py-3 text-sm text-on-surface">
|
|
480
|
+
${escapeHtml(warning)}
|
|
481
|
+
</div>
|
|
482
|
+
`,
|
|
483
|
+
)
|
|
484
|
+
.join('')}
|
|
485
|
+
</div>
|
|
486
|
+
`
|
|
487
|
+
: '';
|
|
488
|
+
|
|
489
|
+
return `
|
|
490
|
+
<form class="space-y-5" data-form="apply-row-update-preview">
|
|
491
|
+
<div class="space-y-2">
|
|
492
|
+
<div class="text-[10px] font-mono uppercase tracking-[0.18em] text-on-surface-variant/55">
|
|
493
|
+
${escapeHtml(modal.tableName ?? 'Table Row')}
|
|
494
|
+
</div>
|
|
495
|
+
<p class="text-sm leading-7 text-on-surface-variant/70">
|
|
496
|
+
Review the SQL and changed values before applying this row update.
|
|
497
|
+
</p>
|
|
498
|
+
</div>
|
|
499
|
+
${warningsMarkup}
|
|
500
|
+
<div class="space-y-2">
|
|
501
|
+
<div class="text-[10px] font-mono uppercase tracking-[0.18em] text-on-surface-variant/55">SQL Preview</div>
|
|
502
|
+
${renderSqlPreviewField(preview.sql ?? '', 'sql-highlight-shell--compact')}
|
|
503
|
+
</div>
|
|
504
|
+
<div class="space-y-2">
|
|
505
|
+
<div class="text-[10px] font-mono uppercase tracking-[0.18em] text-on-surface-variant/55">Changed Values</div>
|
|
506
|
+
${changesMarkup}
|
|
507
|
+
</div>
|
|
508
|
+
${paramsMarkup}
|
|
509
|
+
${renderError(modal.error)}
|
|
510
|
+
<div class="flex items-center justify-end gap-3 pt-2">
|
|
511
|
+
<button class="standard-button" data-action="close-modal" type="button">Cancel</button>
|
|
512
|
+
<button class="signature-button" type="submit">
|
|
513
|
+
${modal.submitting ? 'Applying...' : 'Apply Changes'}
|
|
514
|
+
</button>
|
|
515
|
+
</div>
|
|
516
|
+
</form>
|
|
517
|
+
`;
|
|
518
|
+
}
|
|
519
|
+
|
|
428
520
|
function renderChartColumnOptions(analysis, { allowEmpty = false, includeNumericHint = false } = {}) {
|
|
429
521
|
const options = allowEmpty ? [{ value: "", label: "None" }] : [];
|
|
430
522
|
|
|
@@ -869,6 +961,11 @@ export function renderModal(state) {
|
|
|
869
961
|
title: "Delete Row",
|
|
870
962
|
body: renderDeleteRowConfirmForm(modal),
|
|
871
963
|
},
|
|
964
|
+
"row-update-preview": {
|
|
965
|
+
eyebrow: "Mutation // Review row update",
|
|
966
|
+
title: "Review Update",
|
|
967
|
+
body: renderRowUpdatePreviewForm(modal),
|
|
968
|
+
},
|
|
872
969
|
"chart-editor": {
|
|
873
970
|
eyebrow: "Charts // Configure query-based ECharts panel",
|
|
874
971
|
title: modal.draft?.mode === "edit" ? "Edit Chart" : "New Chart",
|
|
@@ -904,7 +1001,7 @@ export function renderModal(state) {
|
|
|
904
1001
|
|
|
905
1002
|
return `
|
|
906
1003
|
<div class="fixed inset-0 z-50 flex items-center justify-center bg-background/85 px-4 backdrop-blur-sm">
|
|
907
|
-
<div class="w-full ${modal.kind === "chart-editor" ? "max-w-3xl" : "max-w-xl"} border border-outline-variant/20 bg-surface-container shadow-[0_24px_80px_rgba(0,0,0,0.45)]">
|
|
1004
|
+
<div class="w-full ${modal.kind === "chart-editor" || modal.kind === "row-update-preview" ? "max-w-3xl" : "max-w-xl"} border border-outline-variant/20 bg-surface-container shadow-[0_24px_80px_rgba(0,0,0,0.45)]">
|
|
908
1005
|
<div class="flex items-start justify-between gap-4 border-b border-outline-variant/10 bg-surface-container-low px-6 py-5">
|
|
909
1006
|
<div>
|
|
910
1007
|
<div class="text-[10px] font-mono uppercase tracking-[0.26em] text-primary-container/70">
|
|
@@ -38,7 +38,6 @@ function renderEditorSurface({ query }) {
|
|
|
38
38
|
|
|
39
39
|
export function renderQueryEditor({
|
|
40
40
|
query,
|
|
41
|
-
title,
|
|
42
41
|
executing = false,
|
|
43
42
|
exporting = false,
|
|
44
43
|
historyLoading = false,
|
|
@@ -48,13 +47,7 @@ export function renderQueryEditor({
|
|
|
48
47
|
}) {
|
|
49
48
|
const secondaryButtonClass = "standard-button";
|
|
50
49
|
const left = `
|
|
51
|
-
<div class="flex items-center gap-2
|
|
52
|
-
<span class="material-symbols-outlined text-xs text-[#FCE300]">database</span>
|
|
53
|
-
<span class="text-[10px] font-mono uppercase tracking-widest text-on-surface-variant">${escapeHtml(
|
|
54
|
-
title
|
|
55
|
-
)}</span>
|
|
56
|
-
</div>
|
|
57
|
-
<div class="hidden items-center gap-2 text-[10px] font-mono uppercase tracking-widest text-on-surface-variant/40 md:flex">
|
|
50
|
+
<div class="flex items-center gap-2 text-[10px] font-mono uppercase tracking-widest text-on-surface-variant/40">
|
|
58
51
|
<span class="material-symbols-outlined text-xs">history</span>
|
|
59
52
|
${historyLoading ? "Loading history..." : `${historyTotal} queries tracked`}
|
|
60
53
|
</div>
|
|
@@ -6,6 +6,33 @@ let cytoscapeFactory = null;
|
|
|
6
6
|
let currentGraph = null;
|
|
7
7
|
let mountVersion = 0;
|
|
8
8
|
let persistedGraphState = null;
|
|
9
|
+
const STRUCTURE_INSPECTOR_VISIBLE_STORAGE_KEY = 'sqlite_hub_structure_inspector_visible';
|
|
10
|
+
|
|
11
|
+
function readStoredInspectorHidden() {
|
|
12
|
+
try {
|
|
13
|
+
const value = globalThis.localStorage?.getItem(STRUCTURE_INSPECTOR_VISIBLE_STORAGE_KEY);
|
|
14
|
+
|
|
15
|
+
if (value === 'true') {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (value === 'false') {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return false;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function storeInspectorHidden(hidden) {
|
|
30
|
+
try {
|
|
31
|
+
globalThis.localStorage?.setItem(STRUCTURE_INSPECTOR_VISIBLE_STORAGE_KEY, String(!hidden));
|
|
32
|
+
} catch {
|
|
33
|
+
// Ignore unavailable browser storage; the in-memory setting still applies.
|
|
34
|
+
}
|
|
35
|
+
}
|
|
9
36
|
|
|
10
37
|
function getTableId(tableName) {
|
|
11
38
|
return `table:${tableName}`;
|
|
@@ -690,6 +717,7 @@ export function setupToolbar(cy) {
|
|
|
690
717
|
break;
|
|
691
718
|
case 'toggle-inspector':
|
|
692
719
|
currentGraph.inspectorHidden = !currentGraph.inspectorHidden;
|
|
720
|
+
storeInspectorHidden(currentGraph.inspectorHidden);
|
|
693
721
|
updateInspectorToggleButton();
|
|
694
722
|
syncInspectorLayout();
|
|
695
723
|
break;
|
|
@@ -765,7 +793,7 @@ export async function mountStructureGraph(snapshot) {
|
|
|
765
793
|
resizeHandler: null,
|
|
766
794
|
openDataButton: null,
|
|
767
795
|
inspectorToggleButton: null,
|
|
768
|
-
inspectorHidden: cachedState?.inspectorHidden ??
|
|
796
|
+
inspectorHidden: cachedState?.inspectorHidden ?? readStoredInspectorHidden(),
|
|
769
797
|
persistStateOnDestroy: true,
|
|
770
798
|
selectedTableName: null,
|
|
771
799
|
};
|