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.
package/frontend/js/app.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
1341
|
-
|
|
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
|
-
|
|
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 ??
|
|
796
|
+
inspectorHidden: cachedState?.inspectorHidden ?? readStoredInspectorHidden(),
|
|
769
797
|
persistStateOnDestroy: true,
|
|
770
798
|
selectedTableName: null,
|
|
771
799
|
};
|
package/frontend/js/store.js
CHANGED
|
@@ -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:
|
|
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
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
statement.
|
|
3924
|
-
|
|
3925
|
-
|
|
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.
|
|
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.
|
|
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="
|
|
45
|
+
<div class="${valueClass}">${escapeHtml(item.value)}</div>
|
|
40
46
|
</div>
|
|
41
|
-
|
|
47
|
+
`;
|
|
48
|
+
},
|
|
42
49
|
)
|
|
43
50
|
.join('')}
|
|
44
51
|
</div>
|