fix(tabs): reuse data tabs only for the same table
This commit is contained in:
16 files changed
+115
-23
No files matched your search
@@ -99,6 +99,7 @@ describe("useNavigationTargets with the real query store", () => {
|
||||
vi.unstubAllGlobals();
|
||||
installLocalStorage();
|
||||
mocks.connectionStore.activeConnectionId = "";
|
||||
mocks.connectionStore.getConfig.mockImplementation((connectionId: string) => ({ id: connectionId, db_type: "postgres" }));
|
||||
mocks.settingsStore.editorSettings.reuseDataTab = true;
|
||||
mocks.ensureConnected?.mockResolvedValue?.(undefined);
|
||||
mocks.connectionStore.ensureConnected.mockResolvedValue(undefined);
|
||||
@@ -172,6 +173,63 @@ describe("useNavigationTargets with the real query store", () => {
|
||||
expect(new Set(queryStore.tabs.map((tab) => tab.id))).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("keeps different sidebar tables independent when data-tab reuse is enabled", async () => {
|
||||
const { queryStore } = await setupNavigation();
|
||||
const { useSidebarDataOpenRuntime } = await import("@/composables/useSidebarDataOpenRuntime");
|
||||
const runtime = useSidebarDataOpenRuntime();
|
||||
const users = { id: "users", label: "users", type: "table" as const, connectionId: "connection-1", database: "app", schema: "public", tableType: "TABLE" };
|
||||
|
||||
await runtime.openData(users);
|
||||
await runtime.openData({ ...users, id: "orders", label: "orders" });
|
||||
|
||||
expect(queryStore.tabs).toHaveLength(2);
|
||||
expect(queryStore.tabs.map((tab) => tab.tableMeta?.tableName)).toEqual(["users", "orders"]);
|
||||
});
|
||||
|
||||
it("reuses a sidebar table when the same table is opened from the object browser", async () => {
|
||||
mocks.connectionStore.getConfig.mockImplementation((connectionId: string) => ({ id: connectionId, db_type: "mysql" }));
|
||||
const { navigation, queryStore } = await setupNavigation();
|
||||
const { useSidebarDataOpenRuntime } = await import("@/composables/useSidebarDataOpenRuntime");
|
||||
const runtime = useSidebarDataOpenRuntime();
|
||||
const users = { id: "users", label: "users", type: "table" as const, connectionId: "connection-1", database: "app", tableType: "TABLE" };
|
||||
|
||||
await runtime.openData(users);
|
||||
const sidebarTabId = queryStore.activeTabId;
|
||||
await navigation.openObjectBrowserTableTarget({ connectionId: "connection-1", database: "app", schema: "app", tableName: "users", tableType: "TABLE" });
|
||||
|
||||
expect(queryStore.tabs).toHaveLength(1);
|
||||
expect(queryStore.activeTabId).toBe(sidebarTabId);
|
||||
});
|
||||
|
||||
it("reuses a restored legacy MySQL tab when the same table is opened from the sidebar", async () => {
|
||||
mocks.connectionStore.getConfig.mockImplementation((connectionId: string) => ({ id: connectionId, db_type: "mysql" }));
|
||||
mocks.loadOpenTabsState.mockResolvedValue({
|
||||
tabs: [
|
||||
{
|
||||
id: "restored-users",
|
||||
title: "app.users",
|
||||
connectionId: "connection-1",
|
||||
database: "app",
|
||||
schema: "app",
|
||||
mode: "data",
|
||||
sql: "SELECT * FROM users",
|
||||
tableMeta: { schema: "app", tableName: "users", tableType: "TABLE", columns: [], primaryKeys: [] },
|
||||
},
|
||||
],
|
||||
activeTabId: "restored-users",
|
||||
});
|
||||
const { queryStore } = await setupNavigation();
|
||||
await queryStore.initOpenTabs({ validConnectionIds: ["connection-1"] });
|
||||
const { useSidebarDataOpenRuntime } = await import("@/composables/useSidebarDataOpenRuntime");
|
||||
const runtime = useSidebarDataOpenRuntime();
|
||||
|
||||
await runtime.openData({ id: "users", label: "users", type: "table", connectionId: "connection-1", database: "app", tableType: "TABLE" });
|
||||
|
||||
expect(queryStore.tabs).toHaveLength(1);
|
||||
expect(queryStore.activeTabId).toBe("restored-users");
|
||||
expect(queryStore.tabs[0]?.schema).toBeUndefined();
|
||||
});
|
||||
|
||||
it("creates a new target tab even when the same table was restored", async () => {
|
||||
mocks.loadOpenTabsState.mockResolvedValue({
|
||||
tabs: [
|
||||
|
||||
@@ -169,6 +169,17 @@ describe("useSidebarDataOpenRuntime", () => {
|
||||
expect(mocks.tabs).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("keeps different sidebar tables independent when reuse is enabled", async () => {
|
||||
mocks.reuseDataTab = true;
|
||||
const ordersNode = { ...tableNode, id: "table-orders", label: "orders" };
|
||||
|
||||
await useSidebarDataOpenRuntime().openData(tableNode);
|
||||
await useSidebarDataOpenRuntime().openData(ordersNode);
|
||||
|
||||
expect(mocks.tabs).toHaveLength(2);
|
||||
expect(mocks.tabs.map((tab) => tab.title)).toEqual(["users", "orders"]);
|
||||
});
|
||||
|
||||
it("creates a new HBase tab for the same table when reuse is disabled", async () => {
|
||||
mocks.databaseType = "hbase";
|
||||
|
||||
@@ -178,6 +189,16 @@ describe("useSidebarDataOpenRuntime", () => {
|
||||
expect(mocks.tabs).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("keeps different HBase tables independent when reuse is enabled", async () => {
|
||||
mocks.databaseType = "hbase";
|
||||
mocks.reuseDataTab = true;
|
||||
|
||||
await useSidebarDataOpenRuntime().openData(tableNode);
|
||||
await useSidebarDataOpenRuntime().openData({ ...tableNode, id: "table-orders", label: "orders" });
|
||||
|
||||
expect(mocks.tabs).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("starts cold-cache OceanBase metadata before the table query", async () => {
|
||||
await useSidebarDataOpenRuntime().openData(tableNode);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ export function useSidebarDataOpenRuntime() {
|
||||
async function openData(node: TreeNode, request?: SidebarDataOpenRequest, openMode: DataTabOpenMode = "default", options: { reuseScope?: DataTabReuseScope } = {}) {
|
||||
if (!(node.type === "table" || node.type === "view" || node.type === "materialized_view") || !hasNodeDatabaseContext(node)) return;
|
||||
const config = connectionStore.getConfig(node.connectionId);
|
||||
const reuseScope = options.reuseScope ?? (settingsStore.editorSettings.reuseDataTab ? "database" : "none");
|
||||
const reuseScope = options.reuseScope ?? (settingsStore.editorSettings.reuseDataTab ? "same-table" : "none");
|
||||
if (config?.db_type === "hbase") {
|
||||
await connectionStore.ensureConnected(node.connectionId);
|
||||
const tabId = queryStore.createTab(node.connectionId, node.database, node.label, "hbase", undefined, node.label, undefined, { forceNew: openMode === "new-tab" || reuseScope === "none" });
|
||||
|
||||
Reference in new issue
Block a user