template storing
This commit is contained in:
parent
98477eafde
commit
160d82459d
12 changed files with 386 additions and 1 deletions
18
src/command/templateCommand.ts
Normal file
18
src/command/templateCommand.ts
Normal file
|
@ -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;
|
||||||
|
}
|
72
src/command/templateCommandHandler.ts
Normal file
72
src/command/templateCommandHandler.ts
Normal file
|
@ -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<number>}
|
||||||
|
*/
|
||||||
|
static async create(createTemplate: CreateTemplateCommand): Promise<number> {
|
||||||
|
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<void>}
|
||||||
|
*/
|
||||||
|
static async update(updateTemplate: UpdateTemplateCommand): Promise<void> {
|
||||||
|
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<void>}
|
||||||
|
*/
|
||||||
|
static async delete(deletTemplate: DeleteTemplateCommand): Promise<void> {
|
||||||
|
return await dataSource
|
||||||
|
.createQueryBuilder()
|
||||||
|
.delete()
|
||||||
|
.from(template)
|
||||||
|
.where("id = :id", { id: deletTemplate.id })
|
||||||
|
.execute()
|
||||||
|
.then(() => {})
|
||||||
|
.catch((err) => {
|
||||||
|
throw new InternalException("Failed deleting template", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
95
src/controller/admin/templateController.ts
Normal file
95
src/controller/admin/templateController.ts
Normal file
|
@ -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<any> {
|
||||||
|
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<any> {
|
||||||
|
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<any> {
|
||||||
|
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<any> {
|
||||||
|
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<any> {
|
||||||
|
const id = parseInt(req.params.id);
|
||||||
|
|
||||||
|
let deleteTemplate: DeleteTemplateCommand = {
|
||||||
|
id: id,
|
||||||
|
};
|
||||||
|
await TemplateCommandHandler.delete(deleteTemplate);
|
||||||
|
|
||||||
|
res.sendStatus(204);
|
||||||
|
}
|
|
@ -51,6 +51,8 @@ import { memberExecutivePositionsView } from "./views/memberExecutivePositionVie
|
||||||
import { memberQualificationsView } from "./views/memberQualificationsView";
|
import { memberQualificationsView } from "./views/memberQualificationsView";
|
||||||
import { membershipView } from "./views/membershipsView";
|
import { membershipView } from "./views/membershipsView";
|
||||||
import { MemberDataViews1734520998539 } from "./migrations/1734520998539-memberDataViews";
|
import { MemberDataViews1734520998539 } from "./migrations/1734520998539-memberDataViews";
|
||||||
|
import { template } from "./entity/template";
|
||||||
|
import { Template1734854680201 } from "./migrations/1734854680201-template";
|
||||||
|
|
||||||
const dataSource = new DataSource({
|
const dataSource = new DataSource({
|
||||||
type: DB_TYPE as any,
|
type: DB_TYPE as any,
|
||||||
|
@ -90,6 +92,7 @@ const dataSource = new DataSource({
|
||||||
calendar,
|
calendar,
|
||||||
calendarType,
|
calendarType,
|
||||||
query,
|
query,
|
||||||
|
template,
|
||||||
memberView,
|
memberView,
|
||||||
memberExecutivePositionsView,
|
memberExecutivePositionsView,
|
||||||
memberQualificationsView,
|
memberQualificationsView,
|
||||||
|
@ -112,6 +115,7 @@ const dataSource = new DataSource({
|
||||||
SecuringCalendarType1733249553766,
|
SecuringCalendarType1733249553766,
|
||||||
QueryStore1734187754677,
|
QueryStore1734187754677,
|
||||||
MemberDataViews1734520998539,
|
MemberDataViews1734520998539,
|
||||||
|
Template1734854680201,
|
||||||
],
|
],
|
||||||
migrationsRun: true,
|
migrationsRun: true,
|
||||||
migrationsTransactionMode: "each",
|
migrationsTransactionMode: "each",
|
||||||
|
|
36
src/entity/template.ts
Normal file
36
src/entity/template.ts
Normal file
|
@ -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;
|
||||||
|
}
|
30
src/factory/admin/template.ts
Normal file
30
src/factory/admin/template.ts
Normal file
|
@ -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<template>} records
|
||||||
|
* @returns {Array<TemplateViewModel>}
|
||||||
|
*/
|
||||||
|
public static mapToBase(records: Array<template>): Array<TemplateViewModel> {
|
||||||
|
return records.map((r) => this.mapToSingle(r));
|
||||||
|
}
|
||||||
|
}
|
30
src/migrations/1734854680201-template.ts
Normal file
30
src/migrations/1734854680201-template.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { MigrationInterface, QueryRunner, Table } from "typeorm";
|
||||||
|
import { DB_TYPE } from "../env.defaults";
|
||||||
|
|
||||||
|
export class Template1734854680201 implements MigrationInterface {
|
||||||
|
name = "Template1734854680201";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
const variableType_int = DB_TYPE == "mysql" ? "int" : "integer";
|
||||||
|
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: "template",
|
||||||
|
columns: [
|
||||||
|
{ name: "id", type: variableType_int, isPrimary: true, isGenerated: true, generationStrategy: "increment" },
|
||||||
|
{ name: "template", type: "varchar", length: "255", isNullable: false },
|
||||||
|
{ name: "description", type: "varchar", length: "255", isNullable: true },
|
||||||
|
{ name: "design", type: "text", isNullable: false, default: "'{}'" },
|
||||||
|
{ name: "headerHTML", type: "text", isNullable: false, default: "''" },
|
||||||
|
{ name: "bodyHTML", type: "text", isNullable: false, default: "''" },
|
||||||
|
{ name: "footerHTML", type: "text", isNullable: false, default: "''" },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable("template");
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import membershipStatus from "./membershipStatus";
|
||||||
import qualification from "./qualification";
|
import qualification from "./qualification";
|
||||||
import calendarType from "./calendarType";
|
import calendarType from "./calendarType";
|
||||||
import queryStore from "./queryStore";
|
import queryStore from "./queryStore";
|
||||||
|
import template from "./template";
|
||||||
|
|
||||||
import member from "./member";
|
import member from "./member";
|
||||||
import protocol from "./protocol";
|
import protocol from "./protocol";
|
||||||
|
@ -39,6 +40,7 @@ router.use(
|
||||||
router.use("/qualification", PermissionHelper.passCheckMiddleware("read", "settings", "qualification"), qualification);
|
router.use("/qualification", PermissionHelper.passCheckMiddleware("read", "settings", "qualification"), qualification);
|
||||||
router.use("/calendartype", PermissionHelper.passCheckMiddleware("read", "settings", "calendar_type"), calendarType);
|
router.use("/calendartype", PermissionHelper.passCheckMiddleware("read", "settings", "calendar_type"), calendarType);
|
||||||
router.use("/querystore", PermissionHelper.passCheckMiddleware("read", "settings", "query_store"), queryStore);
|
router.use("/querystore", PermissionHelper.passCheckMiddleware("read", "settings", "query_store"), queryStore);
|
||||||
|
router.use("/template", PermissionHelper.passCheckMiddleware("read", "settings", "template"), template);
|
||||||
|
|
||||||
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
|
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
|
||||||
router.use("/protocol", PermissionHelper.passCheckMiddleware("read", "club", "protocol"), protocol);
|
router.use("/protocol", PermissionHelper.passCheckMiddleware("read", "club", "protocol"), protocol);
|
||||||
|
|
45
src/routes/admin/template.ts
Normal file
45
src/routes/admin/template.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import express, { Request, Response } from "express";
|
||||||
|
import {
|
||||||
|
createTemplate,
|
||||||
|
deleteTemplate,
|
||||||
|
getAllTemplates,
|
||||||
|
getTemplateById,
|
||||||
|
updateTemplate,
|
||||||
|
} from "../../controller/admin/templateController";
|
||||||
|
import PermissionHelper from "../../helpers/permissionHelper";
|
||||||
|
|
||||||
|
var router = express.Router({ mergeParams: true });
|
||||||
|
|
||||||
|
router.get("/", async (req: Request, res: Response) => {
|
||||||
|
await getAllTemplates(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/:id", async (req: Request, res: Response) => {
|
||||||
|
await getTemplateById(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/",
|
||||||
|
PermissionHelper.passCheckMiddleware("create", "settings", "template"),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
|
await createTemplate(req, res);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
router.patch(
|
||||||
|
"/:id",
|
||||||
|
PermissionHelper.passCheckMiddleware("update", "settings", "template"),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
|
await updateTemplate(req, res);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
router.delete(
|
||||||
|
"/:id",
|
||||||
|
PermissionHelper.passCheckMiddleware("delete", "settings", "template"),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
|
await deleteTemplate(req, res);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router;
|
41
src/service/templateService.ts
Normal file
41
src/service/templateService.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { dataSource } from "../data-source";
|
||||||
|
import { template } from "../entity/template";
|
||||||
|
import { member } from "../entity/member";
|
||||||
|
import InternalException from "../exceptions/internalException";
|
||||||
|
|
||||||
|
export default abstract class TemplateService {
|
||||||
|
/**
|
||||||
|
* @description get all templates
|
||||||
|
* @returns {Promise<Array<template>>}
|
||||||
|
*/
|
||||||
|
static async getAll(): Promise<Array<template>> {
|
||||||
|
return await dataSource
|
||||||
|
.getRepository(template)
|
||||||
|
.createQueryBuilder("template")
|
||||||
|
.getMany()
|
||||||
|
.then((res) => {
|
||||||
|
return res;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
throw new InternalException("templates not found", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description get template by id
|
||||||
|
* @returns {Promise<template>}
|
||||||
|
*/
|
||||||
|
static async getById(id: number): Promise<template> {
|
||||||
|
return await dataSource
|
||||||
|
.getRepository(template)
|
||||||
|
.createQueryBuilder("template")
|
||||||
|
.where("template.id = :id", { id: id })
|
||||||
|
.getOneOrFail()
|
||||||
|
.then((res) => {
|
||||||
|
return res;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
throw new InternalException("template not found by id", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,8 @@ export type PermissionModule =
|
||||||
| "user"
|
| "user"
|
||||||
| "role"
|
| "role"
|
||||||
| "query"
|
| "query"
|
||||||
| "query_store";
|
| "query_store"
|
||||||
|
| "template";
|
||||||
|
|
||||||
export type PermissionType = "read" | "create" | "update" | "delete";
|
export type PermissionType = "read" | "create" | "update" | "delete";
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ export const permissionModules: Array<PermissionModule> = [
|
||||||
"role",
|
"role",
|
||||||
"query",
|
"query",
|
||||||
"query_store",
|
"query_store",
|
||||||
|
"template",
|
||||||
];
|
];
|
||||||
export const permissionTypes: Array<PermissionType> = ["read", "create", "update", "delete"];
|
export const permissionTypes: Array<PermissionType> = ["read", "create", "update", "delete"];
|
||||||
export const sectionsAndModules: SectionsAndModulesObject = {
|
export const sectionsAndModules: SectionsAndModulesObject = {
|
||||||
|
@ -65,6 +67,7 @@ export const sectionsAndModules: SectionsAndModulesObject = {
|
||||||
"membership_status",
|
"membership_status",
|
||||||
"calendar_type",
|
"calendar_type",
|
||||||
"query_store",
|
"query_store",
|
||||||
|
"template",
|
||||||
],
|
],
|
||||||
user: ["user", "role"],
|
user: ["user", "role"],
|
||||||
};
|
};
|
||||||
|
|
9
src/viewmodel/admin/template.models.ts
Normal file
9
src/viewmodel/admin/template.models.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export interface TemplateViewModel {
|
||||||
|
id: number;
|
||||||
|
template: string;
|
||||||
|
description: string | null;
|
||||||
|
design: object;
|
||||||
|
headerHTML: string;
|
||||||
|
bodyHTML: string;
|
||||||
|
footerHTML: string;
|
||||||
|
}
|
Loading…
Reference in a new issue