diff --git a/src/controllers/pagesOrder.js b/src/controllers/pagesOrder.js index 2a55e17..1068bbf 100644 --- a/src/controllers/pagesOrder.js +++ b/src/controllers/pagesOrder.js @@ -23,6 +23,15 @@ class PagesOrder { return order; } + /** + * Returns all records about page's order + * + * @returns {Promise} + */ + static async getAll() { + return Model.getAll(); + } + /** * Pushes the child page to the parent's order list * diff --git a/src/models/pageOrder.js b/src/models/pageOrder.js index 91aaefa..0e08ad2 100644 --- a/src/models/pageOrder.js +++ b/src/models/pageOrder.js @@ -34,6 +34,19 @@ class PageOrder { return new PageOrder(data); } + /** + * Find all pages which match passed query object + * + * @param {Object} query + * @returns {Promise} + */ + static async getAll(query = {}) { + const docs = await db.find(query); + + return Promise.all(docs.map(doc => new PageOrder(doc))); + } + + /** * @constructor * diff --git a/src/routes/middlewares/pages.js b/src/routes/middlewares/pages.js index 6e8ead8..ad190ad 100644 --- a/src/routes/middlewares/pages.js +++ b/src/routes/middlewares/pages.js @@ -4,44 +4,48 @@ const asyncMiddleware = require('../../utils/asyncMiddleware'); /** * Process one-level pages list to parent-children list - * @param {string[]} pages - list of all available pages + * + * @param {string} parentPageId - parent page id + * @param {Page[]} pages - list of all available pages + * @param {PagesOrder[]} pagesOrder - list of pages order * @param {number} level * @param {number} currentLevel * * @return {Page[]} */ -async function createMenuTree(pages, level = 1, currentLevel = 1) { - return await Promise.all(pages.map(async pageId => { - const parent = await Pages.get(pageId); +function createMenuTree(parentPageId, pages, pagesOrder, level = 1, currentLevel = 1) { + let childrenOrder = pagesOrder.find(order => order.data.page === parentPageId); - /** - * By default we accept that deepestChildren is empty Array - * @type {Array} - */ - let deepestChildren = []; + /** + * branch is a page children in tree + * if we got some children order on parents tree, then we push found pages in order sequence + * otherwise just find all pages includes parent tree + */ + let branch = []; + if (childrenOrder) { + branch = childrenOrder.order.map( pageId => { + return pages.find( page => page._id === pageId); + }); + } else { + branch = pages.filter( page => page._parent === parentPageId); + } - /** - * Here we try to check parent's children order - * If we got something, pluck to found Page deeper and get its children order - */ - try { - /** - * Go deeper until we didn't get the deepest level - * On each 'currentLevel' create new Menu Tree with ordered Page ids - */ - if (currentLevel !== level) { - const children = await PagesOrder.get(pageId); - deepestChildren = await createMenuTree(children.order, level, currentLevel + 1) - } - } catch (e) {} + /** + * stop recursion when we got the passed max level + */ + if (currentLevel === level + 1) { + return []; + } - /** - * Assign parent's children with found Menu Tree - */ + /** + * Each parents children can have subbranches + */ + return branch.filter(page => page && page._id).map( page => { return Object.assign({ - children: deepestChildren - }, parent.data); - })); + children: createMenuTree(page._id, pages, pagesOrder, level, currentLevel + 1) + }, page.data); + }); + } /** @@ -57,8 +61,9 @@ module.exports = asyncMiddleware(async function (req, res, next) { */ const parentIdOfRootPages = '0'; try { - const rootPages = await PagesOrder.get(parentIdOfRootPages); - res.locals.menu = await createMenuTree(rootPages.order, 2); + const pages = await Pages.getAll(); + const pagesOrder = await PagesOrder.getAll(); + res.locals.menu = createMenuTree(parentIdOfRootPages, pages, pagesOrder, 2); } catch (error) { console.log('Can not load menu:', error); }