fix(sidebar): align group selection with visible tree

This commit is contained in:
dadong authored and GitHub committed 2026-08-19 15:42:44 +08:00
1 parent c09dfbc813
commit a40dc02825
6 files changed
+297 -40

No files matched your search

@@ -449,6 +449,42 @@ export function connectionIdsInGroups(layout: SidebarLayout, groupIds: Iterable<
return connectionIds;
}
/** 收集单个分组下的所有连接 ID(含嵌套子分组),供分组勾选框级联选中连接使用。 */
export function connectionIdsUnderGroup(layout: SidebarLayout, groupId: string): string[] {
return connectionIdsInGroups(layout, [groupId]);
}
/** 收集分组自身及其下属所有含连接的子分组 ID,供级联选中时自动展开使用。 */
export function connectionBearingGroupIdsUnder(layout: SidebarLayout, groupId: string): string[] {
const entry = findGroupEntry(layout.order, groupId);
if (!entry) return [];
const ids: string[] = [];
const visit = (groupEntry: Extract<SidebarOrderEntry, { type: "group" }>): boolean => {
let hasConnection = false;
for (const child of entryChildren(groupEntry)) {
if (child.type === "connection") hasConnection = true;
else if (visit(child)) hasConnection = true;
}
if (hasConnection) ids.push(groupEntry.id);
return hasConnection;
};
visit(entry);
return ids;
}
/** 批量展开指定分组(collapsed 置为 false),无变化时返回原布局。 */
export function expandGroups(layout: SidebarLayout, groupIds: Iterable<string>): SidebarLayout {
const targets = new Set(groupIds);
if (!targets.size) return layout;
let changed = false;
const groups = layout.groups.map((group) => {
if (!targets.has(group.id) || !group.collapsed) return group;
changed = true;
return { ...group, collapsed: false };
});
return changed ? { ...layout, groups } : layout;
}
export function deleteGroups(layout: SidebarLayout, groupIds: Iterable<string>): SidebarLayout {
const targets = new Set(groupIds);
if (!targets.size) return layout;
@@ -4,6 +4,7 @@ import type { TreeNode } from "@/types/database";
export interface SidebarTreeContext {
getVisibleNodes: () => TreeNode[];
getVisibleNodeIndex: (id: string) => number;
getProjectedConnectionIds?: () => ReadonlySet<string> | null;
isSearchProjectionActive?: () => boolean;
getTreeLoadSearchOptions?: (node: TreeNode) => { searchFilter: string; allowGlobalSearchMismatch: true; expectedSidebarSearchQuery: string } | undefined;
setTableSearchQuery?: (parentNodeId: string, query: string, local: boolean) => void;