Skip to content

Commit

Permalink
Added page navigation (#209)
Browse files Browse the repository at this point in the history
* Added navigation on page

* Removed useless log, added docs to navigator component

* Fixed duplicated variables, some changes in navigation functions, changed pages.twig and navigator.twig

* Added flatArray model, changed navigation functions

* Replaced page footer style to page.pcss

* Fixed generating flat array, when pages remove

* Removed useless generating

* Renamed flatArray model to pagesFlatArray, updated descriptions, renamed generate to regenerate, removed hardcoded key name in cache

* Changed styles naming and added margin for navigation

* Added ability to change nesting in flat array, fixed BEM

* Updated nesting parameter, fixed BEM

* Changed navigator component by passing objects, removed navigator wrapper

* Style navigator renamed to navigator__item

* Update src/backend/models/pagesFlatArray.ts

Co-authored-by: Peter Savchenko <[email protected]>

* Renamed navigator__item to navigator_item

* Deleted wrappers from navigator buttons, removed page__footer

Co-authored-by: Peter Savchenko <[email protected]>
  • Loading branch information
slaveeks and neSpecc authored Aug 2, 2022
1 parent 213f9d8 commit 70f89f2
Show file tree
Hide file tree
Showing 15 changed files with 352 additions and 18 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"morgan": "^1.10.0",
"multer": "^1.4.2",
"nedb": "^1.8.0",
"node-cache": "^5.1.2",
"node-fetch": "^2.6.1",
"open-graph-scraper": "^4.9.0",
"twig": "^1.15.4",
Expand Down
10 changes: 8 additions & 2 deletions src/backend/controllers/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import Page, { PageData } from '../models/page';
import Alias from '../models/alias';
import PagesOrder from './pagesOrder';
import PageOrder from '../models/pageOrder';
import HttpException from "../exceptions/httpException";
import HttpException from '../exceptions/httpException';
import PagesFlatArray from '../models/pagesFlatArray';

type PageDataFields = keyof PageData;

Expand Down Expand Up @@ -195,6 +196,7 @@ class Pages {
pagesAvailable[index] = null;
pagesAvailable = Pages.removeChildren(pagesAvailable, item._id);
});
PagesFlatArray.regenerate();

return pagesAvailable;
}
Expand All @@ -221,6 +223,7 @@ class Pages {

alias.save();
}
await PagesFlatArray.regenerate();

return insertedPage;
} catch (e) {
Expand Down Expand Up @@ -264,6 +267,7 @@ class Pages {
Alias.markAsDeprecated(previousUri);
}
}
await PagesFlatArray.regenerate();

return updatedPage;
}
Expand All @@ -286,8 +290,10 @@ class Pages {

await alias.destroy();
}
const removedPage = page.destroy();
await PagesFlatArray.regenerate();

return page.destroy();
return removedPage;
}

/**
Expand Down
8 changes: 7 additions & 1 deletion src/backend/controllers/pagesOrder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PageOrder from '../models/pageOrder';
import Page from '../models/page';
import PagesFlatArray from '../models/pagesFlatArray';

/**
* @class PagesOrder
Expand Down Expand Up @@ -62,6 +63,7 @@ class PagesOrder {

order.push(childId);
await order.save();
await PagesFlatArray.regenerate();
}

/**
Expand All @@ -76,11 +78,13 @@ class PagesOrder {

oldParentOrder.remove(targetPageId);
await oldParentOrder.save();
await PagesFlatArray.regenerate();

const newParentOrder = await PageOrder.get(newParentId);

newParentOrder.push(targetPageId);
await newParentOrder.save();
await PagesFlatArray.regenerate();
}

/**
Expand Down Expand Up @@ -125,6 +129,7 @@ class PagesOrder {
pageOrder.order = Array.from(new Set([...pageOrder.order, ...unordered]));
pageOrder.putAbove(currentPageId, putAbovePageId);
await pageOrder.save();
await PagesFlatArray.regenerate();
}

/**
Expand All @@ -138,7 +143,8 @@ class PagesOrder {
throw new Error('Page with given id does not contain order');
}

return order.destroy();
await order.destroy();
await PagesFlatArray.regenerate();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/backend/models/pageOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,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;
}
Expand All @@ -204,7 +204,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;
}
Expand Down
182 changes: 182 additions & 0 deletions src/backend/models/pagesFlatArray.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import Page from './page';
import PageOrder from './pageOrder';
import NodeCache from 'node-cache';

// Create cache for flat array
const cache = new NodeCache({ stdTTL: 120 });

const cacheKey = 'pagesFlatArray';

/**
* Element for pagesFlatArray
*/
export interface PagesFlatArrayData {
/**
* Page id
*/
id: string;

/**
* Page parent id
*/
parentId?: string;

/**
* id of parent with parent id '0'
*/
rootId: string;

/**
* Page level in sidebar view
*/
level: number;

/**
* Page title
*/
title: string;

/**
* Page uri
*/
uri?: string;
}

