From 587062d4d1108953b59dfac9ecd0e03dda024dfe Mon Sep 17 00:00:00 2001 From: slaveeks Date: Fri, 1 Jul 2022 21:30:28 +0300 Subject: [PATCH] Added navigation on page --- src/backend/models/pageOrder.ts | 104 +++++++++++++++++- src/backend/routes/aliases.ts | 20 ++++ src/backend/routes/api/pages.ts | 4 +- src/backend/routes/pages.ts | 20 ++++ src/backend/views/components/navigator.twig | 21 ++++ src/backend/views/pages/page.twig | 15 ++- src/frontend/styles/components/navigator.pcss | 46 ++++++++ src/frontend/styles/main.pcss | 1 + src/frontend/styles/vars.pcss | 7 +- 9 files changed, 231 insertions(+), 7 deletions(-) create mode 100644 src/backend/views/components/navigator.twig create mode 100644 src/frontend/styles/components/navigator.pcss diff --git a/src/backend/models/pageOrder.ts b/src/backend/models/pageOrder.ts index 84c18b5..4d88905 100644 --- a/src/backend/models/pageOrder.ts +++ b/src/backend/models/pageOrder.ts @@ -1,4 +1,5 @@ import database from '../utils/database/index'; +import Pages from '../controllers/pages'; const db = database['pagesOrder']; @@ -86,6 +87,105 @@ class PageOrder { return new PageOrder(docs); } + /** + * Returns previous page for navigation + * + * @param {string} pageId - page's id + * @returns {Promise} - previous page id + */ + public static async getPreviousNavigationPage(pageId: string): Promise { + const page = await Pages.get(pageId); + + const pageParent = await page.getParent(); + + let previousPageId = null; + + // Check if page has a parent + if (pageParent._id) { + // Get order by parent + const order = await this.get(pageParent._id); + + // Get previous page + previousPageId = order.getSubPageBefore(pageId); + + // Check if previous page consists in parent order + if (!previousPageId) { + previousPageId = pageParent._id; + } + + return previousPageId; + } + + // Get order, which includes getting page, because it has no parent + const order = await this.getRootPageOrder(); + + // Get parent page before page, which was gotten + const parentPageBefore = order.getSubPageBefore(pageId); + + if (parentPageBefore) { + // Get previous parent page order + const newOrder = await this.get(parentPageBefore); + + // Check if order is empty + if (!newOrder._order || newOrder._order.length == 0) { + return parentPageBefore; + } + previousPageId = newOrder._order[newOrder._order.length - 1]; + } + + return previousPageId; + } + + /** + * Returns next page for navigation + * + * @param {string} pageId - page's id + * @returns {Promise} - next page id + */ + public static async getNextNavigationPage(pageId: string): Promise { + const page = await Pages.get(pageId); + const pageParent = await page.getParent(); + + let nextPageId; + + // Check if page has a parent + if (pageParent._id) { + let order = await this.get(pageParent._id); + + // Get next page by parent order + nextPageId = order.getSubPageAfter(pageId); + + // Check if next page consists in parent order + if (nextPageId) { + return nextPageId; + } + + // Get order, which includes parent + order = await this.getRootPageOrder(); + + nextPageId = order.getSubPageAfter(pageParent._id); + + return nextPageId; + } + + // Get order by page id + const childOrder = await this.get(pageId); + + // Check if order is empty + if (childOrder._order && childOrder._order.length > 0) { + nextPageId = childOrder._order[0]; + + return nextPageId; + } + + // Get order, which includes getting page, because it has no parent + const order = await this.getRootPageOrder(); + + nextPageId = order.getSubPageAfter(pageId); + + return nextPageId; + } + /** * Returns only child page's order * @@ -182,7 +282,7 @@ class PageOrder { * * @param {string} pageId - identity of page */ - public getPageBefore(pageId: string): string | null { + public getSubPageBefore(pageId: string): string | null { if (this.order === undefined) { return null; } @@ -204,7 +304,7 @@ class PageOrder { * * @param pageId - identity of page */ - public getPageAfter(pageId: string): string | null { + public getSubPageAfter(pageId: string): string | null { if (this.order === undefined) { return null; } diff --git a/src/backend/routes/aliases.ts b/src/backend/routes/aliases.ts index 1dc2195..b77a4aa 100644 --- a/src/backend/routes/aliases.ts +++ b/src/backend/routes/aliases.ts @@ -3,6 +3,8 @@ import Aliases from '../controllers/aliases'; import Pages from '../controllers/pages'; import Alias from '../models/alias'; import verifyToken from './middlewares/token'; +import PageOrder from '../models/pageOrder'; +import Page from '../models/page'; const router = express.Router(); @@ -32,9 +34,27 @@ router.get('*', verifyToken, async (req: Request, res: Response) => { const pageParent = await page.getParent(); + let previousPage; + + let nextPage; + + const previousPageId = await PageOrder.getPreviousNavigationPage(alias.id); + + const nextPageId = await PageOrder.getNextNavigationPage(alias.id); + + if (previousPageId){ + previousPage = await Page.get(previousPageId); + } + + if (nextPageId) { + nextPage = await Page.get(nextPageId); + } + res.render('pages/page', { page, pageParent, + previousPage, + nextPage, config: req.app.locals.config, }); } diff --git a/src/backend/routes/api/pages.ts b/src/backend/routes/api/pages.ts index ba240b7..7aef335 100644 --- a/src/backend/routes/api/pages.ts +++ b/src/backend/routes/api/pages.ts @@ -158,8 +158,8 @@ router.delete('/page/:id', async (req: Request, res: Response) => { } const parentPageOrder = await PagesOrder.get(page._parent); - const pageBeforeId = parentPageOrder.getPageBefore(page._id); - const pageAfterId = parentPageOrder.getPageAfter(page._id); + const pageBeforeId = parentPageOrder.getSubPageBefore(page._id); + const pageAfterId = parentPageOrder.getSubPageAfter(page._id); let pageToRedirect; diff --git a/src/backend/routes/pages.ts b/src/backend/routes/pages.ts index fe70f37..eedb10e 100644 --- a/src/backend/routes/pages.ts +++ b/src/backend/routes/pages.ts @@ -3,6 +3,8 @@ import Pages from '../controllers/pages'; import PagesOrder from '../controllers/pagesOrder'; import verifyToken from './middlewares/token'; import allowEdit from './middlewares/locals'; +import PageOrder from '../models/pageOrder'; +import Page from '../models/page'; const router = express.Router(); @@ -62,10 +64,28 @@ router.get('/page/:id', verifyToken, async (req: Request, res: Response, next: N const pageParent = await page.parent; + let previousPage; + + let nextPage; + + const previousPageId = await PageOrder.getPreviousNavigationPage(pageId); + + const nextPageId = await PageOrder.getNextNavigationPage(pageId); + + if (previousPageId) { + previousPage = await Page.get(previousPageId); + } + + if (nextPageId) { + nextPage = await Page.get(nextPageId); + } + res.render('pages/page', { page, pageParent, config: req.app.locals.config, + previousPage, + nextPage, }); } catch (error) { res.status(404); diff --git a/src/backend/views/components/navigator.twig b/src/backend/views/components/navigator.twig new file mode 100644 index 0000000..b5f998e --- /dev/null +++ b/src/backend/views/components/navigator.twig @@ -0,0 +1,21 @@ +{% set mainClass = 'navigator' %} + + +{% set tag = 'div' %} + +{% if url is not empty %} + {% set tag = 'a' %} +{% endif %} + +<{{tag}} + {{ name is not empty ? 'name="' ~ name ~ '"': '' }} +class="{{ mainClass }} {{ mainClass }}--{{ direction|default('previous') }} {{ class ?? '' }}" +{{ url is not empty ? 'href="' ~ url ~ '"' : '' }} +> +
+ {{ direction }} +
+
+ {{ label }} +
+ diff --git a/src/backend/views/pages/page.twig b/src/backend/views/pages/page.twig index e123c4d..53d13ab 100644 --- a/src/backend/views/pages/page.twig +++ b/src/backend/views/pages/page.twig @@ -23,6 +23,9 @@ {% include 'components/button.twig' with {label: 'Edit', icon: 'pencil', size: 'small', url: '/page/edit/' ~ page._id, class: 'page__header-button'} %} {% endif %} +

{{ page.title }}

@@ -39,7 +42,17 @@ {% endif %} {% endfor %} -