mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-08-10 07:55:24 +02:00
Added flatArray model, changed navigation functions
This commit is contained in:
parent
aaf7e99782
commit
ba3139962e
8 changed files with 5364 additions and 5092 deletions
|
@ -31,6 +31,7 @@
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"nedb": "^1.8.0",
|
"nedb": "^1.8.0",
|
||||||
|
"node-cache": "^5.1.2",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"open-graph-scraper": "^4.9.0",
|
"open-graph-scraper": "^4.9.0",
|
||||||
"twig": "^1.15.4",
|
"twig": "^1.15.4",
|
||||||
|
|
|
@ -2,7 +2,8 @@ import Page, { PageData } from '../models/page';
|
||||||
import Alias from '../models/alias';
|
import Alias from '../models/alias';
|
||||||
import PagesOrder from './pagesOrder';
|
import PagesOrder from './pagesOrder';
|
||||||
import PageOrder from '../models/pageOrder';
|
import PageOrder from '../models/pageOrder';
|
||||||
import HttpException from "../exceptions/httpException";
|
import HttpException from '../exceptions/httpException';
|
||||||
|
import flatArray from '../models/flatArray';
|
||||||
|
|
||||||
type PageDataFields = keyof PageData;
|
type PageDataFields = keyof PageData;
|
||||||
|
|
||||||
|
@ -195,6 +196,7 @@ class Pages {
|
||||||
pagesAvailable[index] = null;
|
pagesAvailable[index] = null;
|
||||||
pagesAvailable = Pages.removeChildren(pagesAvailable, item._id);
|
pagesAvailable = Pages.removeChildren(pagesAvailable, item._id);
|
||||||
});
|
});
|
||||||
|
flatArray.generate();
|
||||||
|
|
||||||
return pagesAvailable;
|
return pagesAvailable;
|
||||||
}
|
}
|
||||||
|
@ -221,6 +223,7 @@ class Pages {
|
||||||
|
|
||||||
alias.save();
|
alias.save();
|
||||||
}
|
}
|
||||||
|
await flatArray.generate();
|
||||||
|
|
||||||
return insertedPage;
|
return insertedPage;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -264,6 +267,7 @@ class Pages {
|
||||||
Alias.markAsDeprecated(previousUri);
|
Alias.markAsDeprecated(previousUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await flatArray.generate();
|
||||||
|
|
||||||
return updatedPage;
|
return updatedPage;
|
||||||
}
|
}
|
||||||
|
@ -286,6 +290,7 @@ class Pages {
|
||||||
|
|
||||||
await alias.destroy();
|
await alias.destroy();
|
||||||
}
|
}
|
||||||
|
await flatArray.generate();
|
||||||
|
|
||||||
return page.destroy();
|
return page.destroy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import PageOrder from '../models/pageOrder';
|
import PageOrder from '../models/pageOrder';
|
||||||
import Page from '../models/page';
|
import Page from '../models/page';
|
||||||
|
import flatArray from '../models/flatArray';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class PagesOrder
|
* @class PagesOrder
|
||||||
|
@ -62,6 +63,7 @@ class PagesOrder {
|
||||||
|
|
||||||
order.push(childId);
|
order.push(childId);
|
||||||
await order.save();
|
await order.save();
|
||||||
|
await flatArray.generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,11 +78,13 @@ class PagesOrder {
|
||||||
|
|
||||||
oldParentOrder.remove(targetPageId);
|
oldParentOrder.remove(targetPageId);
|
||||||
await oldParentOrder.save();
|
await oldParentOrder.save();
|
||||||
|
await flatArray.generate();
|
||||||
|
|
||||||
const newParentOrder = await PageOrder.get(newParentId);
|
const newParentOrder = await PageOrder.get(newParentId);
|
||||||
|
|
||||||
newParentOrder.push(targetPageId);
|
newParentOrder.push(targetPageId);
|
||||||
await newParentOrder.save();
|
await newParentOrder.save();
|
||||||
|
await flatArray.generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,6 +129,7 @@ class PagesOrder {
|
||||||
pageOrder.order = Array.from(new Set([...pageOrder.order, ...unordered]));
|
pageOrder.order = Array.from(new Set([...pageOrder.order, ...unordered]));
|
||||||
pageOrder.putAbove(currentPageId, putAbovePageId);
|
pageOrder.putAbove(currentPageId, putAbovePageId);
|
||||||
await pageOrder.save();
|
await pageOrder.save();
|
||||||
|
await flatArray.generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,7 +143,8 @@ class PagesOrder {
|
||||||
throw new Error('Page with given id does not contain order');
|
throw new Error('Page with given id does not contain order');
|
||||||
}
|
}
|
||||||
|
|
||||||
return order.destroy();
|
await order.destroy();
|
||||||
|
await flatArray.generate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
158
src/backend/models/flatArray.ts
Normal file
158
src/backend/models/flatArray.ts
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
import Page from './page';
|
||||||
|
import PageOrder from './pageOrder';
|
||||||
|
import NodeCache from 'node-cache';
|
||||||
|
|
||||||
|
// Create cache for flat array
|
||||||
|
const cache = new NodeCache({ stdTTL: 120 });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} FlatArrayData
|
||||||
|
* @property {string} id - page id
|
||||||
|
* @property {string} parentId - page parent id
|
||||||
|
* @property {string} rootId - page root id
|
||||||
|
* @property {number} level - page level in sidebar
|
||||||
|
* @property {string} title - page title
|
||||||
|
* @property {string} uri - page uri
|
||||||
|
*/
|
||||||
|
export interface FlatArrayData {
|
||||||
|
id?: string;
|
||||||
|
parentId?: string;
|
||||||
|
rootId?: string;
|
||||||
|
level?: number;
|
||||||
|
title?: string;
|
||||||
|
uri?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class FlatArray
|
||||||
|
* @class FlatArray model
|
||||||
|
*/
|
||||||
|
class FlatArray {
|
||||||
|
/**
|
||||||
|
* Returns pages flat array
|
||||||
|
*
|
||||||
|
* @returns {Promise<Array<FlatArrayData>>}
|
||||||
|
*/
|
||||||
|
public static async get(): Promise<Array<FlatArrayData>> {
|
||||||
|
// Get flat array from cache
|
||||||
|
let arr = cache.get('flatArray') as Array<FlatArrayData>;
|
||||||
|
|
||||||
|
// Check is flat array consists in cache
|
||||||
|
if (!arr) {
|
||||||
|
arr = await this.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates flat array, saves it to cache, returns it
|
||||||
|
*
|
||||||
|
* @returns {Promise<Array<FlatArrayData>>}
|
||||||
|
*/
|
||||||
|
public static async generate(): Promise<Array<FlatArrayData>> {
|
||||||
|
const pages = await Page.getAll();
|
||||||
|
const pagesOrders = await PageOrder.getAll();
|
||||||
|
|
||||||
|
let arr = new Array<FlatArrayData>();
|
||||||
|
|
||||||
|
// 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('flatArray', arr);
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns previous page
|
||||||
|
*
|
||||||
|
* @param pageId - page id
|
||||||
|
* @returns {Promise<FlatArrayData | undefined>}
|
||||||
|
*/
|
||||||
|
public static async getPageBefore(pageId: string): Promise<FlatArrayData | 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<FlatArrayData | undefined>}
|
||||||
|
*/
|
||||||
|
public static async getPageAfter(pageId: string): Promise<FlatArrayData | 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<FlatArrayData>>}
|
||||||
|
*/
|
||||||
|
private static getChildrenFlatArray(pageId: string, level: number,
|
||||||
|
pages: Array<Page>, orders: Array<PageOrder>): Array<FlatArrayData> {
|
||||||
|
let arr: Array<FlatArrayData> = new Array<FlatArrayData>();
|
||||||
|
|
||||||
|
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 FlatArray;
|
|
@ -1,5 +1,4 @@
|
||||||
import database from '../utils/database/index';
|
import database from '../utils/database/index';
|
||||||
import Pages from '../controllers/pages';
|
|
||||||
|
|
||||||
const db = database['pagesOrder'];
|
const db = database['pagesOrder'];
|
||||||
|
|
||||||
|
@ -87,105 +86,6 @@ class PageOrder {
|
||||||
return new PageOrder(docs);
|
return new PageOrder(docs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns previous page for navigation
|
|
||||||
*
|
|
||||||
* @param {string} pageId - page's id
|
|
||||||
* @returns {Promise<string | null>} - previous page id
|
|
||||||
*/
|
|
||||||
public static async getPreviousNavigationPage(pageId: string): Promise<string> {
|
|
||||||
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<string | null>} - next page id
|
|
||||||
*/
|
|
||||||
public static async getNextNavigationPage(pageId: string): Promise<string> {
|
|
||||||
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
|
* Returns only child page's order
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,8 +3,7 @@ import Aliases from '../controllers/aliases';
|
||||||
import Pages from '../controllers/pages';
|
import Pages from '../controllers/pages';
|
||||||
import Alias from '../models/alias';
|
import Alias from '../models/alias';
|
||||||
import verifyToken from './middlewares/token';
|
import verifyToken from './middlewares/token';
|
||||||
import PageOrder from '../models/pageOrder';
|
import FlatArray from '../models/flatArray';
|
||||||
import Page from '../models/page';
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
@ -34,11 +33,8 @@ router.get('*', verifyToken, async (req: Request, res: Response) => {
|
||||||
|
|
||||||
const pageParent = await page.getParent();
|
const pageParent = await page.getParent();
|
||||||
|
|
||||||
const previousPageId = await PageOrder.getPreviousNavigationPage(alias.id);
|
const previousPage = await FlatArray.getPageBefore(alias.id);
|
||||||
const nextPageId = await PageOrder.getNextNavigationPage(alias.id);
|
const nextPage = await FlatArray.getPageAfter(alias.id);
|
||||||
|
|
||||||
const previousPage = await Page.get(previousPageId);
|
|
||||||
const nextPage = await Page.get(nextPageId);
|
|
||||||
|
|
||||||
res.render('pages/page', {
|
res.render('pages/page', {
|
||||||
page,
|
page,
|
||||||
|
|
|
@ -3,8 +3,7 @@ import Pages from '../controllers/pages';
|
||||||
import PagesOrder from '../controllers/pagesOrder';
|
import PagesOrder from '../controllers/pagesOrder';
|
||||||
import verifyToken from './middlewares/token';
|
import verifyToken from './middlewares/token';
|
||||||
import allowEdit from './middlewares/locals';
|
import allowEdit from './middlewares/locals';
|
||||||
import PageOrder from '../models/pageOrder';
|
import FlatArray from '../models/flatArray';
|
||||||
import Page from '../models/page';
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
@ -64,11 +63,8 @@ router.get('/page/:id', verifyToken, async (req: Request, res: Response, next: N
|
||||||
|
|
||||||
const pageParent = await page.parent;
|
const pageParent = await page.parent;
|
||||||
|
|
||||||
const previousPageId = await PageOrder.getPreviousNavigationPage(pageId);
|
const previousPage = await FlatArray.getPageBefore(pageId);
|
||||||
const nextPageId = await PageOrder.getNextNavigationPage(pageId);
|
const nextPage = await FlatArray.getPageAfter(pageId);
|
||||||
|
|
||||||
const previousPage = await Page.get(previousPageId);
|
|
||||||
const nextPage = await Page.get(nextPageId);
|
|
||||||
|
|
||||||
res.render('pages/page', {
|
res.render('pages/page', {
|
||||||
page,
|
page,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue