From 160d82459d0b25aa521a7ee9b107d400cdb8345d Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Sun, 22 Dec 2024 10:29:42 +0100 Subject: [PATCH 01/16] template storing --- src/command/templateCommand.ts | 18 ++++ src/command/templateCommandHandler.ts | 72 ++++++++++++++++ src/controller/admin/templateController.ts | 95 ++++++++++++++++++++++ src/data-source.ts | 4 + src/entity/template.ts | 36 ++++++++ src/factory/admin/template.ts | 30 +++++++ src/migrations/1734854680201-template.ts | 30 +++++++ src/routes/admin/index.ts | 2 + src/routes/admin/template.ts | 45 ++++++++++ src/service/templateService.ts | 41 ++++++++++ src/type/permissionTypes.ts | 5 +- src/viewmodel/admin/template.models.ts | 9 ++ 12 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 src/command/templateCommand.ts create mode 100644 src/command/templateCommandHandler.ts create mode 100644 src/controller/admin/templateController.ts create mode 100644 src/entity/template.ts create mode 100644 src/factory/admin/template.ts create mode 100644 src/migrations/1734854680201-template.ts create mode 100644 src/routes/admin/template.ts create mode 100644 src/service/templateService.ts create mode 100644 src/viewmodel/admin/template.models.ts diff --git a/src/command/templateCommand.ts b/src/command/templateCommand.ts new file mode 100644 index 0000000..9823d20 --- /dev/null +++ b/src/command/templateCommand.ts @@ -0,0 +1,18 @@ +export interface CreateTemplateCommand { + template: string; + description: string | null; +} + +export interface UpdateTemplateCommand { + id: number; + template: string; + description: string | null; + design: object; + headerHTML: string; + bodyHTML: string; + footerHTML: string; +} + +export interface DeleteTemplateCommand { + id: number; +} diff --git a/src/command/templateCommandHandler.ts b/src/command/templateCommandHandler.ts new file mode 100644 index 0000000..3cf9871 --- /dev/null +++ b/src/command/templateCommandHandler.ts @@ -0,0 +1,72 @@ +import { dataSource } from "../data-source"; +import { template } from "../entity/template"; +import InternalException from "../exceptions/internalException"; +import { CreateTemplateCommand, DeleteTemplateCommand, UpdateTemplateCommand } from "./templateCommand"; + +export default abstract class TemplateCommandHandler { + /** + * @description create template + * @param CreateTemplateCommand + * @returns {Promise} + */ + static async create(createTemplate: CreateTemplateCommand): Promise { + return await dataSource + .createQueryBuilder() + .insert() + .into(template) + .values({ + template: createTemplate.template, + description: createTemplate.description, + }) + .execute() + .then((result) => { + return result.identifiers[0].id; + }) + .catch((err) => { + throw new InternalException("Failed creating template", err); + }); + } + + /** + * @description update template + * @param UpdateTemplateCommand + * @returns {Promise} + */ + static async update(updateTemplate: UpdateTemplateCommand): Promise { + return await dataSource + .createQueryBuilder() + .update(template) + .set({ + template: updateTemplate.template, + description: updateTemplate.description, + design: updateTemplate.design, + headerHTML: updateTemplate.headerHTML, + bodyHTML: updateTemplate.bodyHTML, + footerHTML: updateTemplate.footerHTML, + }) + .where("id = :id", { id: updateTemplate.id }) + .execute() + .then(() => {}) + .catch((err) => { + throw new InternalException("Failed updating template", err); + }); + } + + /** + * @description delete template + * @param DeleteTemplateCommand + * @returns {Promise} + */ + static async delete(deletTemplate: DeleteTemplateCommand): Promise { + return await dataSource + .createQueryBuilder() + .delete() + .from(template) + .where("id = :id", { id: deletTemplate.id }) + .execute() + .then(() => {}) + .catch((err) => { + throw new InternalException("Failed deleting template", err); + }); + } +} diff --git a/src/controller/admin/templateController.ts b/src/controller/admin/templateController.ts new file mode 100644 index 0000000..6f46ae6 --- /dev/null +++ b/src/controller/admin/templateController.ts @@ -0,0 +1,95 @@ +import { Request, Response } from "express"; +import TemplateService from "../../service/templateService"; +import TemplateFactory from "../../factory/admin/template"; +import { CreateTemplateCommand, DeleteTemplateCommand, UpdateTemplateCommand } from "../../command/templateCommand"; +import TemplateCommandHandler from "../../command/templateCommandHandler"; + +/** + * @description get all templates + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function getAllTemplates(req: Request, res: Response): Promise { + let templates = await TemplateService.getAll(); + + res.json(TemplateFactory.mapToBase(templates)); +} + +/** + * @description get template by id + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function getTemplateById(req: Request, res: Response): Promise { + const id = parseInt(req.params.id); + let template = await TemplateService.getById(id); + + res.json(TemplateFactory.mapToSingle(template)); +} + +/** + * @description create new template + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function createTemplate(req: Request, res: Response): Promise { + const template = req.body.template; + const description = req.body.description; + + let createTemplate: CreateTemplateCommand = { + template: template, + description: description, + }; + let id = await TemplateCommandHandler.create(createTemplate); + + res.status(200).send(id); +} + +/** + * @description update template + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function updateTemplate(req: Request, res: Response): Promise { + const id = parseInt(req.params.id); + const template = req.body.template; + const description = req.body.description; + const design = req.body.design; + const headerHTML = req.body.headerHTML; + const bodyHTML = req.body.bodyHTML; + const footerHTML = req.body.footerHTML; + + let updateTemplate: UpdateTemplateCommand = { + id: id, + template: template, + description: description, + design: design, + headerHTML: headerHTML, + bodyHTML: bodyHTML, + footerHTML: footerHTML, + }; + await TemplateCommandHandler.update(updateTemplate); + + res.sendStatus(204); +} + +/** + * @description delete template + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function deleteTemplate(req: Request, res: Response): Promise { + const id = parseInt(req.params.id); + + let deleteTemplate: DeleteTemplateCommand = { + id: id, + }; + await TemplateCommandHandler.delete(deleteTemplate); + + res.sendStatus(204); +} diff --git a/src/data-source.ts b/src/data-source.ts index 685d05c..0b29b2c 100644 --- a/src/data-source.ts +++ b/src/data-source.ts @@ -51,6 +51,8 @@ import { memberExecutivePositionsView } from "./views/memberExecutivePositionVie import { memberQualificationsView } from "./views/memberQualificationsView"; import { membershipView } from "./views/membershipsView"; import { MemberDataViews1734520998539 } from "./migrations/1734520998539-memberDataViews"; +import { template } from "./entity/template"; +import { Template1734854680201 } from "./migrations/1734854680201-template"; const dataSource = new DataSource({ type: DB_TYPE as any, @@ -90,6 +92,7 @@ const dataSource = new DataSource({ calendar, calendarType, query, + template, memberView, memberExecutivePositionsView, memberQualificationsView, @@ -112,6 +115,7 @@ const dataSource = new DataSource({ SecuringCalendarType1733249553766, QueryStore1734187754677, MemberDataViews1734520998539, + Template1734854680201, ], migrationsRun: true, migrationsTransactionMode: "each", diff --git a/src/entity/template.ts b/src/entity/template.ts new file mode 100644 index 0000000..2b5d366 --- /dev/null +++ b/src/entity/template.ts @@ -0,0 +1,36 @@ +import { Column, Entity, PrimaryColumn } from "typeorm"; + +@Entity() +export class template { + @PrimaryColumn({ generated: "increment", type: "int" }) + id: number; + + @Column({ type: "varchar", length: 255 }) + template: string; + + @Column({ type: "varchar", length: 255, nullable: true }) + description?: string; + + @Column({ + type: "text", + default: "{}", + transformer: { + to(value: object) { + return JSON.stringify(value); + }, + from(value: string) { + return JSON.parse(value); + }, + }, + }) + design: object; + + @Column({ type: "text", default: "" }) + headerHTML: string; + + @Column({ type: "text", default: "" }) + bodyHTML: string; + + @Column({ type: "text", default: "" }) + footerHTML: string; +} diff --git a/src/factory/admin/template.ts b/src/factory/admin/template.ts new file mode 100644 index 0000000..c1d721d --- /dev/null +++ b/src/factory/admin/template.ts @@ -0,0 +1,30 @@ +import { template } from "../../entity/template"; +import { TemplateViewModel } from "../../viewmodel/admin/template.models"; + +export default abstract class TemplateFactory { + /** + * @description map record to template + * @param {template} record + * @returns {TemplateViewModel} + */ + public static mapToSingle(record: template): TemplateViewModel { + return { + id: record.id, + template: record.template, + description: record.description, + design: record.design, + headerHTML: record.headerHTML, + bodyHTML: record.bodyHTML, + footerHTML: record.footerHTML, + }; + } + + /** + * @description map records to template + * @param {Array