feat: enhance connection and query store logic for improved tab management and persistence
This commit is contained in:
parent
684877f563
commit
45785fd11e
17
src/App.vue
17
src/App.vue
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue