mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 10:28:44 +00:00
feat(editor): configure multi-statement result view
This commit is contained in:
@@ -71,6 +71,7 @@ import {
|
||||
type DisconnectTabHandlingMode,
|
||||
type DataTabReuseMode,
|
||||
type DataGridFilterEditorView,
|
||||
type MultiStatementDefaultView,
|
||||
type OpenTabsRestoreMode,
|
||||
type AppCloseUnsavedTabsMode,
|
||||
type SidebarObjectInfoMode,
|
||||
@@ -415,6 +416,7 @@ const editDataGridQuickEntry = ref(settingsStore.editorSettings.dataGridQuickEnt
|
||||
const editDataGridFilterEditorView = ref<DataGridFilterEditorView>(settingsStore.editorSettings.dataGridFilterEditorView);
|
||||
const dataGridFilterViewPreviewExpanded = ref(true);
|
||||
const editDataGridTextFilterPanelHeight = ref(settingsStore.editorSettings.dataGridTextFilterPanelHeight);
|
||||
const editMultiStatementDefaultView = ref<MultiStatementDefaultView>(settingsStore.editorSettings.multiStatementDefaultView);
|
||||
const editDataGridAutoTransposeSingleRow = ref(settingsStore.editorSettings.dataGridAutoTransposeSingleRow);
|
||||
const editDataGridCellDetailButtonVisible = ref(settingsStore.editorSettings.dataGridCellDetailButtonVisible);
|
||||
const editDataGridCrosshairHighlight = ref(settingsStore.editorSettings.dataGridCrosshairHighlight);
|
||||
@@ -615,6 +617,7 @@ function currentEditorSettingsDraft(): EditorSettingsDraft {
|
||||
dataGridQuickEntry: editDataGridQuickEntry.value,
|
||||
dataGridFilterEditorView: editDataGridFilterEditorView.value,
|
||||
dataGridTextFilterPanelHeight: editDataGridTextFilterPanelHeight.value,
|
||||
multiStatementDefaultView: editMultiStatementDefaultView.value,
|
||||
dataGridAutoTransposeSingleRow: editDataGridAutoTransposeSingleRow.value,
|
||||
dataGridCellDetailButtonVisible: editDataGridCellDetailButtonVisible.value,
|
||||
dataGridCrosshairHighlight: editDataGridCrosshairHighlight.value,
|
||||
@@ -1009,6 +1012,7 @@ function syncEditorSettingsDraftFromStore() {
|
||||
editDataGridQuickEntry.value = settingsStore.editorSettings.dataGridQuickEntry;
|
||||
editDataGridFilterEditorView.value = settingsStore.editorSettings.dataGridFilterEditorView;
|
||||
editDataGridTextFilterPanelHeight.value = settingsStore.editorSettings.dataGridTextFilterPanelHeight;
|
||||
editMultiStatementDefaultView.value = settingsStore.editorSettings.multiStatementDefaultView;
|
||||
editDataGridAutoTransposeSingleRow.value = settingsStore.editorSettings.dataGridAutoTransposeSingleRow;
|
||||
editDataGridCellDetailButtonVisible.value = settingsStore.editorSettings.dataGridCellDetailButtonVisible;
|
||||
editDataGridCrosshairHighlight.value = settingsStore.editorSettings.dataGridCrosshairHighlight;
|
||||
@@ -1318,6 +1322,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
|
||||
editDataGridQuickEntry.value = DEFAULT_EDITOR_SETTINGS.dataGridQuickEntry;
|
||||
editDataGridFilterEditorView.value = DEFAULT_EDITOR_SETTINGS.dataGridFilterEditorView;
|
||||
editDataGridTextFilterPanelHeight.value = DEFAULT_EDITOR_SETTINGS.dataGridTextFilterPanelHeight;
|
||||
editMultiStatementDefaultView.value = DEFAULT_EDITOR_SETTINGS.multiStatementDefaultView;
|
||||
editDataGridAutoTransposeSingleRow.value = DEFAULT_EDITOR_SETTINGS.dataGridAutoTransposeSingleRow;
|
||||
editDataGridCellDetailButtonVisible.value = DEFAULT_EDITOR_SETTINGS.dataGridCellDetailButtonVisible;
|
||||
editDataGridCrosshairHighlight.value = DEFAULT_EDITOR_SETTINGS.dataGridCrosshairHighlight;
|
||||
@@ -1402,6 +1407,7 @@ function resetAllDefaults() {
|
||||
editDataGridQuickEntry.value = DEFAULT_EDITOR_SETTINGS.dataGridQuickEntry;
|
||||
editDataGridFilterEditorView.value = DEFAULT_EDITOR_SETTINGS.dataGridFilterEditorView;
|
||||
editDataGridTextFilterPanelHeight.value = DEFAULT_EDITOR_SETTINGS.dataGridTextFilterPanelHeight;
|
||||
editMultiStatementDefaultView.value = DEFAULT_EDITOR_SETTINGS.multiStatementDefaultView;
|
||||
editDataGridAutoTransposeSingleRow.value = DEFAULT_EDITOR_SETTINGS.dataGridAutoTransposeSingleRow;
|
||||
editDataGridCellDetailButtonVisible.value = DEFAULT_EDITOR_SETTINGS.dataGridCellDetailButtonVisible;
|
||||
editDataGridCrosshairHighlight.value = DEFAULT_EDITOR_SETTINGS.dataGridCrosshairHighlight;
|
||||
@@ -5539,6 +5545,21 @@ onUnmounted(() => {
|
||||
@update:model-value="updatePageSizeDraft"
|
||||
/>
|
||||
</div>
|
||||
<div data-settings-search-id="multi-statement-default-view" :class="['flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2', settingsSearchTargetClass('multi-statement-default-view')]">
|
||||
<div class="min-w-0 space-y-1">
|
||||
<Label for="multi-statement-default-view">{{ t("settings.multiStatementDefaultView") }}</Label>
|
||||
<p class="text-xs text-muted-foreground">{{ t("settings.multiStatementDefaultViewDescription") }}</p>
|
||||
</div>
|
||||
<Select v-model="editMultiStatementDefaultView">
|
||||
<SelectTrigger id="multi-statement-default-view" class="h-8 w-32 shrink-0">
|
||||
<SelectValue :placeholder="t('settings.multiStatementDefaultView')" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="result">{{ t("tabs.tableData") }}</SelectItem>
|
||||
<SelectItem value="summary">{{ t("tabs.executionSummary") }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="space-y-1">
|
||||
<Label for="query-result-max-rows-enabled">
|
||||
|
||||
@@ -275,7 +275,7 @@ describe("useSqlExecution", () => {
|
||||
expect(executeCurrentSql).toHaveBeenCalledWith("SELECT * FROM patrol WHERE post_id = '224';", {});
|
||||
});
|
||||
|
||||
it("opens the execution summary for a multi-statement batch", async () => {
|
||||
it("opens the result table for a multi-statement batch by default", async () => {
|
||||
const sql = "SELECT 1;\nSELECT 2;";
|
||||
const activeTab = ref<QueryTab | undefined>({ ...queryTab("app"), sql });
|
||||
const activeConnection = ref<ConnectionConfig | undefined>(connection("mysql"));
|
||||
@@ -295,6 +295,30 @@ describe("useSqlExecution", () => {
|
||||
|
||||
await execution.tryExecute();
|
||||
|
||||
expect(activeOutputView.value).toBe("result");
|
||||
});
|
||||
|
||||
it("opens the execution summary for a multi-statement batch when configured", async () => {
|
||||
const sql = "SELECT 1;\nSELECT 2;";
|
||||
const activeTab = ref<QueryTab | undefined>({ ...queryTab("app"), sql });
|
||||
const activeConnection = ref<ConnectionConfig | undefined>(connection("mysql"));
|
||||
const activeOutputView = ref<"result" | "summary" | "explain" | "chart">("result");
|
||||
const queryStore = useQueryStore();
|
||||
useSettingsStore().editorSettings.multiStatementDefaultView = "summary";
|
||||
vi.spyOn(queryStore, "executeCurrentSql").mockImplementation(async () => {
|
||||
if (activeTab.value) activeTab.value.result = { columns: ["value"], rows: [[1]], affected_rows: 0, execution_time_ms: 1 };
|
||||
});
|
||||
vi.spyOn(useHistoryStore(), "add").mockResolvedValue(undefined);
|
||||
|
||||
const execution = useSqlExecution({
|
||||
activeTab: computed(() => activeTab.value),
|
||||
activeConnection: computed(() => activeConnection.value),
|
||||
executableSql: computed(() => sql),
|
||||
activeOutputView,
|
||||
});
|
||||
|
||||
await execution.tryExecute();
|
||||
|
||||
expect(activeOutputView.value).toBe("summary");
|
||||
});
|
||||
|
||||
@@ -468,7 +492,7 @@ GO`;
|
||||
expect(activeTab.value?.result?.execution_error).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps ordinary SQL Server multi-result batches on their summary", async () => {
|
||||
it("opens ordinary SQL Server multi-result batches in the result table by default", async () => {
|
||||
const sql = "SELECT 1 AS first_value; SELECT 2 AS second_value;";
|
||||
const activeTab = ref<QueryTab | undefined>({ ...queryTab("dbx_sqlserver_demo"), sql });
|
||||
const activeConnection = ref<ConnectionConfig | undefined>(connection("sqlserver"));
|
||||
@@ -494,12 +518,12 @@ GO`;
|
||||
|
||||
await execution.tryExecute();
|
||||
|
||||
expect(activeOutputView.value).toBe("summary");
|
||||
expect(activeOutputView.value).toBe("result");
|
||||
expect(setActiveResultIndex).not.toHaveBeenCalled();
|
||||
expect(activeTab.value?.result?.rows).toEqual([[1]]);
|
||||
});
|
||||
|
||||
it("keeps the summary for ordinary SQL Server data aliased as Message", async () => {
|
||||
it("opens ordinary SQL Server data aliased as Message in the result table by default", async () => {
|
||||
const sql = `DECLARE @value nvarchar(1) = N'x';
|
||||
SELECT @value AS Message;`;
|
||||
const activeTab = ref<QueryTab | undefined>({ ...queryTab("dbx_sqlserver_demo"), sql });
|
||||
@@ -520,7 +544,7 @@ SELECT @value AS Message;`;
|
||||
|
||||
await execution.tryExecute();
|
||||
|
||||
expect(activeOutputView.value).toBe("summary");
|
||||
expect(activeOutputView.value).toBe("result");
|
||||
expect(activeTab.value?.result?.rows).toEqual([["x"]]);
|
||||
});
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ export function useSqlExecution(deps: {
|
||||
return;
|
||||
}
|
||||
const statementCount = splitSqlStatementRanges(sql, executionDatabaseType).length;
|
||||
deps.activeOutputView.value = statementCount > 1 ? "summary" : "result";
|
||||
deps.activeOutputView.value = statementCount > 1 ? settingsStore.editorSettings.multiStatementDefaultView : "result";
|
||||
const connName = executionConnection?.name || "";
|
||||
const start = Date.now();
|
||||
const isRedis = executionDatabaseType === "redis";
|
||||
|
||||
@@ -6298,6 +6298,8 @@ export default {
|
||||
tableOpenPageSizeDescription: "Rows loaded per page when opening a new table. Changing rows per page in a table updates this default for future table tabs.",
|
||||
queryPageSize: "Default query rows per page",
|
||||
queryPageSizeDescription: "Rows loaded per query result page. The maximum supported page size is {max}.",
|
||||
multiStatementDefaultView: "Default view for multiple statements",
|
||||
multiStatementDefaultViewDescription: "Choose whether batches with multiple SQL statements open in the result table or execution summary.",
|
||||
queryResultMaxRows: "Maximum query result rows",
|
||||
queryResultMaxRowsEnabled: "Limit query result rows",
|
||||
queryResultMaxRowsDescription: "Caps rows returned by queries, table data, stored procedures, and continuous loading.",
|
||||
|
||||
@@ -6000,6 +6000,8 @@ export default withEnglishFallback({
|
||||
tableOpenPageSizeDescription: "Filas cargadas por página al abrir una tabla nueva. Cambiar las filas por página actualiza este valor para futuras pestañas de tablas.",
|
||||
queryPageSize: "Filas predeterminadas por página de consulta",
|
||||
queryPageSizeDescription: "Filas cargadas por página de resultados. Se admiten hasta {max} filas.",
|
||||
multiStatementDefaultView: "Vista predeterminada para varias sentencias",
|
||||
multiStatementDefaultViewDescription: "Elige si los lotes con varias sentencias SQL se abren en la tabla de resultados o en el resumen de ejecución.",
|
||||
queryResultMaxRows: "Máximo de filas del resultado",
|
||||
queryResultMaxRowsEnabled: "Limitar filas del resultado",
|
||||
queryResultMaxRowsDescription: "Limita las filas conservadas por consultas, datos de tablas, procedimientos almacenados y carga continua.",
|
||||
|
||||
@@ -6000,6 +6000,8 @@ export default withEnglishFallback({
|
||||
tableOpenPageSizeDescription: "Righe caricate per pagina quando si apre una nuova tabella. La modifica delle righe per pagina aggiorna questo valore per le future schede tabella.",
|
||||
queryPageSize: "Righe predefinite per pagina di query",
|
||||
queryPageSizeDescription: "Righe caricate per pagina dei risultati. Sono supportate fino a {max} righe.",
|
||||
multiStatementDefaultView: "Vista predefinita per istruzioni multiple",
|
||||
multiStatementDefaultViewDescription: "Scegli se i batch con più istruzioni SQL si aprono nella tabella dei risultati o nel riepilogo dell'esecuzione.",
|
||||
queryResultMaxRows: "Numero massimo di righe del risultato",
|
||||
queryResultMaxRowsEnabled: "Limita le righe del risultato",
|
||||
queryResultMaxRowsDescription: "Limita le righe conservate da query, dati tabella, stored procedure e caricamento continuo.",
|
||||
|
||||
@@ -6034,6 +6034,8 @@ export default withEnglishFallback({
|
||||
tableOpenPageSizeDescription: "新しいテーブルを開くときに 1 ページあたり読み込む行数です。テーブルで行数を変更すると、今後のテーブルタブのデフォルトも更新されます。",
|
||||
queryPageSize: "クエリ結果のデフォルト行数",
|
||||
queryPageSizeDescription: "クエリ結果の 1 ページあたりの行数です。最大 {max} 行まで指定できます。",
|
||||
multiStatementDefaultView: "複数ステートメントの既定ビュー",
|
||||
multiStatementDefaultViewDescription: "複数の SQL ステートメントを含むバッチを、結果テーブルまたは実行サマリーのどちらで開くか選択します。",
|
||||
queryResultMaxRows: "クエリ結果の最大行数",
|
||||
queryResultMaxRowsEnabled: "クエリ結果の行数を制限",
|
||||
queryResultMaxRowsDescription: "クエリ、テーブルデータ、ストアドプロシージャ、および連続読み込みで保持する合計行数を制限します。",
|
||||
|
||||
@@ -5695,6 +5695,8 @@ export default withEnglishFallback({
|
||||
tableOpenPageSizeDescription: "새 테이블을 열 때 페이지당 로드되는 행 수입니다. 테이블에서 페이지당 행을 변경하면 향후 테이블 탭의 기본값이 업데이트됩니다.",
|
||||
queryPageSize: "쿼리 결과 기본 페이지당 행 수",
|
||||
queryPageSizeDescription: "쿼리 결과 페이지당 로드할 행 수입니다. 최대 {max}행을 지원합니다.",
|
||||
multiStatementDefaultView: "여러 구문 기본 보기",
|
||||
multiStatementDefaultViewDescription: "여러 SQL 구문이 있는 배치를 결과 테이블 또는 실행 요약 중 어디에서 열지 선택합니다.",
|
||||
queryResultMaxRows: "쿼리 결과 최대 행 수",
|
||||
queryResultMaxRowsEnabled: "쿼리 결과 행 수 제한",
|
||||
queryResultMaxRowsDescription: "쿼리, 테이블 데이터, 저장 프로시저 및 연속 로딩에서 유지할 총 행 수를 제한합니다.",
|
||||
|
||||
@@ -6002,6 +6002,8 @@ export default withEnglishFallback({
|
||||
tableOpenPageSizeDescription: "Linhas carregadas por página ao abrir uma nova tabela. Alterar as linhas por página atualiza esse padrão para futuras abas de tabelas.",
|
||||
queryPageSize: "Linhas padrão por página de consulta",
|
||||
queryPageSizeDescription: "Linhas carregadas por página de resultados. São suportadas até {max} linhas.",
|
||||
multiStatementDefaultView: "Visualização padrão para várias instruções",
|
||||
multiStatementDefaultViewDescription: "Escolha se lotes com várias instruções SQL abrem na tabela de resultados ou no resumo da execução.",
|
||||
queryResultMaxRows: "Máximo de linhas do resultado",
|
||||
queryResultMaxRowsEnabled: "Limitar linhas do resultado",
|
||||
queryResultMaxRowsDescription: "Limita as linhas mantidas por consultas, dados de tabelas, procedimentos armazenados e carregamento contínuo.",
|
||||
|
||||
@@ -6282,6 +6282,8 @@ export default withEnglishFallback({
|
||||
tableOpenPageSizeDescription: "新打开数据表时每页加载的行数。在表数据页修改每页行数后,也会更新后续新建表标签页的默认值。",
|
||||
queryPageSize: "查询结果默认每页行数",
|
||||
queryPageSizeDescription: "每个查询结果分页加载的行数,最大支持 {max} 行。",
|
||||
multiStatementDefaultView: "多语句执行默认视图",
|
||||
multiStatementDefaultViewDescription: "选择多条 SQL 语句批量执行后默认打开数据表或执行摘要。",
|
||||
queryResultMaxRows: "查询结果最大行数",
|
||||
queryResultMaxRowsEnabled: "限制查询结果行数",
|
||||
queryResultMaxRowsDescription: "限制查询、表数据、存储过程及连续滚动累计保留的总行数。",
|
||||
|
||||
@@ -5319,6 +5319,8 @@ export default withEnglishFallback({
|
||||
tableOpenPageSizeDescription: "新開啟資料表時每頁載入的列數。在資料表頁面調整每頁列數後,也會更新後續新建資料表分頁的預設值。",
|
||||
queryPageSize: "查詢結果預設每頁列數",
|
||||
queryPageSizeDescription: "每個查詢結果分頁載入的列數,最多支援 {max} 列。",
|
||||
multiStatementDefaultView: "多語句執行預設檢視",
|
||||
multiStatementDefaultViewDescription: "選擇多條 SQL 語句批次執行後預設開啟資料表或執行摘要。",
|
||||
queryResultMaxRows: "查詢結果最大列數",
|
||||
queryResultMaxRowsEnabled: "限制查詢結果列數",
|
||||
queryResultMaxRowsDescription: "限制查詢、資料表資料、預存程序及連續捲動累計保留的總列數。",
|
||||
|
||||
@@ -100,6 +100,10 @@ describe("EDITOR_SETTINGS_DRAFT_KEYS", () => {
|
||||
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("dataGridTextFilterPanelHeight");
|
||||
});
|
||||
|
||||
it("includes the multi-statement default view", () => {
|
||||
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("multiStatementDefaultView");
|
||||
});
|
||||
|
||||
it("includes the cell detail button visibility", () => {
|
||||
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("dataGridCellDetailButtonVisible");
|
||||
});
|
||||
@@ -185,6 +189,10 @@ describe("editorSettingsDraftFromSettings", () => {
|
||||
expect(draft.dataGridTextFilterPanelHeight).toBe(224);
|
||||
});
|
||||
|
||||
it("maps the multi-statement default view from settings", () => {
|
||||
expect(editorSettingsDraftFromSettings(makeSettings({ multiStatementDefaultView: "summary" })).multiStatementDefaultView).toBe("summary");
|
||||
});
|
||||
|
||||
it("preserves the table-open default for legacy settings", () => {
|
||||
const settings = makeSettings();
|
||||
delete (settings as Partial<EditorSettings>).tableOpenPageSize;
|
||||
@@ -307,6 +315,13 @@ describe("editorSettingsPatchFromDraft", () => {
|
||||
expect(editorSettingsPatchFromDraft(visible, hidden)).toEqual({ dataGridCellDetailButtonVisible: true });
|
||||
});
|
||||
|
||||
it("includes the multi-statement default view when changed", () => {
|
||||
const result = editorSettingsDraftFromSettings(makeSettings({ multiStatementDefaultView: "result" }));
|
||||
const summary = editorSettingsDraftFromSettings(makeSettings({ multiStatementDefaultView: "summary" }));
|
||||
|
||||
expect(editorSettingsPatchFromDraft(summary, result)).toEqual({ multiStatementDefaultView: "summary" });
|
||||
});
|
||||
|
||||
it("includes continueOnErrorOnBatch in patch when changed", () => {
|
||||
const settings = makeSettings({ continueOnErrorOnBatch: false });
|
||||
const draft = editorSettingsDraftFromSettings(settings);
|
||||
|
||||
@@ -66,6 +66,18 @@ describe("settings search", () => {
|
||||
expect(SETTINGS_SEARCH_DEFINITIONS.map((definition) => definition.id)).not.toContain("editor-global-query-timeout");
|
||||
});
|
||||
|
||||
it("indexes the multi-statement default view and its settings control", () => {
|
||||
expect(SETTINGS_SEARCH_DEFINITIONS).toContainEqual({
|
||||
id: "multi-statement-default-view",
|
||||
category: "data",
|
||||
titleKey: "settings.multiStatementDefaultView",
|
||||
descriptionKey: "settings.multiStatementDefaultViewDescription",
|
||||
targetId: "multi-statement-default-view",
|
||||
});
|
||||
expect(settingsDialogSource).toContain('data-settings-search-id="multi-statement-default-view"');
|
||||
expect(settingsDialogSource).toContain('v-model="editMultiStatementDefaultView"');
|
||||
});
|
||||
|
||||
it("matches translated title, description, and category without changing declared order", () => {
|
||||
const entries = resolveSettingsSearchEntries(definitions, { isWeb: false, visibleCategories: allCategories }, translate, categoryLabels);
|
||||
expect(searchSettings(entries, "TYPEFACE", "en").map((entry) => entry.id)).toEqual(["font"]);
|
||||
|
||||
@@ -45,6 +45,7 @@ export const EDITOR_SETTINGS_DRAFT_KEYS = [
|
||||
"dataGridQuickEntry",
|
||||
"dataGridFilterEditorView",
|
||||
"dataGridTextFilterPanelHeight",
|
||||
"multiStatementDefaultView",
|
||||
"dataGridAutoTransposeSingleRow",
|
||||
"dataGridCellDetailButtonVisible",
|
||||
"dataGridCrosshairHighlight",
|
||||
|
||||
@@ -180,6 +180,7 @@ export const SETTINGS_SEARCH_DEFINITIONS: readonly SettingsSearchDefinition[] =
|
||||
{ id: "navigation-disconnect-tabs", category: "navigation", titleKey: "settings.disconnectTabHandlingMode", descriptionKey: "settings.disconnectTabHandlingModeDescription", targetId: "navigation" },
|
||||
{ id: "query-page-size", category: "data", titleKey: "settings.queryPageSize", descriptionKey: "settings.queryPageSizeDescription", targetId: "data" },
|
||||
{ id: "data-page-size", category: "data", titleKey: "settings.tableOpenPageSize", descriptionKey: "settings.tableOpenPageSizeDescription", targetId: "data" },
|
||||
{ id: "multi-statement-default-view", category: "data", titleKey: "settings.multiStatementDefaultView", descriptionKey: "settings.multiStatementDefaultViewDescription", targetId: "multi-statement-default-view" },
|
||||
{ id: "query-result-max-rows", category: "data", titleKey: "settings.queryResultMaxRows", descriptionKey: "settings.queryResultMaxRowsDescription", targetId: "data" },
|
||||
{ id: "data-grid-header-comments", category: "data", titleKey: "settings.showColumnCommentsInHeader", descriptionKey: "settings.showColumnCommentsInHeaderDescription", targetId: "data" },
|
||||
{ id: "data-grid-header-types", category: "data", titleKey: "settings.showColumnTypesInHeader", descriptionKey: "settings.showColumnTypesInHeaderDescription", targetId: "data" },
|
||||
|
||||
@@ -276,6 +276,12 @@ describe("normalizeEditorSettings", () => {
|
||||
expect(normalizeEditorSettings({ resultRunDisplayMode: "invalid" as any }).resultRunDisplayMode).toBe("tabs");
|
||||
});
|
||||
|
||||
it("defaults multi-statement execution to the result table and preserves the summary option", () => {
|
||||
expect(normalizeEditorSettings({}).multiStatementDefaultView).toBe("result");
|
||||
expect(normalizeEditorSettings({ multiStatementDefaultView: "summary" }).multiStatementDefaultView).toBe("summary");
|
||||
expect(normalizeEditorSettings({ multiStatementDefaultView: "invalid" as any }).multiStatementDefaultView).toBe("result");
|
||||
});
|
||||
|
||||
it("defaults persistent data grid view options off and preserves enabled values", () => {
|
||||
const defaults = normalizeEditorSettings({});
|
||||
expect(defaults.dataGridMultiRowTranspose).toBe(false);
|
||||
|
||||
@@ -431,6 +431,8 @@ export type DataGridSearchMode = (typeof DATA_GRID_SEARCH_MODES)[number];
|
||||
export type DataGridFilterEditorView = "quick" | "conditions" | "text";
|
||||
const RESULT_RUN_DISPLAY_MODES = ["tabs", "list"] as const;
|
||||
export type ResultRunDisplayMode = (typeof RESULT_RUN_DISPLAY_MODES)[number];
|
||||
const MULTI_STATEMENT_DEFAULT_VIEWS = ["result", "summary"] as const;
|
||||
export type MultiStatementDefaultView = (typeof MULTI_STATEMENT_DEFAULT_VIEWS)[number];
|
||||
export const TABLE_FONT_SIZE_MIN = 8;
|
||||
export const TABLE_FONT_SIZE_MAX = 16;
|
||||
export const TABLE_FONT_SIZE_DEFAULT = 13;
|
||||
@@ -581,6 +583,7 @@ export interface EditorSettings {
|
||||
dataGridCopyExtractor: DataGridCopyPreference;
|
||||
dataGridExtractorOptions: DataGridExtractorOptions;
|
||||
resultRunDisplayMode: ResultRunDisplayMode;
|
||||
multiStatementDefaultView: MultiStatementDefaultView;
|
||||
dataGridAutoTransposeSingleRow: boolean;
|
||||
dataGridCellDetailButtonVisible: boolean;
|
||||
dataGridCrosshairHighlight: boolean;
|
||||
@@ -797,6 +800,7 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
||||
dataGridCopyExtractor: "smart",
|
||||
dataGridExtractorOptions: normalizeDataGridExtractorOptions(DEFAULT_DATA_GRID_EXTRACTOR_OPTIONS),
|
||||
resultRunDisplayMode: "tabs",
|
||||
multiStatementDefaultView: "result",
|
||||
dataGridAutoTransposeSingleRow: false,
|
||||
dataGridCellDetailButtonVisible: true,
|
||||
dataGridCrosshairHighlight: false,
|
||||
@@ -926,6 +930,10 @@ function normalizeResultRunDisplayMode(value: unknown): ResultRunDisplayMode {
|
||||
return RESULT_RUN_DISPLAY_MODES.includes(value as ResultRunDisplayMode) ? (value as ResultRunDisplayMode) : DEFAULT_EDITOR_SETTINGS.resultRunDisplayMode;
|
||||
}
|
||||
|
||||
function normalizeMultiStatementDefaultView(value: unknown): MultiStatementDefaultView {
|
||||
return MULTI_STATEMENT_DEFAULT_VIEWS.includes(value as MultiStatementDefaultView) ? (value as MultiStatementDefaultView) : DEFAULT_EDITOR_SETTINGS.multiStatementDefaultView;
|
||||
}
|
||||
|
||||
function normalizeTableFontSize(value: unknown): number {
|
||||
if (typeof value !== "number" || !Number.isFinite(value)) return TABLE_FONT_SIZE_DEFAULT;
|
||||
return Math.min(TABLE_FONT_SIZE_MAX, Math.max(TABLE_FONT_SIZE_MIN, Math.round(value)));
|
||||
@@ -1199,6 +1207,7 @@ export function normalizeEditorSettings(settings: Partial<EditorSettings>, exist
|
||||
dataGridCopyExtractor: normalizeDataGridCopyPreference(settings.dataGridCopyExtractor),
|
||||
dataGridExtractorOptions: normalizeDataGridExtractorOptions(settings.dataGridExtractorOptions),
|
||||
resultRunDisplayMode: normalizeResultRunDisplayMode(settings.resultRunDisplayMode),
|
||||
multiStatementDefaultView: normalizeMultiStatementDefaultView(settings.multiStatementDefaultView),
|
||||
dataGridAutoTransposeSingleRow: settings.dataGridAutoTransposeSingleRow === true,
|
||||
dataGridCellDetailButtonVisible: typeof settings.dataGridCellDetailButtonVisible === "boolean" ? settings.dataGridCellDetailButtonVisible : DEFAULT_EDITOR_SETTINGS.dataGridCellDetailButtonVisible,
|
||||
dataGridCrosshairHighlight: typeof settings.dataGridCrosshairHighlight === "boolean" ? settings.dataGridCrosshairHighlight : DEFAULT_EDITOR_SETTINGS.dataGridCrosshairHighlight,
|
||||
@@ -1818,6 +1827,7 @@ export const useSettingsStore = defineStore("settings", () => {
|
||||
if (partial.dataGridCopyExtractor !== undefined) editorSettings.value.dataGridCopyExtractor = normalizeDataGridCopyPreference(partial.dataGridCopyExtractor);
|
||||
if (partial.dataGridExtractorOptions !== undefined) editorSettings.value.dataGridExtractorOptions = normalizeDataGridExtractorOptions(partial.dataGridExtractorOptions);
|
||||
if (partial.resultRunDisplayMode !== undefined) editorSettings.value.resultRunDisplayMode = normalizeResultRunDisplayMode(partial.resultRunDisplayMode);
|
||||
if (partial.multiStatementDefaultView !== undefined) editorSettings.value.multiStatementDefaultView = normalizeMultiStatementDefaultView(partial.multiStatementDefaultView);
|
||||
if (partial.dataGridAutoTransposeSingleRow !== undefined) editorSettings.value.dataGridAutoTransposeSingleRow = partial.dataGridAutoTransposeSingleRow === true;
|
||||
if (partial.dataGridCellDetailButtonVisible !== undefined) editorSettings.value.dataGridCellDetailButtonVisible = typeof partial.dataGridCellDetailButtonVisible === "boolean" ? partial.dataGridCellDetailButtonVisible : DEFAULT_EDITOR_SETTINGS.dataGridCellDetailButtonVisible;
|
||||
if (partial.dataGridCrosshairHighlight !== undefined) editorSettings.value.dataGridCrosshairHighlight = typeof partial.dataGridCrosshairHighlight === "boolean" ? partial.dataGridCrosshairHighlight : DEFAULT_EDITOR_SETTINGS.dataGridCrosshairHighlight;
|
||||
|
||||
Reference in New Issue
Block a user