fix(sidebar): centralize tree action handling

This commit is contained in:
t8y2 committed 2026-07-14 18:10:52 +08:00
1 parent 7f096653db
commit ee85033068
28 files changed
+2705 -1032

No files matched your search

+21 -9
View File
@@ -2,7 +2,7 @@ import { defineStore } from "pinia";
import { uuid } from "@/lib/common/utils";
import { ref, computed, watch, markRaw } from "vue";
import type { ColumnInfo, CompletionAssistantCandidate, CompletionAssistantObjectKind, CompletionAssistantRequest, ConnectionConfig, CatalogInfo, ForeignKeyInfo, ObjectInfo, SchemaInfo, SidebarLayout, TableInfo, TreeNode, TunnelProfile, VectorCollectionMeta } from "@/types/database";
import { applyPinnedTreeNodeState, updatePinnedTreeNodeInPlace } from "@/lib/app/pinnedItems";
import { applyPinnedTreeNodeState, migrateLegacyPinnedTreeNodeIds, syncPinnedTreeNodeStateInPlace, treeNodePinKey } from "@/lib/app/pinnedItems";
import {
reconcileLayout,
buildTreeNodesFromLayout,
@@ -912,8 +912,9 @@ export const useConnectionStore = defineStore("connection", () => {
localStorage.setItem(PINNED_TREE_NODES_STORAGE_KEY, JSON.stringify([...pinnedTreeNodeIds.value]));
}
function isTreeNodePinned(id: string): boolean {
return pinnedTreeNodeIds.value.has(id);
function isTreeNodePinned(node: TreeNode | string): boolean {
if (typeof node === "string") return pinnedTreeNodeIds.value.has(node);
return pinnedTreeNodeIds.value.has(treeNodePinKey(node)) || pinnedTreeNodeIds.value.has(node.id);
}
function isConnectionUtilityNode(node: TreeNode): boolean {
@@ -972,7 +973,12 @@ export const useConnectionStore = defineStore("connection", () => {
return child;
});
}
parent.children = markRawLeafTreeNodes(applyPinnedTreeNodeState(children, pinnedTreeNodeIds.value));
const migratedPins = migrateLegacyPinnedTreeNodeIds(children, pinnedTreeNodeIds.value);
if (migratedPins.changed) {
pinnedTreeNodeIds.value = migratedPins.ids;
persistPinnedTreeNodeIds();
}
parent.children = markRawLeafTreeNodes(applyPinnedTreeNodeState(children, migratedPins.ids));
loadedTreeNodeChildrenIds.value.add(parent.id);
}
@@ -1584,15 +1590,21 @@ export const useConnectionStore = defineStore("connection", () => {
return null;
}
function toggleTreeNodePin(id: string) {
function toggleTreeNodePin(node: TreeNode) {
const pinKey = treeNodePinKey(node);
const next = new Set(pinnedTreeNodeIds.value);
if (next.has(id)) next.delete(id);
else next.add(id);
const wasPinned = next.has(pinKey) || next.has(node.id);
// Remove the legacy bare id as part of every toggle so old ambiguous pins
// cannot continue matching objects in a different database.
next.delete(node.id);
if (wasPinned) next.delete(pinKey);
else next.add(pinKey);
pinnedTreeNodeIds.value = next;
persistPinnedTreeNodeIds();
const scope = updatePinnedTreeNodeInPlace(treeNodes.value, id, next.has(id));
if (scope === "root") rebuildTreeNodes();
// Pinning is infrequent; synchronizing the loaded tree here also clears any
// stale flags created by legacy unscoped ids without rebuilding metadata.
syncPinnedTreeNodeStateInPlace(treeNodes.value, next);
}
async function addConnection(config: ConnectionConfig, targetGroupId?: string | null) {