@@ -87,21 +87,53 @@ class Pages {
8787 }
8888
8989 /**
90- * Group all pages by their parents
91- * If the pageId is passed, it excludes passed page from result pages
90+ * Depth in parent chain: 0 for root pages, +1 per ancestor below root (for select indent).
91+ */
92+ private static computePageDepth ( page : Page , pagesMap : Map < string , Page > ) : number {
93+ let depth = 0 ;
94+ let cur : Page | undefined = page ;
95+
96+ while ( cur ?. _parent && ! isEqualIds ( cur . _parent , '0' as EntityId ) ) {
97+ depth ++ ;
98+ cur = pagesMap . get ( cur . _parent . toString ( ) ) ;
99+ }
100+
101+ return depth ;
102+ }
103+
104+ /**
105+ * Ordered pages for the parent `<select>` with nesting depth (indent in the template).
92106 *
93- * @param {string } pageId - pageId to exclude from result pages
94- * @returns {Page[] }
107+ * @param excludePageId - when editing, exclude this page and its descendants (same as groupByParent)
95108 */
96- public static async groupByParent ( pageId = '' as EntityId ) : Promise < Page [ ] > {
109+ public static async getParentSelectOptions (
110+ excludePageId ?: EntityId
111+ ) : Promise < Array < { page : Page ; depth : number } > > {
112+ const { pages, pagesMap } = excludePageId
113+ ? await this . groupByParentWithMap ( excludePageId )
114+ : await this . groupByParentWithMap ( '' as EntityId ) ;
115+
116+ return pages . map ( ( page ) => ( {
117+ page,
118+ depth : Pages . computePageDepth ( page , pagesMap ) ,
119+ } ) ) ;
120+ }
121+
122+ /**
123+ * Same as {@link groupByParent} but returns the pages map from the same load (no second getPagesMap).
124+ */
125+ private static async groupByParentWithMap ( pageId = '' as EntityId ) : Promise < {
126+ pages : Page [ ] ;
127+ pagesMap : Map < string , Page > ;
128+ } > {
97129 const rootPageOrder = await PagesOrder . getRootPageOrder ( ) ; // get order of the root pages
98130 const childPageOrder = await PagesOrder . getChildPageOrder ( ) ; // get order of the all other pages
99131
100132 /**
101133 * If there is no root and child page order, then it returns an empty array
102134 */
103135 if ( ! rootPageOrder || ( ! rootPageOrder && childPageOrder . length <= 0 ) ) {
104- return [ ] ;
136+ return { pages : [ ] , pagesMap : new Map ( ) } ;
105137 }
106138
107139 const pagesMap = await this . getPagesMap ( ) ;
@@ -140,16 +172,31 @@ class Pages {
140172 * Otherwise just returns result itself
141173 */
142174 if ( pageId ) {
143- return this . removeChildren ( result , pageId ) . reduce ( ( prev , curr ) => {
175+ const pages = this . removeChildren ( result , pageId ) . reduce ( ( prev , curr ) => {
144176 if ( curr instanceof Page ) {
145177 prev . push ( curr ) ;
146178 }
147179
148180 return prev ;
149181 } , Array < Page > ( ) ) ;
150- } else {
151- return result ;
182+
183+ return { pages , pagesMap } ;
152184 }
185+
186+ return { pages : result , pagesMap } ;
187+ }
188+
189+ /**
190+ * Group all pages by their parents
191+ * If the pageId is passed, it excludes passed page from result pages
192+ *
193+ * @param {string } pageId - pageId to exclude from result pages
194+ * @returns {Page[] }
195+ */
196+ public static async groupByParent ( pageId = '' as EntityId ) : Promise < Page [ ] > {
197+ const { pages } = await this . groupByParentWithMap ( pageId ) ;
198+
199+ return pages ;
153200 }
154201
155202 /**
0 commit comments