mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-07-19 05:09:41 +02:00
Order child pages (#21)
* save ordering pages * move to another collection * requested changes. Code improvements * add margin * unit tests * fix * requested changes * recursive method: create menu tree * update comments * fix bug * requested changes * move const * fix error message on catch * add migration * rewrite to splices * move methods * testing put above method * linter fix
This commit is contained in:
parent
dbfc594e66
commit
d61818761e
20 changed files with 1069 additions and 2563 deletions
|
@ -17,6 +17,7 @@
|
||||||
"codex.editor.header": "^2.0.5",
|
"codex.editor.header": "^2.0.5",
|
||||||
"cookie-parser": "~1.4.3",
|
"cookie-parser": "~1.4.3",
|
||||||
"debug": "~4.1.0",
|
"debug": "~4.1.0",
|
||||||
|
"eslint-plugin-standard": "^4.0.0",
|
||||||
"express": "~4.16.0",
|
"express": "~4.16.0",
|
||||||
"http-errors": "~1.7.1",
|
"http-errors": "~1.7.1",
|
||||||
"module-dispatcher": "^1.0.2",
|
"module-dispatcher": "^1.0.2",
|
||||||
|
@ -48,6 +49,8 @@
|
||||||
"eslint": "^5.3.0",
|
"eslint": "^5.3.0",
|
||||||
"eslint-config-codex": "github:codex-team/eslint-config",
|
"eslint-config-codex": "github:codex-team/eslint-config",
|
||||||
"eslint-plugin-chai-friendly": "^0.4.1",
|
"eslint-plugin-chai-friendly": "^0.4.1",
|
||||||
|
"eslint-plugin-import": "^2.14.0",
|
||||||
|
"eslint-plugin-node": "^8.0.1",
|
||||||
"highlight.js": "^9.13.1",
|
"highlight.js": "^9.13.1",
|
||||||
"husky": "^1.1.2",
|
"husky": "^1.1.2",
|
||||||
"mini-css-extract-plugin": "^0.4.3",
|
"mini-css-extract-plugin": "^0.4.3",
|
||||||
|
|
2
public/dist/code-styling.bundle.js
vendored
2
public/dist/code-styling.bundle.js
vendored
File diff suppressed because one or more lines are too long
2161
public/dist/editor.bundle.js
vendored
2161
public/dist/editor.bundle.js
vendored
File diff suppressed because one or more lines are too long
4
public/dist/main.bundle.js
vendored
4
public/dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/main.css
vendored
2
public/dist/main.css
vendored
File diff suppressed because one or more lines are too long
|
@ -138,7 +138,6 @@ class Pages {
|
||||||
}
|
}
|
||||||
|
|
||||||
page.data = data;
|
page.data = data;
|
||||||
|
|
||||||
return page.save();
|
return page.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
95
src/controllers/pagesOrder.js
Normal file
95
src/controllers/pagesOrder.js
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
const Model = require('../models/pageOrder');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class PagesOrder
|
||||||
|
* @classdesc PagesOrder controller
|
||||||
|
*
|
||||||
|
* Manipulates with Pages: changes the order, deletes, updates and so on...
|
||||||
|
*/
|
||||||
|
class PagesOrder {
|
||||||
|
/**
|
||||||
|
* Returns Page's order
|
||||||
|
*
|
||||||
|
* @param {string} parentId - of which page we want to get children order
|
||||||
|
* @returns {Promise<PageOrder>}
|
||||||
|
*/
|
||||||
|
static async get(parentId) {
|
||||||
|
const order = await Model.get(parentId);
|
||||||
|
|
||||||
|
if (!order._id) {
|
||||||
|
throw new Error('Page with given id does not contain order');
|
||||||
|
}
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes the child page to the parent's order list
|
||||||
|
*
|
||||||
|
* @param {string} parentId - parent page's id
|
||||||
|
* @param {string} childId - new page pushed to the order
|
||||||
|
*/
|
||||||
|
static async push(parentId, childId) {
|
||||||
|
const order = await Model.get(parentId);
|
||||||
|
|
||||||
|
order.push(childId);
|
||||||
|
await order.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move one page to another Page's order
|
||||||
|
*
|
||||||
|
* @param {string} oldParentId - old parent page's id
|
||||||
|
* @param {string} newParentId - new parent page's id
|
||||||
|
* @param {string} targetPageId - page's id which is changing the parent page
|
||||||
|
*/
|
||||||
|
static async move(oldParentId, newParentId, targetPageId) {
|
||||||
|
const oldParentOrder = await Model.get(oldParentId);
|
||||||
|
|
||||||
|
oldParentOrder.remove(targetPageId);
|
||||||
|
await oldParentOrder.save();
|
||||||
|
|
||||||
|
const newParentOrder = await Model.get(newParentId);
|
||||||
|
|
||||||
|
newParentOrder.push(targetPageId);
|
||||||
|
await newParentOrder.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns new array with ordered pages
|
||||||
|
*
|
||||||
|
* @param {Page[]} pages - list of all available pages
|
||||||
|
* @param {string} currentPageId - page's id around which we are ordering
|
||||||
|
* @param {string} parentPageId - parent page's id that contains page above
|
||||||
|
* @param {Boolean} ignoreSelf - should we ignore current page in list or not
|
||||||
|
* @return {Page[]}
|
||||||
|
*/
|
||||||
|
static async getOrderedChildren(pages, currentPageId, parentPageId, ignoreSelf = false) {
|
||||||
|
const children = await PagesOrder.get(parentPageId);
|
||||||
|
const result = [];
|
||||||
|
|
||||||
|
children.order.forEach(pageId => {
|
||||||
|
pages.forEach(page => {
|
||||||
|
if (page._id === pageId && (pageId !== currentPageId || !ignoreSelf)) {
|
||||||
|
result.push(page);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} currentPageId - page's id that changes the order
|
||||||
|
* @param {string} parentPageId - parent page's id that contains both two pages
|
||||||
|
* @param {string} putAbovePageId - page's id above which we put the target page
|
||||||
|
*/
|
||||||
|
static async update(currentPageId, parentPageId, putAbovePageId) {
|
||||||
|
const pageOrder = await Model.get(parentPageId);
|
||||||
|
|
||||||
|
pageOrder.putAbove(currentPageId, putAbovePageId);
|
||||||
|
await pageOrder.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = PagesOrder;
|
|
@ -27,7 +27,8 @@ export default class Writing {
|
||||||
this.nodes = {
|
this.nodes = {
|
||||||
editorWrapper: null,
|
editorWrapper: null,
|
||||||
saveButton: null,
|
saveButton: null,
|
||||||
parentIdSelector: null
|
parentIdSelector: null,
|
||||||
|
putAboveIdSelector: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ export default class Writing {
|
||||||
this.saveButtonClicked();
|
this.saveButtonClicked();
|
||||||
});
|
});
|
||||||
this.nodes.parentIdSelector = moduleEl.querySelector('[name="parent"]');
|
this.nodes.parentIdSelector = moduleEl.querySelector('[name="parent"]');
|
||||||
|
this.nodes.putAboveIdSelector = moduleEl.querySelector('[name="above"]');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,8 +91,15 @@ export default class Writing {
|
||||||
throw new Error('Entry should start with Header');
|
throw new Error('Entry should start with Header');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** get ordering selector value */
|
||||||
|
let putAbovePageId = null;
|
||||||
|
if (this.nodes.putAboveIdSelector) {
|
||||||
|
putAbovePageId = this.nodes.putAboveIdSelector.value;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
parent: this.nodes.parentIdSelector.value,
|
parent: this.nodes.parentIdSelector.value,
|
||||||
|
putAbovePageId: putAbovePageId,
|
||||||
body: editorData
|
body: editorData
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,9 @@
|
||||||
&__left {
|
&__left {
|
||||||
margin: auto 0;
|
margin: auto 0;
|
||||||
color: var(--color-text-second);
|
color: var(--color-text-second);
|
||||||
|
|
||||||
|
& span {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ const {pages: db} = require('../utils/database/index');
|
||||||
* @property {string} title - page title
|
* @property {string} title - page title
|
||||||
* @property {*} body - page body
|
* @property {*} body - page body
|
||||||
* @property {string} parent - id of parent page
|
* @property {string} parent - id of parent page
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
156
src/models/pageOrder.js
Normal file
156
src/models/pageOrder.js
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
const {pagesOrder: db} = require('../utils/database/index');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} PageOrderData
|
||||||
|
* @property {string} _id - row unique id
|
||||||
|
* @property {string} page - page id
|
||||||
|
* @property {Array<string>} order - list of ordered pages
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class PageOrder
|
||||||
|
* @classdesc PageOrder
|
||||||
|
*
|
||||||
|
* Creates order for Pages with children
|
||||||
|
*/
|
||||||
|
class PageOrder {
|
||||||
|
/**
|
||||||
|
* Returns current Page's children order
|
||||||
|
*
|
||||||
|
* @param {string} pageId - page's id
|
||||||
|
*/
|
||||||
|
static async get(pageId) {
|
||||||
|
const order = await db.findOne({page: pageId});
|
||||||
|
|
||||||
|
let data = {};
|
||||||
|
|
||||||
|
if (!order) {
|
||||||
|
data.page = pageId;
|
||||||
|
} else {
|
||||||
|
data = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PageOrder(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
*
|
||||||
|
* @param {PageOrderData} data
|
||||||
|
*/
|
||||||
|
constructor(data = {}) {
|
||||||
|
if (data === null) {
|
||||||
|
data = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data._id) {
|
||||||
|
this._id = data._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor data setter
|
||||||
|
* @param {PageOrderData} pageOrderData
|
||||||
|
*/
|
||||||
|
set data(pageOrderData) {
|
||||||
|
this._page = pageOrderData.page || 0;
|
||||||
|
this._order = pageOrderData.order || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return Page Children order
|
||||||
|
* @returns {PageOrderData}
|
||||||
|
*/
|
||||||
|
get data() {
|
||||||
|
return {
|
||||||
|
_id: this._id,
|
||||||
|
page: '' + this._page,
|
||||||
|
order: this._order
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes page id to the orders array
|
||||||
|
*
|
||||||
|
* @param {string} pageId - page's id
|
||||||
|
*/
|
||||||
|
push(pageId) {
|
||||||
|
if (typeof pageId === 'string') {
|
||||||
|
this._order.push(pageId);
|
||||||
|
} else {
|
||||||
|
throw new Error('given id is not string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes page id from orders array
|
||||||
|
*
|
||||||
|
* @param {string} pageId - page's id
|
||||||
|
*/
|
||||||
|
remove(pageId) {
|
||||||
|
const found = this._order.indexOf(pageId);
|
||||||
|
|
||||||
|
if (found >= 0) {
|
||||||
|
this._order.splice(found, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} currentPageId - page's id that changes the order
|
||||||
|
* @param {string} putAbovePageId - page's id above which we put the target page
|
||||||
|
*
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
putAbove(currentPageId, putAbovePageId) {
|
||||||
|
const found1 = this.order.indexOf(putAbovePageId);
|
||||||
|
const found2 = this.order.indexOf(currentPageId);
|
||||||
|
|
||||||
|
if (found1 === -1 || found2 === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const margin = found1 < found2 ? 1 : 0;
|
||||||
|
|
||||||
|
this.order.splice(found1, 0, currentPageId);
|
||||||
|
this.order.splice(found2 + margin, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ordered list
|
||||||
|
*
|
||||||
|
* @return {string[]}
|
||||||
|
*/
|
||||||
|
get order() {
|
||||||
|
return this._order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save or update page data in the database
|
||||||
|
*/
|
||||||
|
async save() {
|
||||||
|
if (!this._id) {
|
||||||
|
const insertedRow = await db.insert(this.data);
|
||||||
|
|
||||||
|
this._id = insertedRow._id;
|
||||||
|
} else {
|
||||||
|
await db.update({_id: this._id}, this.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove page data from the database
|
||||||
|
*/
|
||||||
|
async destroy() {
|
||||||
|
await db.remove({_id: this._id});
|
||||||
|
|
||||||
|
delete this._id;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = PageOrder;
|
|
@ -2,6 +2,7 @@ const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const multer = require('multer')();
|
const multer = require('multer')();
|
||||||
const Pages = require('../../controllers/pages');
|
const Pages = require('../../controllers/pages');
|
||||||
|
const PagesOrder = require('../../controllers/pagesOrder');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /page/:id
|
* GET /page/:id
|
||||||
|
@ -55,6 +56,9 @@ router.put('/page', multer.any(), async (req, res) => {
|
||||||
const {title, body, parent} = req.body;
|
const {title, body, parent} = req.body;
|
||||||
const page = await Pages.insert({title, body, parent});
|
const page = await Pages.insert({title, body, parent});
|
||||||
|
|
||||||
|
/** push to the orders array */
|
||||||
|
await PagesOrder.push(parent, page._id);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
result: page
|
result: page
|
||||||
|
@ -76,9 +80,18 @@ router.post('/page/:id', multer.any(), async (req, res) => {
|
||||||
const {id} = req.params;
|
const {id} = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const {title, body, parent} = req.body;
|
const {title, body, parent, putAbovePageId} = req.body;
|
||||||
const page = await Pages.update(id, {title, body, parent});
|
let page = await Pages.get(id);
|
||||||
|
|
||||||
|
if (page._parent !== parent) {
|
||||||
|
await PagesOrder.move(page._parent, parent, id);
|
||||||
|
} else {
|
||||||
|
if (putAbovePageId && putAbovePageId !== '0') {
|
||||||
|
await PagesOrder.update(page._id, page._parent, putAbovePageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
page = await Pages.update(id, {title, body, parent});
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
result: page
|
result: page
|
||||||
|
|
|
@ -1,17 +1,47 @@
|
||||||
const Pages = require('../../controllers/pages');
|
const Pages = require('../../controllers/pages');
|
||||||
|
const PagesOrder = require('../../controllers/pagesOrder');
|
||||||
const asyncMiddleware = require('../../utils/asyncMiddleware');
|
const asyncMiddleware = require('../../utils/asyncMiddleware');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process one-level pages list to parent-childrens list
|
* Process one-level pages list to parent-children list
|
||||||
* @param {Page[]} pages - list of all available pages
|
* @param {string[]} pages - list of all available pages
|
||||||
|
* @param {number} level
|
||||||
|
* @param {number} currentLevel
|
||||||
|
*
|
||||||
* @return {Page[]}
|
* @return {Page[]}
|
||||||
*/
|
*/
|
||||||
function createMenuTree(pages) {
|
async function createMenuTree(pages, level = 1, currentLevel = 1) {
|
||||||
return pages.filter(page => page._parent === '0').map(page => {
|
return await Promise.all(pages.map(async pageId => {
|
||||||
|
const parent = await Pages.get(pageId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default we accept that deepestChildren is empty Array
|
||||||
|
* @type {Array}
|
||||||
|
*/
|
||||||
|
let deepestChildren = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign parent's children with found Menu Tree
|
||||||
|
*/
|
||||||
return Object.assign({
|
return Object.assign({
|
||||||
children: pages.filter(child => child._parent === page._id).reverse()
|
children: deepestChildren
|
||||||
}, page.data);
|
}, parent.data);
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,13 +51,16 @@ function createMenuTree(pages) {
|
||||||
* @param next
|
* @param next
|
||||||
*/
|
*/
|
||||||
module.exports = asyncMiddleware(async function (req, res, next) {
|
module.exports = asyncMiddleware(async function (req, res, next) {
|
||||||
|
/**
|
||||||
|
* Pages without parent
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
const parentIdOfRootPages = '0';
|
||||||
try {
|
try {
|
||||||
const menu = await Pages.getAll();
|
const rootPages = await PagesOrder.get(parentIdOfRootPages);
|
||||||
|
res.locals.menu = await createMenuTree(rootPages.order, 2);
|
||||||
res.locals.menu = createMenuTree(menu);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('Can not load menu:', error);
|
console.log('Can not load menu:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const Pages = require('../controllers/pages');
|
const Pages = require('../controllers/pages');
|
||||||
|
const PagesOrder = require('../controllers/pagesOrder');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new page form
|
* Create new page form
|
||||||
|
@ -21,12 +22,14 @@ router.get('/page/edit/:id', async (req, res, next) => {
|
||||||
const pageId = req.params.id;
|
const pageId = req.params.id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let page = await Pages.get(pageId);
|
const page = await Pages.get(pageId);
|
||||||
let pagesAvailable = await Pages.getAllExceptChildrens(pageId);
|
const pagesAvailable = await Pages.getAllExceptChildrens(pageId);
|
||||||
|
const parentsChildrenOrdered = await PagesOrder.getOrderedChildren(pagesAvailable, pageId, page._parent, true);
|
||||||
|
|
||||||
res.render('pages/form', {
|
res.render('pages/form', {
|
||||||
pagesAvailable,
|
page,
|
||||||
page
|
parentsChildrenOrdered,
|
||||||
|
pagesAvailable
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(404);
|
res.status(404);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const pages = require('./pages');
|
const pages = require('./pages');
|
||||||
|
const pagesOrder = require('./pagesOrder');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Database
|
* @class Database
|
||||||
|
@ -142,5 +143,6 @@ class Database {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
class: Database,
|
class: Database,
|
||||||
pages: new Database(pages)
|
pages: new Database(pages),
|
||||||
|
pagesOrder: new Database(pagesOrder)
|
||||||
};
|
};
|
||||||
|
|
34
src/utils/database/pagesOrder.js
Normal file
34
src/utils/database/pagesOrder.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
const Datastore = require('nedb');
|
||||||
|
const config = require('../../../config');
|
||||||
|
|
||||||
|
const db = new Datastore({filename: `./${config.database}/pagesOrder.db`, autoload: true});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current DataStore preparation
|
||||||
|
* Add initial row for RootPage
|
||||||
|
*/
|
||||||
|
(async function() {
|
||||||
|
const parentIdOfRootPages = '0';
|
||||||
|
const cbk = (resolve, reject) => (err, doc) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(doc);
|
||||||
|
};
|
||||||
|
|
||||||
|
const order = await new Promise((resolve, reject) => {
|
||||||
|
db.findOne({page: parentIdOfRootPages}, cbk(resolve, reject));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!order) {
|
||||||
|
const initialData = {
|
||||||
|
page: '0',
|
||||||
|
order: []
|
||||||
|
};
|
||||||
|
await db.insert(initialData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
module.exports = db;
|
|
@ -14,21 +14,35 @@
|
||||||
</module-settings>
|
</module-settings>
|
||||||
<header class="writing-header">
|
<header class="writing-header">
|
||||||
<span class="writing-header__left">
|
<span class="writing-header__left">
|
||||||
|
<span>
|
||||||
New Page at the
|
New Page at the
|
||||||
{% set currentPageId = 0 %}
|
{% set currentPageId = 0 %}
|
||||||
{% if page is not empty %}
|
{% if page is not empty %}
|
||||||
{% set currentPageId = page._id %}
|
{% set currentPageId = page._id %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<select name="parent">
|
<select name="parent">
|
||||||
<option value="0">Root</option>
|
<option value="0">Root</option>
|
||||||
{% for _page in pagesAvailable %}
|
{% for _page in pagesAvailable %}
|
||||||
{% if _page._id != currentPageId %}
|
{% if _page._id != currentPageId %}
|
||||||
<option value="{{ _page._id }}" {{ page is not empty and page._parent == _page._id ? 'selected' : ''}}>
|
<option value="{{ _page._id }}" {{ page is not empty and page._parent == _page._id ? 'selected' : ''}}>
|
||||||
{{ _page.title }}
|
{{ _page.title }}
|
||||||
</option>
|
</option>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{% if parentsChildrenOrdered is not empty %}
|
||||||
|
<span>
|
||||||
|
Put Above
|
||||||
|
<select name="above">
|
||||||
|
<option value="0">—</option>
|
||||||
|
{% for _page in parentsChildrenOrdered %}
|
||||||
|
<option value="{{ _page._id }}">{{ _page.title }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
<span class="writing-header__save" name="js-submit">
|
<span class="writing-header__save" name="js-submit">
|
||||||
Save
|
Save
|
||||||
|
|
143
test/models/pageOrder.js
Normal file
143
test/models/pageOrder.js
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
const {expect} = require('chai');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const config = require('../../config');
|
||||||
|
const PageOrder = require('../../src/models/pageOrder');
|
||||||
|
const {pagesOrder} = require('../../src/utils/database');
|
||||||
|
|
||||||
|
describe('PageOrder model', () => {
|
||||||
|
after(() => {
|
||||||
|
const pathToDB = path.resolve(__dirname, '../../', config.database, './pages.db');
|
||||||
|
|
||||||
|
if (fs.existsSync(pathToDB)) {
|
||||||
|
fs.unlinkSync(pathToDB);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Empty Model', async () => {
|
||||||
|
let pageOrder = new PageOrder();
|
||||||
|
|
||||||
|
expect(pageOrder.data).to.be.a('object');
|
||||||
|
|
||||||
|
let {data} = pageOrder;
|
||||||
|
|
||||||
|
expect(data._id).to.be.undefined;
|
||||||
|
expect(data.page).to.be.to.equal('0');
|
||||||
|
expect(data.order).to.be.an('array').that.is.empty;
|
||||||
|
|
||||||
|
page = new PageOrder(null);
|
||||||
|
|
||||||
|
data = page.data;
|
||||||
|
|
||||||
|
expect(data._id).to.be.undefined;
|
||||||
|
expect(data.page).to.be.to.equal('0');
|
||||||
|
expect(data.order).to.be.an('array').that.is.empty;
|
||||||
|
|
||||||
|
const testData = {
|
||||||
|
_id: 'order_id',
|
||||||
|
page: 'page_id',
|
||||||
|
order: []
|
||||||
|
};
|
||||||
|
|
||||||
|
page = new PageOrder(testData);
|
||||||
|
data = page.data;
|
||||||
|
|
||||||
|
expect(data._id).to.equal(testData._id);
|
||||||
|
expect(data.page).to.equal(testData.page);
|
||||||
|
expect(data.order).to.be.an('array').that.is.empty;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Testing Model methods', async () => {
|
||||||
|
const testData = {
|
||||||
|
page: 'page_id',
|
||||||
|
order: ['1', '2']
|
||||||
|
};
|
||||||
|
const pageOrder = new PageOrder(testData);
|
||||||
|
let {data} = await pageOrder.save();
|
||||||
|
|
||||||
|
expect(data._id).not.be.undefined;
|
||||||
|
expect(data.page).to.equal(testData.page);
|
||||||
|
expect(data.order).to.deep.equals(testData.order);
|
||||||
|
|
||||||
|
const insertedPageOrder = await pagesOrder.findOne({_id: data._id});
|
||||||
|
expect(insertedPageOrder._id).to.equal(data._id);
|
||||||
|
expect(insertedPageOrder.page).to.equal(data.page);
|
||||||
|
expect(insertedPageOrder.order).to.deep.equal(data.order);
|
||||||
|
|
||||||
|
const updateData = {
|
||||||
|
page: 'page_id_2',
|
||||||
|
order: ['3']
|
||||||
|
};
|
||||||
|
|
||||||
|
pageOrder.data = updateData;
|
||||||
|
await pageOrder.save();
|
||||||
|
|
||||||
|
expect(pageOrder.data._id).to.equal(insertedPageOrder._id);
|
||||||
|
|
||||||
|
const updatedData = await pagesOrder.findOne({_id: insertedPageOrder._id});
|
||||||
|
|
||||||
|
expect(updatedData.page).to.equal(updateData.page);
|
||||||
|
expect(updatedData.order).to.deep.equal(updateData.order);
|
||||||
|
|
||||||
|
await pageOrder.destroy();
|
||||||
|
|
||||||
|
expect(pageOrder.data._id).to.be.undefined;
|
||||||
|
|
||||||
|
const removedPage = await pagesOrder.findOne({_id: updatedData._id});
|
||||||
|
|
||||||
|
expect(removedPage).to.be.null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Testing push and remove order methods', async () => {
|
||||||
|
const testData = {
|
||||||
|
page: 'page_id',
|
||||||
|
order: ['1', '2']
|
||||||
|
};
|
||||||
|
const pageOrder = new PageOrder(testData);
|
||||||
|
await pageOrder.save();
|
||||||
|
pageOrder.push('3');
|
||||||
|
expect(pageOrder.data.order).to.be.an('array').that.is.not.empty;
|
||||||
|
pageOrder.data.order.forEach((el) => {
|
||||||
|
expect(el).to.be.an('string')
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(pageOrder.data.order).to.deep.equals(['1', '2', '3']);
|
||||||
|
|
||||||
|
pageOrder.remove('2');
|
||||||
|
expect(pageOrder.data.order).to.deep.equals(['1', '3']);
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
pageOrder.push(3);
|
||||||
|
}).to.throw('given id is not string');
|
||||||
|
|
||||||
|
pageOrder.push('4');
|
||||||
|
pageOrder.push('5');
|
||||||
|
pageOrder.push('2');
|
||||||
|
|
||||||
|
pageOrder.putAbove('2', '3');
|
||||||
|
expect(pageOrder.data.order).to.deep.equals(['1', '2', '3', '4', '5']);
|
||||||
|
|
||||||
|
pageOrder.putAbove('2', '10');
|
||||||
|
expect(pageOrder.data.order).to.deep.equals(['1', '2', '3', '4', '5']);
|
||||||
|
await pageOrder.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Testing static methods', async () => {
|
||||||
|
const testData = {
|
||||||
|
page: 'page_id',
|
||||||
|
order: ['1', '2']
|
||||||
|
};
|
||||||
|
const pageOrder = new PageOrder(testData);
|
||||||
|
const insertedData = await pageOrder.save();
|
||||||
|
|
||||||
|
const insertedPageOrder = await PageOrder.get(insertedData.data.page);
|
||||||
|
expect(insertedPageOrder).to.instanceOf(PageOrder);
|
||||||
|
expect(insertedPageOrder.data._id).to.be.equal(insertedData.data._id);
|
||||||
|
|
||||||
|
const emptyInstance = await PageOrder.get(null);
|
||||||
|
expect(emptyInstance.data.page).to.be.equal('0');
|
||||||
|
expect(emptyInstance.data.order).to.be.an('array').that.is.empty;
|
||||||
|
|
||||||
|
await pageOrder.destroy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,5 +1,6 @@
|
||||||
const {app} = require('../../bin/www');
|
const {app} = require('../../bin/www');
|
||||||
const model = require('../../src/models/page');
|
const model = require('../../src/models/page');
|
||||||
|
const PageOrder = require('../../src/models/pageOrder');
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
@ -34,12 +35,12 @@ describe('Pages REST: ', () => {
|
||||||
text: 'Page header'
|
text: 'Page header'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
const parent = 0;
|
||||||
const res = await agent
|
const res = await agent
|
||||||
.put('/api/page')
|
.put('/api/page')
|
||||||
.send({body});
|
.send({body, parent});
|
||||||
|
|
||||||
expect(res).to.have.status(200);
|
expect(res).to.have.status(200);
|
||||||
expect(res).to.be.json;
|
expect(res).to.be.json;
|
||||||
|
@ -58,7 +59,11 @@ describe('Pages REST: ', () => {
|
||||||
expect(createdPage.title).to.equal(body.blocks[0].data.text);
|
expect(createdPage.title).to.equal(body.blocks[0].data.text);
|
||||||
expect(createdPage.body).to.deep.equal(body);
|
expect(createdPage.body).to.deep.equal(body);
|
||||||
|
|
||||||
createdPage.destroy();
|
const pageOrder = await PageOrder.get('' + (createdPage.data.parent || 0));
|
||||||
|
expect(pageOrder.order).to.be.an('array');
|
||||||
|
|
||||||
|
await createdPage.destroy();
|
||||||
|
await pageOrder.destroy()
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Page data validation on create', async () => {
|
it('Page data validation on create', async () => {
|
||||||
|
@ -106,12 +111,14 @@ describe('Pages REST: ', () => {
|
||||||
expect(success).to.be.true;
|
expect(success).to.be.true;
|
||||||
|
|
||||||
const foundPage = await model.get(_id);
|
const foundPage = await model.get(_id);
|
||||||
|
const pageOrder = await PageOrder.get('' + foundPage._parent);
|
||||||
|
|
||||||
expect(foundPage._id).to.equal(_id);
|
expect(foundPage._id).to.equal(_id);
|
||||||
expect(foundPage.title).to.equal(body.blocks[0].data.text);
|
expect(foundPage.title).to.equal(body.blocks[0].data.text);
|
||||||
expect(foundPage.body).to.deep.equal(body);
|
expect(foundPage.body).to.deep.equal(body);
|
||||||
|
|
||||||
foundPage.destroy();
|
await pageOrder.destroy();
|
||||||
|
await foundPage.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Finding page with not existing id', async () => {
|
it('Finding page with not existing id', async () => {
|
||||||
|
@ -175,6 +182,7 @@ describe('Pages REST: ', () => {
|
||||||
expect(result.body).to.deep.equal(updatedBody);
|
expect(result.body).to.deep.equal(updatedBody);
|
||||||
|
|
||||||
const updatedPage = await model.get(_id);
|
const updatedPage = await model.get(_id);
|
||||||
|
const pageOrder = await PageOrder.get('' + updatedPage._parent);
|
||||||
|
|
||||||
expect(updatedPage._id).to.equal(_id);
|
expect(updatedPage._id).to.equal(_id);
|
||||||
expect(updatedPage.title).not.equal(body.blocks[0].data.text);
|
expect(updatedPage.title).not.equal(body.blocks[0].data.text);
|
||||||
|
@ -182,7 +190,8 @@ describe('Pages REST: ', () => {
|
||||||
expect(updatedPage.body).not.equal(body);
|
expect(updatedPage.body).not.equal(body);
|
||||||
expect(updatedPage.body).to.deep.equal(updatedBody);
|
expect(updatedPage.body).to.deep.equal(updatedBody);
|
||||||
|
|
||||||
updatedPage.destroy();
|
await pageOrder.destroy();
|
||||||
|
await updatedPage.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Updating page with not existing id', async () => {
|
it('Updating page with not existing id', async () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue