sqlite-hub 0.9.12 → 0.9.13

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.
@@ -75,6 +75,7 @@ import {
75
75
  setCurrentQuery,
76
76
  setChartsHeightPreset,
77
77
  setChartsHistoryTab,
78
+ setChartsHistoryPanelVisibility,
78
79
  setEditorPanelVisibility,
79
80
  setEditorTab,
80
81
  submitDeleteChartConfirmation,
@@ -163,10 +164,47 @@ let pendingNewTableDesignerAutofocus = false;
163
164
  let pendingQueryEditorFocus = false;
164
165
  let pendingMediaTaggingTagSearchFocus = false;
165
166
 
167
+ const APP_TITLE = 'SQLite Hub';
168
+ const ROUTE_TITLE_SEGMENTS = {
169
+ connections: 'Connections',
170
+ overview: 'Overview',
171
+ data: 'Data',
172
+ structure: 'Structure',
173
+ editor: 'SQL Editor',
174
+ editorResults: 'SQL Editor',
175
+ charts: 'Charts',
176
+ tableDesigner: 'Table Designer',
177
+ mediaTaggingSetup: 'Media Tagging',
178
+ mediaTaggingQueue: 'Tagging Queue',
179
+ settings: 'Settings',
180
+ notFound: 'Not Found',
181
+ };
182
+
166
183
  function invalidateMainRenderCache() {
167
184
  lastRenderedMainMarkup = null;
168
185
  }
169
186
 
187
+ function isSqlEditorRouteName(routeName) {
188
+ return routeName === 'editor' || routeName === 'editorResults';
189
+ }
190
+
191
+ function resolveDocumentTitle(state) {
192
+ if (isSqlEditorRouteName(state.route.name) && state.editor.executing) {
193
+ return `${APP_TITLE} | Running`;
194
+ }
195
+
196
+ const segment = ROUTE_TITLE_SEGMENTS[state.route.name];
197
+ return segment ? `${APP_TITLE} | ${segment}` : APP_TITLE;
198
+ }
199
+
200
+ function syncDocumentTitle(state) {
201
+ const nextTitle = resolveDocumentTitle(state);
202
+
203
+ if (document.title !== nextTitle) {
204
+ document.title = nextTitle;
205
+ }
206
+ }
207
+
170
208
  function isMediaTaggingRouteName(routeName) {
171
209
  return routeName === 'mediaTaggingSetup' || routeName === 'mediaTaggingQueue';
172
210
  }
@@ -589,7 +627,7 @@ function buildChartsHistorySignature(state) {
589
627
  return '';
590
628
  }
591
629
 
592
- const historyVisible = state.editor.historyPanelVisible !== false || !state.charts.selectedHistoryId;
630
+ const historyVisible = state.charts.historyPanelVisible !== false || !state.charts.selectedHistoryId;
593
631
 
594
632
  if (!historyVisible) {
595
633
  return 'charts-history:hidden';
@@ -691,7 +729,7 @@ function patchChartsDetailUi(state) {
691
729
  return false;
692
730
  }
693
731
 
694
- const historyVisible = state.editor.historyPanelVisible !== false || !state.charts.selectedHistoryId;
732
+ const historyVisible = state.charts.historyPanelVisible !== false || !state.charts.selectedHistoryId;
695
733
  const sidebarNode = chartsView.querySelector('.charts-view__sidebar');
696
734
 
697
735
  if (Boolean(sidebarNode) !== historyVisible) {
@@ -1033,6 +1071,8 @@ async function handleTableDesignerCsvImport(fileInput) {
1033
1071
  }
1034
1072
 
1035
1073
  function renderApp(state) {
1074
+ syncDocumentTitle(state);
1075
+
1036
1076
  const previousRoutePath = lastRenderedRoutePath;
1037
1077
  const previousRouteName = lastRenderedRouteName;
1038
1078
  const { main, panel } = resolveView(state);
@@ -1208,7 +1248,8 @@ const router = createRouter(route => {
1208
1248
 
1209
1249
  async function executeEditorQueryAndNavigate() {
1210
1250
  const success = await executeCurrentQuery();
1211
- router.navigate(success ? '/editor/results' : '/editor');
1251
+ const activeTab = getState().editor.activeTab;
1252
+ router.navigate(success && activeTab === 'results' ? '/editor/results' : '/editor');
1212
1253
  }
1213
1254
 
1214
1255
  async function handleAction(actionNode) {
@@ -1337,9 +1378,15 @@ async function handleAction(actionNode) {
1337
1378
  }
1338
1379
  return;
1339
1380
  case 'toggle-query-history-panel':
1340
- setQueryHistoryPanelVisibility(
1341
- actionNode.dataset.nextValue ? actionNode.dataset.nextValue === 'true' : undefined,
1342
- );
1381
+ if (getState().route.name === 'charts') {
1382
+ setChartsHistoryPanelVisibility(
1383
+ actionNode.dataset.nextValue ? actionNode.dataset.nextValue === 'true' : undefined,
1384
+ );
1385
+ } else {
1386
+ setQueryHistoryPanelVisibility(
1387
+ actionNode.dataset.nextValue ? actionNode.dataset.nextValue === 'true' : undefined,
1388
+ );
1389
+ }
1343
1390
  return;
1344
1391
  case 'toggle-editor-panel':
1345
1392
  setEditorPanelVisibility(
@@ -1357,7 +1404,8 @@ async function handleAction(actionNode) {
1357
1404
  case 'run-query-history':
1358
1405
  if (actionNode.dataset.historyId) {
1359
1406
  const success = await runQueryHistoryItem(actionNode.dataset.historyId);
1360
- router.navigate(success ? '/editor/results' : '/editor');
1407
+ const activeTab = getState().editor.activeTab;
1408
+ router.navigate(success && activeTab === 'results' ? '/editor/results' : '/editor');
1361
1409
  }
1362
1410
  return;
1363
1411
  case 'toggle-query-history-saved':
@@ -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 ?? false,
796
+ inspectorHidden: cachedState?.inspectorHidden ?? readStoredInspectorHidden(),
769
797
  persistStateOnDestroy: true,
770
798
  selectedTableName: null,
771
799
  };
@@ -34,9 +34,20 @@ const DATA_PAGE_SIZES = [25, 50, 100];
34
34
  const DATA_ROW_SIZE_STORAGE_KEY = 'data_row_size';
35
35
  const CHARTS_HISTORY_TAB_STORAGE_KEY = 'charts_history_tab';
36
36
  const QUERY_HISTORY_TAB_STORAGE_KEY = 'query_history_tab';
37
+ const UI_PREFERENCE_STORAGE_KEYS = {
38
+ sqlEditorHistoryVisible: 'sqlite_hub_sql_editor_history_visible',
39
+ sqlEditorEditorVisible: 'sqlite_hub_sql_editor_editor_visible',
40
+ sqlEditorActiveTab: 'sqlite_hub_sql_editor_active_tab',
41
+ dataTablesVisible: 'sqlite_hub_data_tables_visible',
42
+ structureTablesVisible: 'sqlite_hub_structure_tables_visible',
43
+ chartsHistoryVisible: 'sqlite_hub_charts_history_visible',
44
+ chartsResultsVisible: 'sqlite_hub_charts_results_visible',
45
+ tableDesignerSqlPreviewVisible: 'sqlite_hub_table_designer_sql_preview_visible',
46
+ };
37
47
  const QUERY_HISTORY_PAGE_SIZE = 30;
38
48
  const QUERY_HISTORY_RUN_LIMIT = 8;
39
49
  const CHART_HEIGHT_PRESETS = new Set(['small', 'medium', 'large']);
50
+ const EDITOR_RESULT_TABS = new Set(['results', 'performance', 'messages']);
40
51
  const MISSING_DATABASE_ERROR = {
41
52
  code: 'ACTIVE_DATABASE_REQUIRED',
42
53
  message: 'No active SQLite database selected.',
@@ -66,6 +77,53 @@ function storeDataPageSize(pageSize) {
66
77
  }
67
78
  }
68
79
 
80
+ function readStoredBoolean(key, fallback) {
81
+ try {
82
+ const value = globalThis.localStorage?.getItem(key);
83
+
84
+ if (value === 'true') {
85
+ return true;
86
+ }
87
+
88
+ if (value === 'false') {
89
+ return false;
90
+ }
91
+
92
+ return fallback;
93
+ } catch {
94
+ return fallback;
95
+ }
96
+ }
97
+
98
+ function storeBoolean(key, value) {
99
+ try {
100
+ globalThis.localStorage?.setItem(key, String(Boolean(value)));
101
+ } catch {
102
+ // Ignore unavailable browser storage; the in-memory setting still applies.
103
+ }
104
+ }
105
+
106
+ function readStoredEditorActiveTab(fallback = 'messages') {
107
+ try {
108
+ const value = globalThis.localStorage?.getItem(UI_PREFERENCE_STORAGE_KEYS.sqlEditorActiveTab);
109
+ return EDITOR_RESULT_TABS.has(value) ? value : fallback;
110
+ } catch {
111
+ return fallback;
112
+ }
113
+ }
114
+
115
+ function storeEditorActiveTab(tab) {
116
+ if (!EDITOR_RESULT_TABS.has(tab)) {
117
+ return;
118
+ }
119
+
120
+ try {
121
+ globalThis.localStorage?.setItem(UI_PREFERENCE_STORAGE_KEYS.sqlEditorActiveTab, tab);
122
+ } catch {
123
+ // Ignore unavailable browser storage; the in-memory setting still applies.
124
+ }
125
+ }
126
+
69
127
  function readStoredChartsHistoryTab(fallback = 'recent') {
70
128
  try {
71
129
  return normalizeChartsHistoryTab(globalThis.localStorage?.getItem(CHARTS_HISTORY_TAB_STORAGE_KEY) ?? fallback);
@@ -124,7 +182,7 @@ const state = {
124
182
  dataBrowser: {
125
183
  tables: [],
126
184
  selectedTable: null,
127
- tablesVisible: true,
185
+ tablesVisible: readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.dataTablesVisible, true),
128
186
  table: null,
129
187
  loading: false,
130
188
  tableLoading: false,
@@ -145,9 +203,9 @@ const state = {
145
203
  },
146
204
  editor: {
147
205
  sqlText: '',
148
- editorPanelVisible: true,
206
+ editorPanelVisible: readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.sqlEditorEditorVisible, true),
149
207
  history: [],
150
- historyPanelVisible: true,
208
+ historyPanelVisible: readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.sqlEditorHistoryVisible, true),
151
209
  historyLoading: false,
152
210
  historyLoadingMore: false,
153
211
  historyError: null,
@@ -163,9 +221,10 @@ const state = {
163
221
  historyRuns: [],
164
222
  historyDetailLoading: false,
165
223
  historyDetailError: null,
166
- activeTab: 'messages',
224
+ activeTab: readStoredEditorActiveTab(),
167
225
  executing: false,
168
226
  result: null,
227
+ lastExecutedSql: '',
169
228
  resultSortColumn: null,
170
229
  resultSortDirection: null,
171
230
  error: null,
@@ -181,10 +240,11 @@ const state = {
181
240
  loading: false,
182
241
  error: null,
183
242
  historyTab: readStoredChartsHistoryTab(),
243
+ historyPanelVisible: readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.chartsHistoryVisible, true),
184
244
  selectedHistoryId: null,
185
245
  chartHeightPreset: 'medium',
186
246
  sqlExpanded: false,
187
- resultsVisible: true,
247
+ resultsVisible: readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.chartsResultsVisible, true),
188
248
  detail: null,
189
249
  detailLoading: false,
190
250
  detailError: null,
@@ -196,7 +256,7 @@ const state = {
196
256
  tables: [],
197
257
  selectedTableName: null,
198
258
  draft: null,
199
- sqlPreviewVisible: true,
259
+ sqlPreviewVisible: readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.tableDesignerSqlPreviewVisible, true),
200
260
  pendingImportedDraft: null,
201
261
  loading: false,
202
262
  detailLoading: false,
@@ -210,7 +270,7 @@ const state = {
210
270
  data: null,
211
271
  selectedName: null,
212
272
  detail: null,
213
- tablesVisible: true,
273
+ tablesVisible: readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.structureTablesVisible, true),
214
274
  loading: false,
215
275
  detailLoading: false,
216
276
  error: null,
@@ -735,10 +795,11 @@ function resetChartsState() {
735
795
  state.charts.loading = false;
736
796
  state.charts.error = null;
737
797
  state.charts.historyTab = readStoredChartsHistoryTab(state.charts.historyTab);
798
+ state.charts.historyPanelVisible = readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.chartsHistoryVisible, true);
738
799
  state.charts.selectedHistoryId = null;
739
800
  state.charts.chartHeightPreset = 'medium';
740
801
  state.charts.sqlExpanded = false;
741
- state.charts.resultsVisible = true;
802
+ state.charts.resultsVisible = readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.chartsResultsVisible, true);
742
803
  state.charts.detail = null;
743
804
  state.charts.detailLoading = false;
744
805
  state.charts.detailError = null;
@@ -902,7 +963,7 @@ function setMissingDatabaseState() {
902
963
  state.structure.detailLoading = false;
903
964
  state.structure.data = null;
904
965
  state.structure.detail = null;
905
- state.structure.tablesVisible = true;
966
+ state.structure.tablesVisible = readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.structureTablesVisible, true);
906
967
  state.structure.error = error;
907
968
 
908
969
  state.tableDesigner.loading = false;
@@ -910,7 +971,7 @@ function setMissingDatabaseState() {
910
971
  state.tableDesigner.tables = [];
911
972
  state.tableDesigner.selectedTableName = null;
912
973
  state.tableDesigner.draft = null;
913
- state.tableDesigner.sqlPreviewVisible = true;
974
+ state.tableDesigner.sqlPreviewVisible = readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.tableDesignerSqlPreviewVisible, true);
914
975
  state.tableDesigner.pendingImportedDraft = null;
915
976
  state.tableDesigner.saving = false;
916
977
  state.tableDesigner.searchQuery = '';
@@ -964,9 +1025,8 @@ function syncRouteContext() {
964
1025
 
965
1026
  if (route.name === 'editorResults') {
966
1027
  state.editor.activeTab = 'results';
1028
+ storeEditorActiveTab('results');
967
1029
  clearQueryHistoryDetailState();
968
- } else if (route.name === 'editor' && state.editor.activeTab === 'results') {
969
- state.editor.activeTab = 'messages';
970
1030
  }
971
1031
 
972
1032
  if (route.name !== 'editorResults') {
@@ -1184,7 +1244,7 @@ async function loadChartsDetail(historyId) {
1184
1244
  if (!Number.isInteger(numericId) || numericId < 1) {
1185
1245
  state.charts.selectedHistoryId = null;
1186
1246
  state.charts.sqlExpanded = false;
1187
- state.charts.resultsVisible = true;
1247
+ state.charts.resultsVisible = readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.chartsResultsVisible, true);
1188
1248
  state.charts.detail = null;
1189
1249
  state.charts.detailLoading = false;
1190
1250
  state.charts.detailError = null;
@@ -1197,7 +1257,7 @@ async function loadChartsDetail(historyId) {
1197
1257
 
1198
1258
  state.charts.selectedHistoryId = numericId;
1199
1259
  state.charts.sqlExpanded = false;
1200
- state.charts.resultsVisible = true;
1260
+ state.charts.resultsVisible = readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.chartsResultsVisible, true);
1201
1261
  state.charts.detail = null;
1202
1262
  state.charts.detailLoading = true;
1203
1263
  state.charts.detailError = null;
@@ -1868,7 +1928,7 @@ function invalidateDatabaseCaches() {
1868
1928
  state.tableDesigner.tables = [];
1869
1929
  state.tableDesigner.selectedTableName = null;
1870
1930
  state.tableDesigner.draft = null;
1871
- state.tableDesigner.sqlPreviewVisible = true;
1931
+ state.tableDesigner.sqlPreviewVisible = readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.tableDesignerSqlPreviewVisible, true);
1872
1932
  state.tableDesigner.pendingImportedDraft = null;
1873
1933
  state.tableDesigner.saving = false;
1874
1934
  state.tableDesigner.searchQuery = '';
@@ -1878,7 +1938,7 @@ function invalidateDatabaseCaches() {
1878
1938
  resetChartsState();
1879
1939
  state.structure.data = null;
1880
1940
  state.structure.detail = null;
1881
- state.structure.tablesVisible = true;
1941
+ state.structure.tablesVisible = readStoredBoolean(UI_PREFERENCE_STORAGE_KEYS.structureTablesVisible, true);
1882
1942
  state.mediaTagging.loading = false;
1883
1943
  state.mediaTagging.previewLoading = false;
1884
1944
  state.mediaTagging.saving = false;
@@ -2303,6 +2363,19 @@ export function toggleChartsSqlPanel() {
2303
2363
 
2304
2364
  export function toggleChartsResultsPanel() {
2305
2365
  state.charts.resultsVisible = !state.charts.resultsVisible;
2366
+ storeBoolean(UI_PREFERENCE_STORAGE_KEYS.chartsResultsVisible, state.charts.resultsVisible);
2367
+ emitChange();
2368
+ }
2369
+
2370
+ export function setChartsHistoryPanelVisibility(visible) {
2371
+ const nextValue = typeof visible === 'boolean' ? visible : !Boolean(state.charts.historyPanelVisible);
2372
+
2373
+ if (state.charts.historyPanelVisible === nextValue) {
2374
+ return;
2375
+ }
2376
+
2377
+ state.charts.historyPanelVisible = nextValue;
2378
+ storeBoolean(UI_PREFERENCE_STORAGE_KEYS.chartsHistoryVisible, nextValue);
2306
2379
  emitChange();
2307
2380
  }
2308
2381
 
@@ -2559,6 +2632,7 @@ export function setCurrentQuery(query) {
2559
2632
  export function clearCurrentQuery() {
2560
2633
  state.editor.sqlText = '';
2561
2634
  state.editor.result = null;
2635
+ state.editor.lastExecutedSql = '';
2562
2636
  resetEditorResultSort();
2563
2637
  state.editor.error = null;
2564
2638
  clearQueryHistoryDetailState();
@@ -2566,22 +2640,17 @@ export function clearCurrentQuery() {
2566
2640
  state.editor.saving = false;
2567
2641
  state.editor.deleting = false;
2568
2642
  state.editor.saveError = null;
2569
- if (state.editor.activeTab === 'results' || state.editor.activeTab === 'performance') {
2570
- state.editor.activeTab = 'messages';
2571
- }
2572
2643
  emitChange();
2573
2644
  }
2574
2645
 
2575
2646
  export function clearEditorResults() {
2576
2647
  state.editor.result = null;
2648
+ state.editor.lastExecutedSql = '';
2577
2649
  resetEditorResultSort();
2578
2650
  state.editor.error = null;
2579
2651
  state.editor.selectedRowIndex = null;
2580
2652
  state.editor.saving = false;
2581
2653
  state.editor.saveError = null;
2582
- if (state.editor.activeTab === 'results') {
2583
- state.editor.activeTab = 'messages';
2584
- }
2585
2654
  emitChange();
2586
2655
  }
2587
2656
 
@@ -2593,16 +2662,23 @@ export function setEditorPanelVisibility(visible) {
2593
2662
  }
2594
2663
 
2595
2664
  state.editor.editorPanelVisible = nextValue;
2665
+ storeBoolean(UI_PREFERENCE_STORAGE_KEYS.sqlEditorEditorVisible, nextValue);
2596
2666
  emitChange();
2597
2667
  }
2598
2668
 
2599
2669
  export function setEditorTab(tab) {
2670
+ if (!EDITOR_RESULT_TABS.has(tab)) {
2671
+ return;
2672
+ }
2673
+
2600
2674
  state.editor.activeTab = tab;
2675
+ storeEditorActiveTab(tab);
2601
2676
  emitChange();
2602
2677
  }
2603
2678
 
2604
2679
  export async function executeCurrentQuery() {
2605
2680
  state.editor.executing = true;
2681
+ state.editor.lastExecutedSql = state.editor.sqlText;
2606
2682
  state.editor.error = null;
2607
2683
  state.editor.selectedRowIndex = null;
2608
2684
  state.editor.saving = false;
@@ -2614,14 +2690,12 @@ export async function executeCurrentQuery() {
2614
2690
  state.editor.result = response.data;
2615
2691
  resetEditorResultSort();
2616
2692
  state.editor.error = null;
2617
- state.editor.activeTab = 'results';
2618
2693
  invalidateDatabaseCaches();
2619
2694
  await refreshQueryHistoryState();
2620
2695
  pushToast(response.message || `Executed ${response.data.statementCount} SQL statement(s).`, 'success');
2621
2696
  return true;
2622
2697
  } catch (error) {
2623
2698
  state.editor.error = normalizeError(error);
2624
- state.editor.activeTab = 'messages';
2625
2699
  await refreshQueryHistoryState();
2626
2700
  return false;
2627
2701
  } finally {
@@ -2676,6 +2750,7 @@ export function setQueryHistoryPanelVisibility(visible) {
2676
2750
  }
2677
2751
 
2678
2752
  state.editor.historyPanelVisible = nextValue;
2753
+ storeBoolean(UI_PREFERENCE_STORAGE_KEYS.sqlEditorHistoryVisible, nextValue);
2679
2754
  emitChange();
2680
2755
  }
2681
2756
 
@@ -2842,6 +2917,7 @@ export async function selectStructureEntry(name) {
2842
2917
 
2843
2918
  export function toggleStructureTablesPanel() {
2844
2919
  state.structure.tablesVisible = state.structure.tablesVisible === false;
2920
+ storeBoolean(UI_PREFERENCE_STORAGE_KEYS.structureTablesVisible, state.structure.tablesVisible);
2845
2921
  emitChange();
2846
2922
  }
2847
2923
 
@@ -2858,6 +2934,7 @@ export function setTableDesignerSqlPreviewVisibility(visible) {
2858
2934
  }
2859
2935
 
2860
2936
  state.tableDesigner.sqlPreviewVisible = nextValue;
2937
+ storeBoolean(UI_PREFERENCE_STORAGE_KEYS.tableDesignerSqlPreviewVisible, nextValue);
2861
2938
  emitChange();
2862
2939
  }
2863
2940
 
@@ -3433,6 +3510,7 @@ export function setDataSearchColumn(columnName) {
3433
3510
 
3434
3511
  export function toggleDataTablesPanel() {
3435
3512
  state.dataBrowser.tablesVisible = state.dataBrowser.tablesVisible === false;
3513
+ storeBoolean(UI_PREFERENCE_STORAGE_KEYS.dataTablesVisible, state.dataBrowser.tablesVisible);
3436
3514
  emitChange();
3437
3515
  }
3438
3516
 
@@ -3896,8 +3974,21 @@ export function getCurrentConnection(snapshot = state) {
3896
3974
  }
3897
3975
 
3898
3976
  export function getQueryMessages(snapshot = state) {
3977
+ const queryText = snapshot.editor.result?.sql ?? (snapshot.editor.error ? snapshot.editor.lastExecutedSql : '');
3978
+ const queryMessages = queryText
3979
+ ? [
3980
+ {
3981
+ tone: 'muted',
3982
+ label: 'QUERY',
3983
+ value: queryText,
3984
+ kind: 'query',
3985
+ },
3986
+ ]
3987
+ : [];
3988
+
3899
3989
  if (snapshot.editor.error) {
3900
3990
  return [
3991
+ ...queryMessages,
3901
3992
  {
3902
3993
  tone: 'alert',
3903
3994
  label: snapshot.editor.error.code,
@@ -3916,14 +4007,17 @@ export function getQueryMessages(snapshot = state) {
3916
4007
  ];
3917
4008
  }
3918
4009
 
3919
- return snapshot.editor.result.statements.map(statement => ({
3920
- tone: statement.kind === 'resultSet' ? 'success' : inferStatusTone(statement.keyword),
3921
- label: `${statement.keyword} #${statement.index + 1}`,
3922
- value:
3923
- statement.kind === 'resultSet'
3924
- ? `${statement.rowCount} row(s) returned.`
3925
- : `${statement.changes} row(s) affected.`,
3926
- }));
4010
+ return [
4011
+ ...queryMessages,
4012
+ ...snapshot.editor.result.statements.map(statement => ({
4013
+ tone: statement.kind === 'resultSet' ? 'success' : inferStatusTone(statement.keyword),
4014
+ label: `${statement.keyword} #${statement.index + 1}`,
4015
+ value:
4016
+ statement.kind === 'resultSet'
4017
+ ? `${statement.rowCount} row(s) returned.`
4018
+ : `${statement.changes} row(s) affected.`,
4019
+ })),
4020
+ ];
3927
4021
  }
3928
4022
 
3929
4023
  export function getQueryPerformance(snapshot = state) {
@@ -402,7 +402,7 @@ function renderChartCard(chart, state, analysis) {
402
402
  export function renderChartsDetail(state) {
403
403
  const detail = state.charts.detail;
404
404
  const selectedHistoryId = state.charts.selectedHistoryId;
405
- const historyVisible = state.editor.historyPanelVisible !== false;
405
+ const historyVisible = state.charts.historyPanelVisible !== false;
406
406
 
407
407
  if (!selectedHistoryId) {
408
408
  return renderEmptyChartDetail();
@@ -514,7 +514,7 @@ export function renderChartsDetail(state) {
514
514
  }
515
515
 
516
516
  export function renderChartsView(state) {
517
- const historyVisible = state.editor.historyPanelVisible !== false || !state.charts.selectedHistoryId;
517
+ const historyVisible = state.charts.historyPanelVisible !== false || !state.charts.selectedHistoryId;
518
518
 
519
519
  if (!state.connections.active && state.charts.error?.code === 'ACTIVE_DATABASE_REQUIRED') {
520
520
  return {
@@ -29,16 +29,23 @@ function renderMessagesPane(state) {
29
29
  <div class="space-y-4">
30
30
  ${items
31
31
  .map(
32
- item => `
32
+ item => {
33
+ const valueClass =
34
+ item.kind === 'query'
35
+ ? 'mt-2 whitespace-pre-wrap break-words font-mono text-xs leading-6 text-on-surface'
36
+ : 'mt-2 text-sm text-on-surface';
37
+
38
+ return `
33
39
  <div class="border border-outline-variant/10 bg-surface-container-low px-4 py-4">
34
40
  <div class="text-[10px] font-mono uppercase tracking-[0.2em] ${
35
41
  item.tone === 'alert' ? 'text-error' : 'text-primary-container'
36
42
  }">
37
43
  ${escapeHtml(item.label)}
38
44
  </div>
39
- <div class="mt-2 text-sm text-on-surface">${escapeHtml(item.value)}</div>
45
+ <div class="${valueClass}">${escapeHtml(item.value)}</div>
40
46
  </div>
41
- `,
47
+ `;
48
+ },
42
49
  )
43
50
  .join('')}
44
51
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlite-hub",
3
- "version": "0.9.12",
3
+ "version": "0.9.13",
4
4
  "description": "SQLite-only local management app backend and SPA shell",
5
5
  "main": "server/server.js",
6
6
  "bin": {