Merge remote-tracking branch 'gitea/develop' into feat/page-templates

# Conflicts:
#	apps/server/src/integrations/throttle/throttle.module.ts
#	apps/server/src/integrations/throttle/throttler-names.ts
This commit is contained in:
claude_code
2026-06-20 20:18:42 +03:00
130 changed files with 9951 additions and 3095 deletions

View File

@@ -30,7 +30,14 @@ export function buildTree(pages: IPage[]): SpaceTreeNode[] {
};
});
// Defense-in-depth: a duplicate id in `pages` would push two references to the
// same node, producing a duplicate React key that crashes the sidebar render.
// Track ids we've already pushed and skip repeats so a stray duplicate from a
// realtime cache write can never break the tree.
const seen = new Set<string>();
pages.forEach((page) => {
if (seen.has(page.id)) return;
seen.add(page.id);
tree.push(pageMap[page.id]);
});
@@ -217,3 +224,33 @@ export function mergeRootTrees(
return sortPositionKeys(merged);
}
// Collect every node id in the tree (roots, branches, leaves). Used by
// collapseAll to clear the open-state map for all current-space nodes.
export function collectAllIds(nodes: SpaceTreeNode[]): string[] {
const ids: string[] = [];
const walk = (list: SpaceTreeNode[]) => {
for (const n of list) {
ids.push(n.id);
if (n.children?.length) walk(n.children);
}
};
walk(nodes);
return ids;
}
// Collect ids of branch nodes (nodes that have children). Used by expandAll to
// open every branch in the open-state map; leaves need no entry.
export function collectBranchIds(nodes: SpaceTreeNode[]): string[] {
const ids: string[] = [];
const walk = (list: SpaceTreeNode[]) => {
for (const n of list) {
if (n.children?.length) {
ids.push(n.id);
walk(n.children);
}
}
};
walk(nodes);
return ids;
}