fix(app-settings): persist and prune pinned tree nodes

This commit is contained in:
t8y2 committed 2026-05-22 14:28:40 +08:00
1 parent 0e189ba0cc
commit 1ef09e8975
12 files changed
+237 -2

No files matched your search

+2
View File
@@ -98,6 +98,8 @@ export const saveAiConfig = forward("saveAiConfig");
export const loadAiConfig = forward("loadAiConfig");
export const loadDesktopSettings = forward("loadDesktopSettings");
export const saveDesktopSettings = forward("saveDesktopSettings");
export const loadPinnedTreeNodeIds = forward("loadPinnedTreeNodeIds");
export const savePinnedTreeNodeIds = forward("savePinnedTreeNodeIds");
export const saveAiConversation = forward("saveAiConversation");
export const loadAiConversations = forward("loadAiConversations");
export const deleteAiConversation = forward("deleteAiConversation");
+8
View File
@@ -480,6 +480,14 @@ export async function saveDesktopSettings(_settings: DesktopSettings): Promise<v
return;
}
export async function loadPinnedTreeNodeIds(): Promise<string[]> {
return get("/api/app-settings/pinned-tree-node-ids");
}
export async function savePinnedTreeNodeIds(_ids: string[]): Promise<void> {
return post("/api/app-settings/pinned-tree-node-ids", { ids: _ids });
}
// --- AI Conversations ---
export async function saveAiConversation(conversation: AiConversation): Promise<void> {
+10
View File
@@ -0,0 +1,10 @@
export function prunePinnedTreeNodeIdsForConnection(ids: Set<string>, connectionId: string): Set<string> {
const next = new Set<string>();
const prefix = `${connectionId}:`;
for (const id of ids) {
if (id === connectionId) continue;
if (id.startsWith(prefix)) continue;
next.add(id);
}
return next;
}
+8
View File
@@ -130,6 +130,14 @@ export async function saveDesktopSettings(settings: DesktopSettings): Promise<vo
return invoke("save_desktop_settings", { settings });
}
export async function loadPinnedTreeNodeIds(): Promise<string[]> {
return invoke("load_pinned_tree_node_ids");
}
export async function savePinnedTreeNodeIds(ids: string[]): Promise<void> {
return invoke("save_pinned_tree_node_ids", { ids });
}
export async function listSystemFonts(): Promise<string[]> {
return invoke("list_system_fonts");
}
+27 -2
View File
@@ -38,6 +38,7 @@ import {
treeNodeSchemaCachePrefix,
} from "@/lib/treeNodeContext";
import { decodeSchemaTreeCache, encodeSchemaTreeCache } from "@/lib/schemaTreeCache";
import { prunePinnedTreeNodeIdsForConnection } from "@/lib/pinnedTreeNodeIds";
import { useSavedSqlStore } from "@/stores/savedSqlStore";
const PINNED_TREE_NODES_STORAGE_KEY = "dbx-pinned-tree-nodes";
@@ -71,7 +72,7 @@ export const useConnectionStore = defineStore("connection", () => {
else localStorage.removeItem("dbx-active-connection");
});
const treeNodes = ref<TreeNode[]>([]);
const pinnedTreeNodeIds = ref<Set<string>>(loadPinnedTreeNodeIds());
const pinnedTreeNodeIds = ref<Set<string>>(new Set());
const connectedIds = ref<Set<string>>(new Set());
const loadedTreeNodeChildrenIds = ref<Set<string>>(new Set());
const connectionErrors = ref<Record<string, string>>({});
@@ -247,7 +248,7 @@ export const useConnectionStore = defineStore("connection", () => {
};
}
function loadPinnedTreeNodeIds(): Set<string> {
function loadPinnedTreeNodeIdsFromLocalStorage(): Set<string> {
try {
if (typeof localStorage === "undefined") return new Set();
const saved = localStorage.getItem(PINNED_TREE_NODES_STORAGE_KEY);
@@ -258,7 +259,28 @@ export const useConnectionStore = defineStore("connection", () => {
}
}
async function loadPinnedTreeNodeIds(): Promise<Set<string>> {
if (!isDesktop) return loadPinnedTreeNodeIdsFromLocalStorage();
const ids = await api.loadPinnedTreeNodeIds().catch(() => []);
const valid = ids.filter((id) => typeof id === "string");
if (valid.length > 0) return new Set(valid);
// Migrate legacy localStorage values for existing desktop users.
const legacy = loadPinnedTreeNodeIdsFromLocalStorage();
if (legacy.size > 0) {
await api.savePinnedTreeNodeIds([...legacy]).catch(() => undefined);
if (typeof localStorage !== "undefined") {
localStorage.removeItem(PINNED_TREE_NODES_STORAGE_KEY);
}
}
return legacy;
}
function persistPinnedTreeNodeIds() {
if (isDesktop) {
void api.savePinnedTreeNodeIds([...pinnedTreeNodeIds.value]).catch(() => undefined);
return;
}
if (typeof localStorage === "undefined") return;
localStorage.setItem(PINNED_TREE_NODES_STORAGE_KEY, JSON.stringify([...pinnedTreeNodeIds.value]));
}
@@ -477,6 +499,8 @@ export const useConnectionStore = defineStore("connection", () => {
const nextConnections = connections.value.filter((c) => c.id !== id);
await persistConnections(nextConnections);
connections.value = nextConnections;
pinnedTreeNodeIds.value = prunePinnedTreeNodeIdsForConnection(pinnedTreeNodeIds.value, id);
persistPinnedTreeNodeIds();
clearConnectionError(id);
sidebarLayout.value = removeConnectionFromSidebarLayout(sidebarLayout.value, id);
rebuildTreeNodes();
@@ -1666,6 +1690,7 @@ export const useConnectionStore = defineStore("connection", () => {
}
async function initFromDisk() {
pinnedTreeNodeIds.value = await loadPinnedTreeNodeIds();
const saved = await api.loadConnections();
connections.value = saved.map(normalizeConnection);
const savedLayout = await api.loadSidebarLayout();