feat: enhance connection and query store logic for improved tab management and persistence

This commit is contained in:
t8y2 2026-05-05 11:11:08 +08:00
parent 684877f563
commit 45785fd11e
3 changed files with 80 additions and 6 deletions

View File

@ -202,12 +202,27 @@ function handleKeydown(e: KeyboardEvent) {
}
function initApp() {
connectionStore.initFromDisk().catch((e: any) => {
connectionStore.initFromDisk().then(() => {
reconnectRestoredTabs();
}).catch((e: any) => {
toast(t("connection.loadFailed", { message: e?.message || String(e) }), 5000);
});
settingsStore.initAiConfig();
}
async function reconnectRestoredTabs() {
const connectionIds = new Set(queryStore.tabs.map(t => t.connectionId).filter(Boolean));
for (const id of connectionIds) {
try {
await connectionStore.ensureConnected(id);
} catch {}
}
const tab = queryStore.tabs.find(t => t.id === queryStore.activeTabId);
if (tab && tab.mode === "data" && tab.tableMeta) {
queryStore.executeCurrentTab();
}
}
onMounted(async () => {
applyTheme();
window.addEventListener("keydown", handleKeydown, true);

View File

@ -1,5 +1,5 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import { ref, watch } from "vue";
import type { ColumnInfo, ConnectionConfig, SidebarLayout, TreeNode } from "@/types/database";
import { orderPinnedFirst } from "@/lib/pinnedItems";
import {
@ -24,7 +24,14 @@ const PINNED_TREE_NODES_STORAGE_KEY = "dbx-pinned-tree-nodes";
export const useConnectionStore = defineStore("connection", () => {
const connections = ref<ConnectionConfig[]>([]);
const activeConnectionId = ref<string | null>(null);
const isDesktop = isTauriRuntime();
const activeConnectionId = ref<string | null>(!isDesktop ? localStorage.getItem("dbx-active-connection") : null);
watch(activeConnectionId, (id) => {
if (isDesktop) return;
if (id) localStorage.setItem("dbx-active-connection", id);
else localStorage.removeItem("dbx-active-connection");
});
const treeNodes = ref<TreeNode[]>([]);
const pinnedTreeNodeIds = ref<Set<string>>(loadPinnedTreeNodeIds());
const connectedIds = ref<Set<string>>(new Set());

View File

@ -1,5 +1,5 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import { ref, watch } from "vue";
import type { DatabaseType, QueryTab } from "@/types/database";
import { orderPinnedFirst } from "@/lib/pinnedItems";
import { canCancelQueryExecution } from "@/lib/queryExecutionState";
@ -7,11 +7,63 @@ import { closeAllTabsState, closeOtherTabsState } from "@/lib/tabCloseActions";
import { buildExplainSql, parseExplainResult } from "@/lib/explainPlan";
import * as api from "@/lib/api";
import { isTauriRuntime } from "@/lib/tauriRuntime";
interface SavedTab {
id: string;
title: string;
connectionId: string;
database: string;
sql: string;
pinned?: boolean;
mode: "data" | "query" | "redis" | "mongo";
tableMeta?: QueryTab["tableMeta"];
}
const STORAGE_KEY = "dbx-open-tabs";
const ACTIVE_TAB_KEY = "dbx-active-tab";
const isDesktop = isTauriRuntime();
function saveTabs(tabs: QueryTab[], activeTabId: string | null) {
if (isDesktop) return;
try {
const saved: SavedTab[] = tabs.map(t => ({
id: t.id, title: t.title, connectionId: t.connectionId,
database: t.database, sql: t.sql, pinned: t.pinned,
mode: t.mode, tableMeta: t.tableMeta,
}));
localStorage.setItem(STORAGE_KEY, JSON.stringify(saved));
localStorage.setItem(ACTIVE_TAB_KEY, activeTabId || "");
} catch {}
}
function loadSavedTabs(): { tabs: QueryTab[]; activeTabId: string | null } {
if (isDesktop) return { tabs: [], activeTabId: null };
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return { tabs: [], activeTabId: null };
const saved: SavedTab[] = JSON.parse(raw);
const tabs: QueryTab[] = saved.map(s => ({
...s,
isExecuting: false,
isCancelling: false,
isExplaining: false,
}));
const activeTabId = localStorage.getItem(ACTIVE_TAB_KEY) || null;
return { tabs, activeTabId: tabs.some(t => t.id === activeTabId) ? activeTabId : tabs[0]?.id || null };
} catch {
return { tabs: [], activeTabId: null };
}
}
export const useQueryStore = defineStore("query", () => {
const tabs = ref<QueryTab[]>([]);
const activeTabId = ref<string | null>(null);
const restored = loadSavedTabs();
const tabs = ref<QueryTab[]>(restored.tabs);
const activeTabId = ref<string | null>(restored.activeTabId);
const MAX_CACHED_RESULTS = 10;
watch([tabs, activeTabId], () => saveTabs(tabs.value, activeTabId.value), { deep: true });
function findTabByTitle(connectionId: string, database: string, title: string) {
return tabs.value.find((t) => t.connectionId === connectionId && t.database === database && t.title === title);
}