/**
* @class PagesFlatArray model - flat array of pages, which are ordered like in sidebar
*/
class PagesFlatArray {
/**
* Returns pages flat array
*
* @param nestingLimit - number of flat array nesting, set null to dismiss the restriction, default nesting 2
* @returns {Promise<Array<PagesFlatArrayData>>}
*/
public static async get(nestingLimit: number | null = 2): Promise<Array<PagesFlatArrayData>> {
// Get flat array from cache
let arr = cache.get(cacheKey) as Array<PagesFlatArrayData>;

// Check is flat array consists in cache
if (!arr) {
arr = await this.regenerate();
}

if (!nestingLimit) {
return arr;
}

return arr.filter( (item) => item.level < nestingLimit );
}

/**
* Generates new flat array, saves it to cache, returns it
* Calls, when there is no pages flat array data in cache or when page or pageOrder data updates
*
* @returns {Promise<Array<PagesFlatArrayData>>}
*/
public static async regenerate(): Promise<Array<PagesFlatArrayData>> {
const pages = await Page.getAll();
const pagesOrders = await PageOrder.getAll();

let arr = new Array<PagesFlatArrayData>();

// Get root order
const rootOrder = pagesOrders.find( order => order.page == '0' );

// Check is root order is not empty
if (!rootOrder) {
return [];
}

for (const pageId of rootOrder.order) {
arr = arr.concat(this.getChildrenFlatArray(pageId, 0, pages,
pagesOrders));
}

// Save generated flat array to cache
cache.set(cacheKey, arr);

return arr;
}

/**
* Returns previous page
*
* @param pageId - page id
* @returns {Promise<PagesFlatArrayData | undefined>}
*/
public static async getPageBefore(pageId: string): Promise<PagesFlatArrayData | undefined> {
const arr = await this.get();

const pageIndex = arr.findIndex( (item) => item.id == pageId);

// Check if index is not the first
if (pageIndex && pageIndex > 0) {
// Return previous element from array
return arr[pageIndex - 1];
} else {
return;
}
}

/**
* Returns next page
*
* @param pageId - page id
* @returns {Promise<PagesFlatArrayData | undefined>}
*/
public static async getPageAfter(pageId: string): Promise<PagesFlatArrayData | undefined> {
const arr = await this.get();

const pageIndex = arr.findIndex( (item) => item.id == pageId );

// Check if index is not the last
if (pageIndex < arr.length -1) {
// Return next element from array
return arr[pageIndex + 1];
} else {
return;
}
}

/**
* Returns child pages array
*
* @param pageId - parent page id
* @param level - page level in sidebar
* @param pages - all pages
* @param orders - all page orders
* @returns {Promise<Array<PagesFlatArrayData>>}
*/
private static getChildrenFlatArray(pageId: string, level: number,
pages: Array<Page>, orders: Array<PageOrder>): Array<PagesFlatArrayData> {
let arr: Array<PagesFlatArrayData> = new Array<PagesFlatArrayData>();

const page = pages.find( item => item._id == pageId );

// Add element to child array
if (page) {
arr.push( {
id: page._id!,
level: level,
parentId: page._parent,
rootId: '0',
title: page.title!,
uri: page.uri,
} );
}

const order = orders.find(item => item.page == pageId);

if (order) {
for (const childPageId of order.order) {
arr = arr.concat(this.getChildrenFlatArray(childPageId, level + 1,
pages, orders));
}
}

return arr;
}
}

export default PagesFlatArray;
6 changes: 6 additions & 0 deletions src/backend/routes/aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Aliases from '../controllers/aliases';
import Pages from '../controllers/pages';
import Alias from '../models/alias';
import verifyToken from './middlewares/token';
import PagesFlatArray from '../models/pagesFlatArray';

const router = express.Router();

Expand Down Expand Up @@ -32,9 +33,14 @@ router.get('*', verifyToken, async (req: Request, res: Response) => {

const pageParent = await page.getParent();

const previousPage = await PagesFlatArray.getPageBefore(alias.id);
const nextPage = await PagesFlatArray.getPageAfter(alias.id);

res.render('pages/page', {
page,
pageParent,
previousPage,
nextPage,
config: req.app.locals.config,
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/backend/routes/api/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
6 changes: 6 additions & 0 deletions src/backend/routes/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Pages from '../controllers/pages';
import PagesOrder from '../controllers/pagesOrder';
import verifyToken from './middlewares/token';
import allowEdit from './middlewares/locals';
import PagesFlatArray from '../models/pagesFlatArray';

const router = express.Router();

Expand Down Expand Up @@ -62,10 +63,15 @@ router.get('/page/:id', verifyToken, async (req: Request, res: Response, next: N

const pageParent = await page.parent;

const previousPage = await PagesFlatArray.getPageBefore(pageId);
const nextPage = await PagesFlatArray.getPageAfter(pageId);

res.render('pages/page', {
page,
pageParent,
config: req.app.locals.config,
previousPage,
nextPage,
});
} catch (error) {
res.status(404);
Expand Down
Loading

0 comments on commit 70f89f2

Please sign in to comment.