diff --git a/apps/desktop/src/stores/queryStore.ts b/apps/desktop/src/stores/queryStore.ts index ccd34ed96..26d7d2880 100644 --- a/apps/desktop/src/stores/queryStore.ts +++ b/apps/desktop/src/stores/queryStore.ts @@ -43,8 +43,16 @@ function loadSavedTabs(): { tabs: QueryTab[]; activeTabId: string | null } { } } +function getI18nT() { + try { + return useI18n().t; + } catch { + return ((key: string, ..._args: unknown[]) => key) as ReturnType["t"]; + } +} + export const useQueryStore = defineStore("query", () => { - const { t } = useI18n(); + const t = getI18nT(); const restored = loadSavedTabs(); const tabs = ref(restored.tabs); const activeTabId = ref(restored.activeTabId); diff --git a/packages/app-tests/dialogOpenWatcher.test.ts b/packages/app-tests/dialogOpenWatcher.test.ts index 3037b1d4e..b55e4b8b9 100644 --- a/packages/app-tests/dialogOpenWatcher.test.ts +++ b/packages/app-tests/dialogOpenWatcher.test.ts @@ -10,7 +10,6 @@ const mountedOpenDialogs = [ "apps/desktop/src/components/sql-file/SqlFileExecutionDialog.vue", "apps/desktop/src/components/diagram/SchemaDiagramDialog.vue", "apps/desktop/src/components/import/TableImportDialog.vue", - "apps/desktop/src/components/structure/TableStructureEditorDialog.vue", "apps/desktop/src/components/lineage/FieldLineageDialog.vue", "apps/desktop/src/components/search/DatabaseSearchDialog.vue", "apps/desktop/src/components/export/DatabaseExportDialog.vue", diff --git a/packages/app-tests/newQueryContext.test.ts b/packages/app-tests/newQueryContext.test.ts index bcaf76a4e..d25d09986 100644 --- a/packages/app-tests/newQueryContext.test.ts +++ b/packages/app-tests/newQueryContext.test.ts @@ -47,6 +47,7 @@ test("new query target prefers the active data tab context", () => { assert.deepEqual(target, { connectionId: "conn-data", database: "analytics", + schema: undefined, shouldRefreshDefaultDatabase: false, }); }); @@ -71,6 +72,7 @@ test("new query target uses the selected sidebar node when there is no active ta assert.deepEqual(target, { connectionId: "conn-tree", database: "reporting", + schema: "public", shouldRefreshDefaultDatabase: false, }); }); @@ -93,6 +95,7 @@ test("new query target prefers the selected sidebar node after sidebar focus", ( assert.deepEqual(target, { connectionId: "conn-tree", database: "reporting", + schema: undefined, shouldRefreshDefaultDatabase: false, }); }); @@ -108,6 +111,7 @@ test("new query target refreshes default database for connection-only sidebar no assert.deepEqual(target, { connectionId: "conn-tree", database: "saved_default", + schema: undefined, shouldRefreshDefaultDatabase: true, }); }); diff --git a/packages/app-tests/tableStructureEditorPresentation.test.ts b/packages/app-tests/tableStructureEditorPresentation.test.ts index ea1e05eae..bda29427e 100644 --- a/packages/app-tests/tableStructureEditorPresentation.test.ts +++ b/packages/app-tests/tableStructureEditorPresentation.test.ts @@ -2,7 +2,7 @@ import { readFileSync } from "node:fs"; import { strict as assert } from "node:assert"; import test from "node:test"; -const source = readFileSync("apps/desktop/src/components/structure/TableStructureEditorDialog.vue", "utf8"); +const source = readFileSync("apps/desktop/src/components/structure/TableStructureEditor.vue", "utf8"); const clickhouseSource = readFileSync("crates/dbx-core/src/db/clickhouse_driver.rs", "utf8"); test("column comments can be expanded into a multiline editor", () => { @@ -14,9 +14,9 @@ test("column comments can be expanded into a multiline editor", () => { test("structure editor keeps columns when optional metadata fails", () => { assert.match(source, /const nextColumns = await api\.getColumns/); - assert.match(source, /api\s*\n\s*\.listIndexes[\s\S]*\.catch\(\(\) => \[\]\)/); - assert.match(source, /api\s*\n\s*\.listForeignKeys[\s\S]*\.catch\(\(\) => \[\]\)/); - assert.match(source, /api\s*\n\s*\.listTriggers[\s\S]*\.catch\(\(\) => \[\]\)/); + assert.match(source, /api\.listIndexes[\s\S]*?\.catch\(\(\) => \[\]\)/); + assert.match(source, /api\.listForeignKeys[\s\S]*?\.catch\(\(\) => \[\]\)/); + assert.match(source, /api\.listTriggers[\s\S]*?\.catch\(\(\) => \[\]\)/); }); test("ClickHouse column metadata preserves comments for structure editing", () => { @@ -24,8 +24,12 @@ test("ClickHouse column metadata preserves comments for structure editing", () = assert.match(clickhouseSource, /comment:\s*row\.get\(5\)/); }); -test("structure editor loads immediately when mounted open", () => { - assert.match(source, /watch\(\s*open,[\s\S]*\{\s*immediate:\s*true\s*\},?\s*\)/); +test("structure editor loads table metadata on mount", () => { + assert.match(source, /async function loadStructure/); + assert.match(source, /api\.getColumns/); + assert.match(source, /api\.listIndexes/); + assert.match(source, /api\.listForeignKeys/); + assert.match(source, /api\.listTriggers/); }); test("structure editor gates controls through table structure capabilities", () => { @@ -52,9 +56,9 @@ test("structure editor exposes column order controls", () => { }); test("structure editor uses a dense wide layout for large tables", () => { - assert.match(source, /sm:max-w-\[1180px\]/); - assert.doesNotMatch(source, /1500px/); assert.match(source, /grid-cols-\[minmax\(0,1fr\)_300px\]/); assert.match(source, /data-structure-density="compact"/); assert.match(source, /class="h-6 min-w-28 text-\[11px\]"/); + assert.match(source, /w-36/); + assert.match(source, /w-24/); }); diff --git a/packages/app-tests/tableStructureSqlBackend.test.ts b/packages/app-tests/tableStructureSqlBackend.test.ts index c63db175e..6a17ed0c9 100644 --- a/packages/app-tests/tableStructureSqlBackend.test.ts +++ b/packages/app-tests/tableStructureSqlBackend.test.ts @@ -5,7 +5,7 @@ import test from "node:test"; const apiSource = readFileSync("apps/desktop/src/lib/api.ts", "utf8"); const tauriSource = readFileSync("apps/desktop/src/lib/tauri.ts", "utf8"); const httpSource = readFileSync("apps/desktop/src/lib/http.ts", "utf8"); -const dialogSource = readFileSync("apps/desktop/src/components/structure/TableStructureEditorDialog.vue", "utf8"); +const dialogSource = readFileSync("apps/desktop/src/components/structure/TableStructureEditor.vue", "utf8"); const tableStructureTypesSource = readFileSync("apps/desktop/src/lib/tableStructureEditorSql.ts", "utf8"); const rustCoreLibSource = readFileSync("crates/dbx-core/src/lib.rs", "utf8"); const rustTableStructureSqlSource = readFileSync("crates/dbx-core/src/table_structure_sql.rs", "utf8");