feat(queryStore): 添加数据库打开状态跟踪功能 (#2251)

- 新增 isDatabaseOpen 方法,用于检查特定连接的数据库是否处于打开状态
- 在 TreeItem 组件中显示数据库打开指示器
- 添加 queryStore.database-open.spec.ts 测试文件,验证数据库打开状态的逻辑
This commit is contained in:
二丫讲梵
2026-06-30 22:43:38 +08:00
committed by GitHub
parent ad4a8e2647
commit 2e8d399dab
3 changed files with 47 additions and 0 deletions
@@ -3127,6 +3127,7 @@ const paddingLeft = computed(() => treeItemPaddingLeft(props.depth));
const isConnected = computed(() => props.node.type === "connection" && !!props.node.connectionId && connectionStore.connectedIds.has(props.node.connectionId));
const isConnectionReadonly = computed(() => props.node.type === "connection" && !!props.node.connectionId && (connectionStore.getConfig(props.node.connectionId)?.read_only ?? false));
const isOpenedDatabase = computed(() => isSidebarDatabaseOpened(props.node, connectionStore.isTreeNodeChildrenLoaded));
const showsDatabaseOpenIndicator = computed(() => props.node.type === "database" && (isOpenedDatabase.value || (!!props.node.connectionId && props.node.database != null && queryStore.isDatabaseOpen(props.node.connectionId, props.node.database))));
const canCloseDatabaseConnection = computed(() => canCloseSidebarDatabaseConnection(props.node, connectionStore.isTreeNodeChildrenLoaded));
const nodeIconClass = computed(() => {
const infoClass = getIconInfo(props.node)?.colorClass;
@@ -4135,6 +4136,7 @@ function treeItemMenuItems(): ContextMenuItem[] {
<span v-if="columnComment" class="sidebar-object-comment ml-auto max-w-[20%] shrink-0 truncate text-right">{{ columnComment }}</span>
<span v-if="tableComment" class="sidebar-object-comment ml-auto max-w-[20%] shrink-0 truncate text-right">{{ tableComment }}</span>
<span v-if="node.type === 'connection' && node.connectionId && connectionStore.connectedIds.has(node.connectionId)" class="w-1.5 h-1.5 rounded-full bg-green-500 shrink-0" />
<span v-if="showsDatabaseOpenIndicator" class="w-1.5 h-1.5 rounded-full bg-green-500 shrink-0" />
<Badge v-if="isConnectionReadonly" variant="secondary" class="h-4 px-1.5 text-[10px] gap-0.5"><Lock class="w-2.5 h-2.5" />{{ t("connection.readOnlyBadge") }}</Badge>
<ConnectionErrorIndicator v-if="node.type === 'connection'" :connection-id="node.connectionId" trigger-class="h-4 w-4" />
<Pin v-if="isPinned" class="w-3 h-3 shrink-0 text-primary fill-current" aria-hidden="true" />
@@ -0,0 +1,40 @@
import { createPinia, setActivePinia } from "pinia";
import { beforeEach, describe, expect, it, vi } from "vitest";
function installLocalStorage() {
const data = new Map<string, string>();
vi.stubGlobal("localStorage", {
getItem: vi.fn((key: string) => data.get(key) ?? null),
setItem: vi.fn((key: string, value: string) => data.set(key, value)),
removeItem: vi.fn((key: string) => data.delete(key)),
});
}
describe("queryStore database open state", () => {
beforeEach(() => {
vi.resetModules();
vi.unstubAllGlobals();
installLocalStorage();
setActivePinia(createPinia());
});
it("tracks whether a connection database has open tabs", async () => {
const { useQueryStore } = await import("@/stores/queryStore");
const store = useQueryStore();
const tabId = store.createTab("pg-1", "app", "query_1");
expect(store.isDatabaseOpen("pg-1", "app")).toBe(true);
expect(store.isDatabaseOpen("pg-1", "analytics")).toBe(false);
expect(store.isDatabaseOpen("pg-2", "app")).toBe(false);
store.updateDatabase(tabId, "analytics");
expect(store.isDatabaseOpen("pg-1", "app")).toBe(false);
expect(store.isDatabaseOpen("pg-1", "analytics")).toBe(true);
store.closeTab(tabId);
expect(store.isDatabaseOpen("pg-1", "analytics")).toBe(false);
});
});
+5
View File
@@ -984,6 +984,10 @@ export const useQueryStore = defineStore("query", () => {
releaseTabsWhere((tab) => tab.connectionId === connectionId && tab.database === database);
}
function isDatabaseOpen(connectionId: string, database: string) {
return tabs.value.some((tab) => tab.connectionId === connectionId && tab.database === database);
}
function updateSql(id: string, sql: string) {
const tab = tabs.value.find((t) => t.id === id);
if (tab) {
@@ -2484,6 +2488,7 @@ export const useQueryStore = defineStore("query", () => {
closeDatabaseTabs,
releaseConnectionTabs,
releaseDatabaseTabs,
isDatabaseOpen,
updateSql,
updateEditorViewport,
updateEditorSelection,