fix(mongodb): preserve collection queries and preview selection

Closes #8306
This commit is contained in:
t8y2 committed 2026-09-09 10:28:03 +08:00
1 parent 7835f4c309
commit a4e4fd0d2f
4 files changed
+55 -1

No files matched your search

@@ -5534,7 +5534,12 @@ function closeCellDetails() {
function toggleMongoJsonPreview() {
if (!canShowMongoJsonPreview.value) return;
showMongoJsonPreview.value = !showMongoJsonPreview.value;
if (showMongoJsonPreview.value) closeCellDetails();
if (showMongoJsonPreview.value) {
closeCellDetails();
if (!currentSelectedCellPosition() && displayItems.value.length > 0 && visibleColumnIndexes.value.length > 0) {
selectSingleCell(0, 0);
}
}
}
function closeMongoJsonPreview() {
@@ -5,6 +5,13 @@ const dataGridSource = readFileSync(new URL("../DataGrid.vue", import.meta.url),
const largeValueSource = readFileSync(new URL("../../../composables/useDataGridLargeValues.ts", import.meta.url), "utf8");
describe("DataGrid cell detail selection", () => {
it("selects the first available cell when opening Mongo JSON preview without a selection", () => {
const togglePreview = dataGridSource.match(/function toggleMongoJsonPreview[\s\S]*?\n\}/)?.[0];
expect(togglePreview).toContain("if (showMongoJsonPreview.value)");
expect(togglePreview).toContain("!currentSelectedCellPosition() && displayItems.value.length > 0 && visibleColumnIndexes.value.length > 0");
expect(togglePreview).toContain("selectSingleCell(0, 0)");
});
it("keeps Canvas hover state while the renderer swaps drawing surfaces", () => {
expect(dataGridSource).toContain("function isCanvasGridInteractionTarget(target: Node): boolean");
expect(dataGridSource).toContain("canvasOverlayRef.value?.contains(target) === true");
@@ -1533,6 +1533,13 @@ function openMongoTreeData(node: TreeNode) {
return;
}
if (node.type !== "mongo-collection") return;
const existing = queryStore.tabs.find(
(tab) => tab.mode === "mongo" && tab.connectionId === node.connectionId && tab.database === node.database && tab.tableMeta?.tableName === node.label,
);
if (existing) {
queryStore.switchTab(existing.id);
return;
}
const tab = queryStore.createTab(node.connectionId, node.database, tabTitle, "mongo");
queryStore.updateSql(tab, node.label);
queryStore.setTableMeta(tab, {
@@ -30,7 +30,11 @@ const connectionStore = {
};
const queryStore = {
tabs: [] as Array<{ id: string; mode: string; connectionId: string; database: string; title?: string; tableMeta?: { tableName: string } }>,
createTab: vi.fn(),
switchTab: vi.fn(),
updateSql: vi.fn(),
setTableMeta: vi.fn(),
openNacosAdmin: vi.fn(),
};
@@ -61,6 +65,7 @@ afterEach(() => {
connectionStore.sidebarSearchQuery = "";
connectionStore.activeConnectionId = null;
connectionStore.connectedIds.clear();
queryStore.tabs = [];
vi.clearAllMocks();
connectionStore.canUseLoadedTreeNodeToggle.mockReturnValue(true);
connectionStore.getConfig.mockReturnValue({ db_type: "mysql", name: "connection" });
@@ -68,6 +73,36 @@ afterEach(() => {
});
describe("SidebarTreeRuntimeHost expansion", () => {
it("reuses a Mongo collection tab by identity without replacing its state", async () => {
const collection: TreeNode = {
id: "mongo:app:orders",
label: "orders",
type: "mongo-collection",
connectionId: "mongo",
database: "app",
};
connectionStore.getConfig.mockReturnValue({ db_type: "mongodb", name: "connection" });
queryStore.tabs = [
{ id: "other-database", mode: "mongo", connectionId: "mongo", database: "other", tableMeta: { tableName: "orders" } },
{ id: "orders-tab", mode: "mongo", connectionId: "mongo", database: "app", title: "My renamed collection", tableMeta: { tableName: "orders" } },
];
const host = ref<InstanceType<typeof SidebarTreeRuntimeHost> | null>(null);
const app = createApp(defineComponent({ setup: () => () => h(SidebarTreeRuntimeHost, { ref: host, node: collection, depth: 0 }) }));
mountedApps.push(app);
const container = document.createElement("div");
document.body.append(container);
app.use(i18n);
app.mount(container);
host.value?.handleRowClick(collection, 1);
await nextTick();
expect(queryStore.switchTab).toHaveBeenCalledWith("orders-tab");
expect(queryStore.createTab).not.toHaveBeenCalled();
expect(queryStore.updateSql).not.toHaveBeenCalled();
expect(queryStore.setTableMeta).not.toHaveBeenCalled();
});
it("activates the owning connection when a cached node toggles locally", async () => {
const group: TreeNode = {
id: "mysql:basic:__tables",