@@ -3,17 +3,26 @@ import Page from '../models/page.js';
33import PageOrder from '../models/pageOrder.js' ;
44import { isEqualIds } from '../database/index.js' ;
55
6+ /** Max sidebar nesting depth (root sections count as depth 1). */
7+ const MENU_MAX_DEPTH = 64 ;
8+
69/**
7- * Process one-level pages list to parent-children list
10+ * Build parent→children menu tree for the sidebar.
811 *
912 * @param parentPageId - parent page id
1013 * @param pages - list of all available pages
1114 * @param pagesOrder - list of pages order
12- * @param level - max level recursion
13- * @param currentLevel - current level of element
15+ * @param maxDepth - stop recursing deeper than this (default: MENU_MAX_DEPTH)
16+ * currentDepth - current depth from the tree root (1 = direct children of parentPageId)
1417 */
15- export function createMenuTree ( parentPageId : EntityId , pages : Page [ ] , pagesOrder : PageOrder [ ] , level = 1 , currentLevel = 1 ) : Page [ ] {
16- const childrenOrder = pagesOrder . find ( order => isEqualIds ( order . data . page , parentPageId ) ) ;
18+ export function createMenuTree (
19+ parentPageId : EntityId ,
20+ pages : Page [ ] ,
21+ pagesOrder : PageOrder [ ] ,
22+ maxDepth : number = MENU_MAX_DEPTH ,
23+ currentDepth : number = 1
24+ ) : Page [ ] {
25+ const childrenOrder = pagesOrder . find ( ( order ) => isEqualIds ( order . data . page , parentPageId ) ) ;
1726
1827 /**
1928 * branch is a page children in tree
@@ -24,26 +33,26 @@ export function createMenuTree(parentPageId: EntityId, pages: Page[], pagesOrder
2433
2534 if ( childrenOrder ) {
2635 ordered = childrenOrder . order . map ( ( pageId : EntityId ) => {
27- return pages . find ( page => isEqualIds ( page . _id , pageId ) ) ;
36+ return pages . find ( ( page ) => isEqualIds ( page . _id , pageId ) ) ;
2837 } ) ;
2938 }
3039
31- const unordered = pages . filter ( page => isEqualIds ( page . _parent , parentPageId ) ) ;
40+ const unordered = pages . filter ( ( page ) => isEqualIds ( page . _parent , parentPageId ) ) ;
3241 const branch = Array . from ( new Set ( [ ...ordered , ...unordered ] ) ) ;
3342
34- /**
35- * stop recursion when we got the passed max level
36- */
37- if ( currentLevel === level + 1 ) {
38- return [ ] ;
39- }
43+ const canRecurse = currentDepth < maxDepth ;
4044
4145 /**
4246 * Each parents children can have subbranches
4347 */
44- return branch . filter ( page => page && page . _id ) . map ( page => {
45- return Object . assign ( {
46- children : createMenuTree ( page . _id , pages , pagesOrder , level , currentLevel + 1 ) ,
47- } , page . data ) ;
48- } ) ;
48+ return branch
49+ . filter ( ( page ) => page && page . _id )
50+ . map ( ( page ) => {
51+ const subtree = canRecurse
52+ ? createMenuTree ( page . _id ! , pages , pagesOrder , maxDepth , currentDepth + 1 )
53+ : [ ] ;
54+
55+ /** `children` must win over anything stored on the page document */
56+ return { ...page . data , children : subtree } ;
57+ } ) ;
4958}
0 commit comments