From d92523723364b0695e04babc915b41f8c375ba8a Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 1 Jun 2021 16:04:43 +0200 Subject: [PATCH] Move pagination to common, add serialization, update BackendController --- src/{ => common}/Pagination.ts | 13 ++++++++++--- src/db/ModelFactory.ts | 2 +- src/db/ModelQuery.ts | 2 +- src/helpers/BackendController.ts | 15 ++++++++++----- test/{ => common}/Pagination.test.ts | 13 ++++++++++++- 5 files changed, 34 insertions(+), 11 deletions(-) rename src/{ => common}/Pagination.ts (86%) rename test/{ => common}/Pagination.test.ts (91%) diff --git a/src/Pagination.ts b/src/common/Pagination.ts similarity index 86% rename from src/Pagination.ts rename to src/common/Pagination.ts index e91368d..0f2e8ee 100644 --- a/src/Pagination.ts +++ b/src/common/Pagination.ts @@ -1,6 +1,9 @@ -import {WrappingError} from "./Utils.js"; +export class Pagination { + public static deserialize(str: string): Pagination { + const data = JSON.parse(str); + return new Pagination(data.page, data.perPage, data.totalCount); + } -export default class Pagination { public readonly page: number; public readonly perPage: number; public readonly totalCount: number; @@ -80,9 +83,13 @@ export default class Pagination { return pages; } + + public serialize(): string { + return JSON.stringify(this); + } } -export class PageNotFoundError extends WrappingError { +export class PageNotFoundError extends Error { public constructor( public readonly page: number, ) { diff --git a/src/db/ModelFactory.ts b/src/db/ModelFactory.ts index 9426d69..272129b 100644 --- a/src/db/ModelFactory.ts +++ b/src/db/ModelFactory.ts @@ -1,7 +1,7 @@ import {Request} from "express"; +import {PageNotFoundError} from "../common/Pagination.js"; import {NotFoundHttpError} from "../HttpError.js"; -import {PageNotFoundError} from "../Pagination.js"; import Model, {ModelType} from "./Model.js"; import ModelComponent from "./ModelComponent.js"; import ModelQuery, {ModelQueryResult, QueryFields} from "./ModelQuery.js"; diff --git a/src/db/ModelQuery.ts b/src/db/ModelQuery.ts index 14e5aeb..d571593 100644 --- a/src/db/ModelQuery.ts +++ b/src/db/ModelQuery.ts @@ -1,6 +1,6 @@ import {Connection} from "mysql"; -import Pagination from "../Pagination.js"; +import {Pagination} from "../common/Pagination.js"; import Model from "./Model.js"; import ModelFactory from "./ModelFactory.js"; import ModelRelation, {RelationDatabaseProperties} from "./ModelRelation.js"; diff --git a/src/helpers/BackendController.ts b/src/helpers/BackendController.ts index 5bc86ee..a7abc52 100644 --- a/src/helpers/BackendController.ts +++ b/src/helpers/BackendController.ts @@ -6,6 +6,7 @@ import UserApprovedComponent from "../auth/models/UserApprovedComponent.js"; import UserEmail from "../auth/models/UserEmail.js"; import UserNameComponent from "../auth/models/UserNameComponent.js"; import {route} from "../common/Routing.js"; +import {Time} from "../common/Time.js"; import MailComponent from "../components/MailComponent.js"; import Controller from "../Controller.js"; import ModelFactory from "../db/ModelFactory.js"; @@ -45,7 +46,7 @@ export default class BackendController extends Controller { this.get('/', this.getIndex, 'backend'); if (User.isApprovalMode()) { - this.get('/accounts-approval', this.getAccountApproval, 'accounts-approval'); + this.get('/accounts-approval/:page?', this.getAccountApproval, 'accounts-approval'); this.post('/accounts-approval/approve', this.postApproveAccount, 'approve-account'); this.post('/accounts-approval/reject', this.postRejectAccount, 'reject-account'); } @@ -62,12 +63,16 @@ export default class BackendController extends Controller { } protected async getAccountApproval(req: Request, res: Response): Promise { - const accounts = await User.select() + const accounts = await User.paginate(req, 1, User.select() .where('approved', 0) - .with('mainEmail') - .get(); + .with('mainEmail')); res.render('backend/accounts_approval', { - accounts: accounts, + accounts: accounts.map(account => Object.assign({ + mainEmailStr: account.mainEmail.getOrFail()?.email, + created_at_iso: account.created_at?.toISOString(), + created_at_human: account.created_at ? Time.humanizeTimeSince(account.created_at) : '', + }, account)), + pagination: accounts.pagination?.serialize(), has_user_name_component: ModelFactory.get(User).hasComponent(UserNameComponent), }); } diff --git a/test/Pagination.test.ts b/test/common/Pagination.test.ts similarity index 91% rename from test/Pagination.test.ts rename to test/common/Pagination.test.ts index a5a1a23..f427af7 100644 --- a/test/Pagination.test.ts +++ b/test/common/Pagination.test.ts @@ -1,4 +1,4 @@ -import Pagination from "../src/Pagination.js"; +import Pagination from "../../src/common/Pagination.js"; describe('Pagination', () => { const pagination = new Pagination(3, 5, 31); @@ -134,4 +134,15 @@ describe('Pagination', () => { expect(pagination.nextPages(2)).toStrictEqual([91, 92, -1, 99, 100]); expect(pagination.nextPages(3)).toStrictEqual([91, 92, 93, -1, 98, 99, 100]); }); + + test('Should serialize properly', () => { + expect(new Pagination(5, 6, 1000).serialize()).toStrictEqual('{"page":5,"perPage":6,"totalCount":1000}'); + }); + + test('Should deserialize properly', () => { + const pagination = Pagination.deserialize('{"page":5,"perPage":6,"totalCount":1000}'); + expect(pagination.page).toStrictEqual(5); + expect(pagination.perPage).toStrictEqual(6); + expect(pagination.totalCount).toStrictEqual(1000); + }); });