Merge pull request '#3-calendar' (#11) from #3-calendar into main
Reviewed-on: Ehrenamt/member-administration-server#11
This commit is contained in:
commit
7b6528ee96
23 changed files with 1048 additions and 1 deletions
88
package-lock.json
generated
88
package-lock.json
generated
|
@ -12,7 +12,9 @@
|
|||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^5.0.0-beta.3",
|
||||
"ics": "^3.8.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"moment": "^2.30.1",
|
||||
"ms": "^2.1.3",
|
||||
"mysql": "^2.18.1",
|
||||
"node-schedule": "^2.1.1",
|
||||
|
@ -1822,6 +1824,17 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ics": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/ics/-/ics-3.8.1.tgz",
|
||||
"integrity": "sha512-UqQlfkajfhrS4pUGQfGIJMYz/Jsl/ob3LqcfEhUmLbwumg+ZNkU0/6S734Vsjq3/FYNpEcZVKodLBoe+zBM69g==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.1.23",
|
||||
"runes2": "^1.1.2",
|
||||
"yup": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
|
@ -2217,6 +2230,15 @@
|
|||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.30.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
|
@ -2252,6 +2274,24 @@
|
|||
"thenify-all": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.7",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/napi-build-utils": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
|
||||
|
@ -2597,6 +2637,12 @@
|
|||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/property-expr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
|
||||
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -2823,6 +2869,12 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/runes2": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/runes2/-/runes2-1.1.4.tgz",
|
||||
"integrity": "sha512-LNPnEDPOOU4ehF71m5JoQyzT2yxwD6ZreFJ7MxZUAoMKNMY1XrAo60H1CUoX5ncSm0rIuKlqn9JZNRrRkNou2g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -3366,6 +3418,12 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-case": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
|
||||
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
|
@ -3374,6 +3432,12 @@
|
|||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/toposort": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
|
@ -3455,6 +3519,18 @@
|
|||
"license": "Unlicense",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
|
@ -3918,6 +3994,18 @@
|
|||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/yup": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/yup/-/yup-1.4.0.tgz",
|
||||
"integrity": "sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"property-expr": "^2.0.5",
|
||||
"tiny-case": "^1.0.3",
|
||||
"toposort": "^2.0.2",
|
||||
"type-fest": "^2.19.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^5.0.0-beta.3",
|
||||
"ics": "^3.8.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"moment": "^2.30.1",
|
||||
"ms": "^2.1.3",
|
||||
"mysql": "^2.18.1",
|
||||
"node-schedule": "^2.1.1",
|
||||
|
|
24
src/command/calendarCommand.ts
Normal file
24
src/command/calendarCommand.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
export interface CreateCalendarCommand {
|
||||
starttime: Date;
|
||||
endtime: Date;
|
||||
title: string;
|
||||
content: string;
|
||||
location: string;
|
||||
allDay: boolean;
|
||||
typeId: number;
|
||||
}
|
||||
|
||||
export interface UpdateCalendarCommand {
|
||||
id: string;
|
||||
starttime: Date;
|
||||
endtime: Date;
|
||||
title: string;
|
||||
content: string;
|
||||
location: string;
|
||||
allDay: boolean;
|
||||
typeId: number;
|
||||
}
|
||||
|
||||
export interface DeleteCalendarCommand {
|
||||
id: string;
|
||||
}
|
96
src/command/calendarCommandHandler.ts
Normal file
96
src/command/calendarCommandHandler.ts
Normal file
|
@ -0,0 +1,96 @@
|
|||
import { dataSource } from "../data-source";
|
||||
import { calendar } from "../entity/calendar";
|
||||
import { calendarType } from "../entity/calendarType";
|
||||
import InternalException from "../exceptions/internalException";
|
||||
import { CreateCalendarCommand, DeleteCalendarCommand, UpdateCalendarCommand } from "./calendarCommand";
|
||||
|
||||
export default abstract class CalendarCommandHandler {
|
||||
/**
|
||||
* @description create calendar
|
||||
* @param CreateCalendarCommand
|
||||
* @returns {Promise<number>}
|
||||
*/
|
||||
static async create(createCalendar: CreateCalendarCommand): Promise<number> {
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(calendar)
|
||||
.values({
|
||||
starttime: createCalendar.starttime,
|
||||
endtime: createCalendar.endtime,
|
||||
title: createCalendar.title,
|
||||
content: createCalendar.content,
|
||||
location: createCalendar.location,
|
||||
allDay: createCalendar.allDay,
|
||||
type: await dataSource
|
||||
.getRepository(calendarType)
|
||||
.createQueryBuilder("type")
|
||||
.where("id = :id", { id: createCalendar.typeId })
|
||||
.getOneOrFail(),
|
||||
})
|
||||
.execute()
|
||||
.then((result) => {
|
||||
return result.identifiers[0].id;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("Failed creating calendar", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description update calendar
|
||||
* @param UpdateCalendarCommand
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async update(updateCalendar: UpdateCalendarCommand): Promise<void> {
|
||||
let sequence = await dataSource
|
||||
.getRepository(calendar)
|
||||
.createQueryBuilder("calendar")
|
||||
.where("id = :id", { id: updateCalendar.id })
|
||||
.getOneOrFail()
|
||||
.then((res) => {
|
||||
return res.sequence;
|
||||
});
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
.update(calendar)
|
||||
.set({
|
||||
starttime: updateCalendar.starttime,
|
||||
endtime: updateCalendar.endtime,
|
||||
title: updateCalendar.title,
|
||||
content: updateCalendar.content,
|
||||
location: updateCalendar.location,
|
||||
allDay: updateCalendar.allDay,
|
||||
type: await dataSource
|
||||
.getRepository(calendarType)
|
||||
.createQueryBuilder("type")
|
||||
.where("id = :id", { id: updateCalendar.typeId })
|
||||
.getOneOrFail(),
|
||||
sequence: sequence + 1,
|
||||
})
|
||||
.where("id = :id", { id: updateCalendar.id })
|
||||
.execute()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw new InternalException("Failed updating award", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description delete calendar
|
||||
* @param DeleteCalendarCommand
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async delete(deleteCalendar: DeleteCalendarCommand): Promise<void> {
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
.delete()
|
||||
.from(calendar)
|
||||
.where("id = :id", { id: deleteCalendar.id })
|
||||
.execute()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw new InternalException("Failed deleting calendar", err);
|
||||
});
|
||||
}
|
||||
}
|
16
src/command/calendarTypeCommand.ts
Normal file
16
src/command/calendarTypeCommand.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
export interface CreateCalendarTypeCommand {
|
||||
type: string;
|
||||
nscdr: boolean;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface UpdateCalendarTypeCommand {
|
||||
id: number;
|
||||
type: string;
|
||||
nscdr: boolean;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface DeleteCalendarTypeCommand {
|
||||
id: number;
|
||||
}
|
70
src/command/calendarTypeCommandHandler.ts
Normal file
70
src/command/calendarTypeCommandHandler.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import { dataSource } from "../data-source";
|
||||
import { calendarType } from "../entity/calendarType";
|
||||
import InternalException from "../exceptions/internalException";
|
||||
import { CreateCalendarTypeCommand, DeleteCalendarTypeCommand, UpdateCalendarTypeCommand } from "./calendarTypeCommand";
|
||||
|
||||
export default abstract class CalendarTypeCommandHandler {
|
||||
/**
|
||||
* @description create calendarType
|
||||
* @param CreateCalendarTypeCommand
|
||||
* @returns {Promise<number>}
|
||||
*/
|
||||
static async create(createCalendarType: CreateCalendarTypeCommand): Promise<number> {
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(calendarType)
|
||||
.values({
|
||||
type: createCalendarType.type,
|
||||
nscdr: createCalendarType.nscdr,
|
||||
color: createCalendarType.color,
|
||||
})
|
||||
.execute()
|
||||
.then((result) => {
|
||||
return result.identifiers[0].id;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("Failed creating calendarType", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description update calendarType
|
||||
* @param UpdateCalendarTypeCommand
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async update(updateCalendarType: UpdateCalendarTypeCommand): Promise<void> {
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
.update(calendarType)
|
||||
.set({
|
||||
type: updateCalendarType.type,
|
||||
nscdr: updateCalendarType.nscdr,
|
||||
color: updateCalendarType.color,
|
||||
})
|
||||
.where("id = :id", { id: updateCalendarType.id })
|
||||
.execute()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw new InternalException("Failed updating award", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description delete calendarType
|
||||
* @param DeleteCalendarTypeCommand
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async delete(deleteCalendarType: DeleteCalendarTypeCommand): Promise<void> {
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
.delete()
|
||||
.from(calendarType)
|
||||
.where("id = :id", { id: deleteCalendarType.id })
|
||||
.execute()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw new InternalException("Failed deleting calendarType", err);
|
||||
});
|
||||
}
|
||||
}
|
201
src/controller/admin/calendarController.ts
Normal file
201
src/controller/admin/calendarController.ts
Normal file
|
@ -0,0 +1,201 @@
|
|||
import { Request, Response } from "express";
|
||||
import CalendarService from "../../service/calendarService";
|
||||
import CalendarFactory from "../../factory/admin/calendar";
|
||||
import CalendarTypeService from "../../service/calendarTypeService";
|
||||
import CalendarTypeFactory from "../../factory/admin/calendarType";
|
||||
import { CreateCalendarCommand, DeleteCalendarCommand, UpdateCalendarCommand } from "../../command/calendarCommand";
|
||||
import CalendarCommandHandler from "../../command/calendarCommandHandler";
|
||||
import {
|
||||
CreateCalendarTypeCommand,
|
||||
DeleteCalendarTypeCommand,
|
||||
UpdateCalendarTypeCommand,
|
||||
} from "../../command/calendarTypeCommand";
|
||||
import CalendarTypeCommandHandler from "../../command/calendarTypeCommandHandler";
|
||||
|
||||
/**
|
||||
* @description get all calendar items
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function getAllCalendarItems(req: Request, res: Response): Promise<any> {
|
||||
let items = await CalendarService.getAll();
|
||||
|
||||
res.json(CalendarFactory.mapToBase(items));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get calendar item by id
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function getCalendarItemById(req: Request, res: Response): Promise<any> {
|
||||
const id = req.params.id;
|
||||
let item = await CalendarService.getById(id);
|
||||
|
||||
res.json(CalendarFactory.mapToSingle(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get all calendar types
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function getAllCalendarTypes(req: Request, res: Response): Promise<any> {
|
||||
let types = await CalendarTypeService.getAll();
|
||||
|
||||
res.json(CalendarTypeFactory.mapToBase(types));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get calendar type by id
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function getCalendarTypeById(req: Request, res: Response): Promise<any> {
|
||||
const id = parseInt(req.params.id);
|
||||
let type = await CalendarTypeService.getById(id);
|
||||
|
||||
res.json(CalendarTypeFactory.mapToSingle(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description create calendar item
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function createCalendarItem(req: Request, res: Response): Promise<any> {
|
||||
const starttime = req.body.starttime;
|
||||
const endtime = req.body.endtime;
|
||||
const title = req.body.title;
|
||||
const content = req.body.content;
|
||||
const location = req.body.location;
|
||||
const allDay = req.body.allDay;
|
||||
const typeId = req.body.typeId;
|
||||
|
||||
let createItem: CreateCalendarCommand = {
|
||||
starttime,
|
||||
endtime,
|
||||
title,
|
||||
content,
|
||||
location,
|
||||
allDay,
|
||||
typeId,
|
||||
};
|
||||
let id = await CalendarCommandHandler.create(createItem);
|
||||
|
||||
res.send(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description create calendar type
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function createCalendarType(req: Request, res: Response): Promise<any> {
|
||||
const type = req.body.type;
|
||||
const nscdr = req.body.nscdr;
|
||||
const color = req.body.color;
|
||||
|
||||
let createType: CreateCalendarTypeCommand = {
|
||||
type,
|
||||
nscdr,
|
||||
color,
|
||||
};
|
||||
let id = await CalendarTypeCommandHandler.create(createType);
|
||||
|
||||
res.send(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description update calendar item
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function updateCalendarItem(req: Request, res: Response): Promise<any> {
|
||||
const id = req.params.id;
|
||||
const starttime = req.body.starttime;
|
||||
const endtime = req.body.endtime;
|
||||
const title = req.body.title;
|
||||
const content = req.body.content;
|
||||
const location = req.body.location;
|
||||
const allDay = req.body.allDay;
|
||||
const typeId = req.body.typeId;
|
||||
|
||||
let updateItem: UpdateCalendarCommand = {
|
||||
id,
|
||||
starttime,
|
||||
endtime,
|
||||
title,
|
||||
content,
|
||||
location,
|
||||
allDay,
|
||||
typeId,
|
||||
};
|
||||
await CalendarCommandHandler.update(updateItem);
|
||||
|
||||
res.sendStatus(204);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description update calendar type
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function updateCalendarType(req: Request, res: Response): Promise<any> {
|
||||
const id = parseInt(req.params.id);
|
||||
const type = req.body.type;
|
||||
const nscdr = req.body.nscdr;
|
||||
const color = req.body.color;
|
||||
|
||||
let updateType: UpdateCalendarTypeCommand = {
|
||||
id,
|
||||
type,
|
||||
nscdr,
|
||||
color,
|
||||
};
|
||||
await CalendarTypeCommandHandler.update(updateType);
|
||||
|
||||
res.sendStatus(204);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description delete calendar item
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function deleteCalendarItem(req: Request, res: Response): Promise<any> {
|
||||
const id = req.params.id;
|
||||
|
||||
let deleteItem: DeleteCalendarCommand = {
|
||||
id,
|
||||
};
|
||||
await CalendarCommandHandler.delete(deleteItem);
|
||||
|
||||
res.sendStatus(204);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description delete calendar type
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function deleteCalendarType(req: Request, res: Response): Promise<any> {
|
||||
const id = parseInt(req.params.id);
|
||||
|
||||
let deleteType: DeleteCalendarTypeCommand = {
|
||||
id,
|
||||
};
|
||||
await CalendarTypeCommandHandler.delete(deleteType);
|
||||
|
||||
res.sendStatus(204);
|
||||
}
|
66
src/controller/publicController.ts
Normal file
66
src/controller/publicController.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
import { Request, Response } from "express";
|
||||
import CalendarService from "../service/calendarService";
|
||||
import CalendarTypeService from "../service/calendarTypeService";
|
||||
import { calendar } from "../entity/calendar";
|
||||
import { createEvents } from "ics";
|
||||
import moment from "moment";
|
||||
|
||||
/**
|
||||
* @description get all calendar items by types or nscdr
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function getCalendarItemsByTypes(req: Request, res: Response): Promise<any> {
|
||||
let types = Array.isArray(req.query.types) ? req.query.types : [req.query.types];
|
||||
|
||||
let items: Array<calendar> = [];
|
||||
if (types.length == 0) {
|
||||
let typeIds = await CalendarTypeService.getByTypes(types as Array<string>);
|
||||
items = await CalendarService.getByTypes(typeIds.map((t) => t.id));
|
||||
} else {
|
||||
items = await CalendarService.getByTypeNSCDR();
|
||||
}
|
||||
|
||||
let events = createEvents(
|
||||
items.map((i) => ({
|
||||
calName: process.env.CLUB_NAME,
|
||||
uid: i.id,
|
||||
sequence: 1,
|
||||
start: moment(i.starttime)
|
||||
.format("YYYY-M-D-H-m")
|
||||
.split("-")
|
||||
.map((a) => parseInt(a)) as [number, number, number, number, number],
|
||||
end: moment(i.endtime)
|
||||
.format("YYYY-M-D-H-m")
|
||||
.split("-")
|
||||
.map((a) => parseInt(a)) as [number, number, number, number, number],
|
||||
title: i.title,
|
||||
description: i.content,
|
||||
location: i.location,
|
||||
categories: [i.type.type],
|
||||
created: moment(i.createdAt)
|
||||
.format("YYYY-M-D-H-m")
|
||||
.split("-")
|
||||
.map((a) => parseInt(a)) as [number, number, number, number, number],
|
||||
lastModified: moment(i.updatedAt)
|
||||
.format("YYYY-M-D-H-m")
|
||||
.split("-")
|
||||
.map((a) => parseInt(a)) as [number, number, number, number, number],
|
||||
transp: "OPAQUE" as "OPAQUE",
|
||||
url: "https://www.ff-merching.de",
|
||||
alarms: [
|
||||
{
|
||||
action: "display",
|
||||
description: "Erinnerung",
|
||||
trigger: {
|
||||
minutes: 30,
|
||||
before: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
}))
|
||||
);
|
||||
|
||||
res.type("ics").send(events.value);
|
||||
}
|
|
@ -36,6 +36,9 @@ import { protocolPresence } from "./entity/protocolPresence";
|
|||
import { protocolVoting } from "./entity/protocolVoting";
|
||||
import { protocolPrintout } from "./entity/protocolPrintout";
|
||||
import { Protocol1729347911107 } from "./migrations/1729347911107-protocol";
|
||||
import { calendar } from "./entity/calendar";
|
||||
import { calendarType } from "./entity/calendarType";
|
||||
import { Calendar1729947763295 } from "./migrations/1729947763295-calendar";
|
||||
|
||||
const dataSource = new DataSource({
|
||||
type: DB_TYPE as any,
|
||||
|
@ -71,6 +74,8 @@ const dataSource = new DataSource({
|
|||
protocolPresence,
|
||||
protocolVoting,
|
||||
protocolPrintout,
|
||||
calendar,
|
||||
calendarType,
|
||||
],
|
||||
migrations: [
|
||||
Initial1724317398939,
|
||||
|
@ -82,6 +87,7 @@ const dataSource = new DataSource({
|
|||
Memberdata1726301836849,
|
||||
CommunicationFields1727439800630,
|
||||
Protocol1729347911107,
|
||||
Calendar1729947763295,
|
||||
],
|
||||
migrationsRun: true,
|
||||
migrationsTransactionMode: "each",
|
||||
|
|
52
src/entity/calendar.ts
Normal file
52
src/entity/calendar.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import {
|
||||
Column,
|
||||
Entity,
|
||||
ManyToOne,
|
||||
PrimaryColumn,
|
||||
PrimaryGeneratedColumn,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
AfterUpdate,
|
||||
BeforeUpdate,
|
||||
} from "typeorm";
|
||||
import { calendarType } from "./calendarType";
|
||||
|
||||
@Entity()
|
||||
export class calendar {
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
id: string;
|
||||
|
||||
@Column({ type: "datetime", nullable: false })
|
||||
starttime: Date;
|
||||
|
||||
@Column({ type: "datetime", nullable: false })
|
||||
endtime: Date;
|
||||
|
||||
@Column({ type: "varchar", length: 255, nullable: false })
|
||||
title: string;
|
||||
|
||||
@Column({ type: "text", nullable: true })
|
||||
content: string;
|
||||
|
||||
@Column({ type: "text", nullable: true })
|
||||
location: string;
|
||||
|
||||
@Column({ type: "boolean", default: false })
|
||||
allDay: boolean;
|
||||
|
||||
@Column({ type: "int", default: 1 })
|
||||
sequence: number;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt: Date;
|
||||
|
||||
@ManyToOne(() => calendarType, (t) => t.calendar, {
|
||||
nullable: false,
|
||||
onDelete: "RESTRICT",
|
||||
onUpdate: "RESTRICT",
|
||||
})
|
||||
type: calendarType;
|
||||
}
|
24
src/entity/calendarType.ts
Normal file
24
src/entity/calendarType.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { Column, Entity, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { calendar } from "./calendar";
|
||||
|
||||
@Entity()
|
||||
export class calendarType {
|
||||
@PrimaryColumn({ generated: "increment", type: "int" })
|
||||
id: number;
|
||||
|
||||
@Column({ type: "varchar", length: 255 })
|
||||
type: string;
|
||||
|
||||
@Column({ type: "boolean" }) // none specified cal dav request
|
||||
nscdr: boolean;
|
||||
|
||||
@Column({ type: "varchar", length: 255 })
|
||||
color: string;
|
||||
|
||||
@OneToMany(() => calendar, (c) => c.type, {
|
||||
nullable: false,
|
||||
onDelete: "RESTRICT",
|
||||
onUpdate: "RESTRICT",
|
||||
})
|
||||
calendar: calendar[];
|
||||
}
|
34
src/factory/admin/calendar.ts
Normal file
34
src/factory/admin/calendar.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { calendar } from "../../entity/calendar";
|
||||
import { CalendarViewModel } from "../../viewmodel/admin/calendar.models";
|
||||
import CalendarTypeFactory from "./calendarType";
|
||||
|
||||
export default abstract class CalendarFactory {
|
||||
/**
|
||||
* @description map record to calendar
|
||||
* @param {calendar} record
|
||||
* @returns {CalendarViewModel}
|
||||
*/
|
||||
public static mapToSingle(record: calendar): CalendarViewModel {
|
||||
return {
|
||||
id: record.id,
|
||||
starttime: record.starttime,
|
||||
endtime: record.endtime,
|
||||
title: record.title,
|
||||
content: record.content,
|
||||
location: record.location,
|
||||
allDay: record.allDay,
|
||||
createdAt: record.createdAt,
|
||||
updatedAt: record.updatedAt,
|
||||
type: CalendarTypeFactory.mapToSingle(record.type),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description map records to calendar
|
||||
* @param {Array<calendar>} records
|
||||
* @returns {Array<CalendarViewModel>}
|
||||
*/
|
||||
public static mapToBase(records: Array<calendar>): Array<CalendarViewModel> {
|
||||
return records.map((r) => this.mapToSingle(r));
|
||||
}
|
||||
}
|
27
src/factory/admin/calendarType.ts
Normal file
27
src/factory/admin/calendarType.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { calendarType } from "../../entity/calendarType";
|
||||
import { CalendarTypeViewModel } from "../../viewmodel/admin/calendarType.models";
|
||||
|
||||
export default abstract class CalendarTypeFactory {
|
||||
/**
|
||||
* @description map record to calendarType
|
||||
* @param {calendarType} record
|
||||
* @returns {CalendarTypeViewModel}
|
||||
*/
|
||||
public static mapToSingle(record: calendarType): CalendarTypeViewModel {
|
||||
return {
|
||||
id: record.id,
|
||||
type: record.type,
|
||||
nscdr: record.nscdr,
|
||||
color: record.color,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description map records to calendarType
|
||||
* @param {Array<calendarType>} records
|
||||
* @returns {Array<CalendarTypeViewModel>}
|
||||
*/
|
||||
public static mapToBase(records: Array<calendarType>): Array<CalendarTypeViewModel> {
|
||||
return records.map((r) => this.mapToSingle(r));
|
||||
}
|
||||
}
|
68
src/migrations/1729947763295-calendar.ts
Normal file
68
src/migrations/1729947763295-calendar.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
import { MigrationInterface, QueryRunner, Table, TableForeignKey } from "typeorm";
|
||||
import { DB_TYPE } from "../env.defaults";
|
||||
|
||||
export class Calendar1729947763295 implements MigrationInterface {
|
||||
name = "Calendar1729947763295";
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
const variableType_int = DB_TYPE == "mysql" ? "int" : "integer";
|
||||
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: "calendar_type",
|
||||
columns: [
|
||||
{ name: "id", type: variableType_int, isPrimary: true, isGenerated: true, generationStrategy: "increment" },
|
||||
{ name: "type", type: "varchar", length: "255", isNullable: false },
|
||||
{ name: "nscdr", type: "tinyint", isNullable: false },
|
||||
{ name: "color", type: "varchar", length: "255", isNullable: false },
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: "calendar",
|
||||
columns: [
|
||||
{ name: "id", type: "varchar", length: "36", isPrimary: true, isGenerated: true, generationStrategy: "uuid" },
|
||||
{ name: "starttime", type: "datetime", isNullable: false },
|
||||
{ name: "endtime", type: "datetime", isNullable: false },
|
||||
{ name: "title", type: "varchar", length: "255", isNullable: false },
|
||||
{ name: "content", type: "text", isNullable: true },
|
||||
{ name: "allDay", type: "tinyint", isNullable: false, default: 0 },
|
||||
{ name: "location", type: "text", isNullable: true },
|
||||
{ name: "sequence", type: variableType_int, default: 1 },
|
||||
{ name: "createdAt", type: "datetime", precision: 6, isNullable: false, default: "CURRENT_TIMESTAMP(6)" },
|
||||
{
|
||||
name: "updatedAt",
|
||||
type: "datetime",
|
||||
precision: 6,
|
||||
isNullable: false,
|
||||
default: "CURRENT_TIMESTAMP(6)",
|
||||
onUpdate: "CURRENT_TIMESTAMP(6)",
|
||||
},
|
||||
{ name: "typeId", type: variableType_int, isNullable: false },
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
await queryRunner.createForeignKey(
|
||||
"calendar",
|
||||
new TableForeignKey({
|
||||
columnNames: ["typeId"],
|
||||
referencedColumnNames: ["id"],
|
||||
referencedTableName: "calendar_type",
|
||||
onDelete: "RESTRICT",
|
||||
onUpdate: "RESTRICT",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
const table = await queryRunner.getTable("calendar");
|
||||
const foreignKey = table.foreignKeys.find((fk) => fk.columnNames.indexOf("typeId") !== -1);
|
||||
await queryRunner.dropForeignKey("calendar", foreignKey);
|
||||
|
||||
await queryRunner.dropTable("calendar");
|
||||
await queryRunner.dropTable("calendar_type");
|
||||
}
|
||||
}
|
98
src/routes/admin/calendar.ts
Normal file
98
src/routes/admin/calendar.ts
Normal file
|
@ -0,0 +1,98 @@
|
|||
import express, { Request, Response } from "express";
|
||||
import {
|
||||
getCalendarItemById,
|
||||
getAllCalendarItems,
|
||||
getAllCalendarTypes,
|
||||
getCalendarTypeById,
|
||||
createCalendarItem,
|
||||
createCalendarType,
|
||||
updateCalendarItem,
|
||||
updateCalendarType,
|
||||
deleteCalendarItem,
|
||||
deleteCalendarType,
|
||||
} from "../../controller/admin/calendarController";
|
||||
import PermissionHelper from "../../helpers/permissionHelper";
|
||||
|
||||
var router = express.Router({ mergeParams: true });
|
||||
|
||||
router.get(
|
||||
"/items",
|
||||
PermissionHelper.passCheckMiddleware("read", "club", "calendar"),
|
||||
async (req: Request, res: Response) => {
|
||||
await getAllCalendarItems(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/item/:id",
|
||||
PermissionHelper.passCheckMiddleware("read", "club", "calendar"),
|
||||
async (req: Request, res: Response) => {
|
||||
await getCalendarItemById(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/types",
|
||||
PermissionHelper.passCheckMiddleware("read", "settings", "calendar_type"),
|
||||
async (req: Request, res: Response) => {
|
||||
await getAllCalendarTypes(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/type/:id",
|
||||
PermissionHelper.passCheckMiddleware("read", "settings", "calendar_type"),
|
||||
async (req: Request, res: Response) => {
|
||||
await getCalendarTypeById(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/item",
|
||||
PermissionHelper.passCheckMiddleware("create", "club", "calendar"),
|
||||
async (req: Request, res: Response) => {
|
||||
await createCalendarItem(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/type",
|
||||
PermissionHelper.passCheckMiddleware("create", "settings", "calendar_type"),
|
||||
async (req: Request, res: Response) => {
|
||||
await createCalendarType(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.patch(
|
||||
"/item/:id",
|
||||
PermissionHelper.passCheckMiddleware("update", "club", "calendar"),
|
||||
async (req: Request, res: Response) => {
|
||||
await updateCalendarItem(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.patch(
|
||||
"/type/:id",
|
||||
PermissionHelper.passCheckMiddleware("update", "settings", "calendar_type"),
|
||||
async (req: Request, res: Response) => {
|
||||
await updateCalendarType(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/item/:id",
|
||||
PermissionHelper.passCheckMiddleware("delete", "club", "calendar"),
|
||||
async (req: Request, res: Response) => {
|
||||
await deleteCalendarItem(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/type/:id",
|
||||
PermissionHelper.passCheckMiddleware("delete", "settings", "calendar_type"),
|
||||
async (req: Request, res: Response) => {
|
||||
await deleteCalendarType(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
export default router;
|
|
@ -10,6 +10,8 @@ import qualification from "./qualification";
|
|||
import member from "./member";
|
||||
import protocol from "./protocol";
|
||||
|
||||
import calendar from "./calendar";
|
||||
|
||||
import role from "./role";
|
||||
import user from "./user";
|
||||
|
||||
|
@ -36,6 +38,7 @@ router.use("/qualification", PermissionHelper.passCheckMiddleware("read", "setti
|
|||
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
|
||||
|
||||
router.use("/protocol", PermissionHelper.passCheckMiddleware("read", "club", "protocol"), protocol);
|
||||
router.use("/calendar", PermissionHelper.passCheckMiddleware("read", "club", "calendar"), calendar);
|
||||
|
||||
router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role);
|
||||
router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user);
|
||||
|
|
|
@ -6,6 +6,7 @@ import allowSetup from "../middleware/allowSetup";
|
|||
import authenticate from "../middleware/authenticate";
|
||||
import errorHandler from "../middleware/errorHandler";
|
||||
|
||||
import publicAvailable from "./public";
|
||||
import setup from "./setup";
|
||||
import auth from "./auth";
|
||||
import admin from "./admin/index";
|
||||
|
@ -21,6 +22,7 @@ export default (app: Express) => {
|
|||
app.use(cors());
|
||||
app.options("*", cors());
|
||||
|
||||
app.use("/public", publicAvailable);
|
||||
app.use("/setup", allowSetup, setup);
|
||||
app.use("/auth", auth);
|
||||
app.use(authenticate);
|
||||
|
|
10
src/routes/public.ts
Normal file
10
src/routes/public.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import express from "express";
|
||||
import { getCalendarItemsByTypes } from "../controller/publicController";
|
||||
|
||||
var router = express.Router({ mergeParams: true });
|
||||
|
||||
router.get("/calendar", async (req, res) => {
|
||||
await getCalendarItemsByTypes(req, res);
|
||||
});
|
||||
|
||||
export default router;
|
80
src/service/calendarService.ts
Normal file
80
src/service/calendarService.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { dataSource } from "../data-source";
|
||||
import { calendar } from "../entity/calendar";
|
||||
import InternalException from "../exceptions/internalException";
|
||||
|
||||
export default abstract class CalendarService {
|
||||
/**
|
||||
* @description get all calendars
|
||||
* @returns {Promise<Array<calendar>>}
|
||||
*/
|
||||
static async getAll(): Promise<Array<calendar>> {
|
||||
return await dataSource
|
||||
.getRepository(calendar)
|
||||
.createQueryBuilder("calendar")
|
||||
.leftJoinAndSelect("calendar.type", "type")
|
||||
.getMany()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("calendars not found", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get calendar by id
|
||||
* @returns {Promise<calendar>}
|
||||
*/
|
||||
static async getById(id: string): Promise<calendar> {
|
||||
return await dataSource
|
||||
.getRepository(calendar)
|
||||
.createQueryBuilder("calendar")
|
||||
.leftJoinAndSelect("calendar.type", "type")
|
||||
.where("calendar.id = :id", { id: id })
|
||||
.getOneOrFail()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("calendar not found by id", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get calendar by types
|
||||
* @returns {Promise<Array<calendar>>}
|
||||
*/
|
||||
static async getByTypes(types: Array<number>): Promise<Array<calendar>> {
|
||||
return await dataSource
|
||||
.getRepository(calendar)
|
||||
.createQueryBuilder("calendar")
|
||||
.leftJoinAndSelect("calendar.type", "type")
|
||||
.where("type.id IN (:...types)", { types: types })
|
||||
.getMany()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("calendars not found by types", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get calendar by types nscdr
|
||||
* @returns {Promise<Array<calendar>>}
|
||||
*/
|
||||
static async getByTypeNSCDR(): Promise<Array<calendar>> {
|
||||
return await dataSource
|
||||
.getRepository(calendar)
|
||||
.createQueryBuilder("calendar")
|
||||
.leftJoinAndSelect("calendar.type", "type")
|
||||
.where("type.nscdr = :nscdr", { nscdr: true })
|
||||
.getMany()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("calendars not found by type nscdr", err);
|
||||
});
|
||||
}
|
||||
}
|
58
src/service/calendarTypeService.ts
Normal file
58
src/service/calendarTypeService.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { dataSource } from "../data-source";
|
||||
import { calendarType } from "../entity/calendarType";
|
||||
import InternalException from "../exceptions/internalException";
|
||||
|
||||
export default abstract class CalendarTypeService {
|
||||
/**
|
||||
* @description get all calendar types
|
||||
* @returns {Promise<Array<calendarType>>}
|
||||
*/
|
||||
static async getAll(): Promise<Array<calendarType>> {
|
||||
return await dataSource
|
||||
.getRepository(calendarType)
|
||||
.createQueryBuilder("calendarType")
|
||||
.getMany()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("calendarTypes not found", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get calendar type by id
|
||||
* @returns {Promise<calendarType>}
|
||||
*/
|
||||
static async getById(id: number): Promise<calendarType> {
|
||||
return await dataSource
|
||||
.getRepository(calendarType)
|
||||
.createQueryBuilder("calendarType")
|
||||
.where("calendarType.id = :id", { id: id })
|
||||
.getOneOrFail()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("calendarType not found by id", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get calendar by names
|
||||
* @returns {Promise<Array<calendarType>>}
|
||||
*/
|
||||
static async getByTypes(names: Array<string>): Promise<Array<calendarType>> {
|
||||
return await dataSource
|
||||
.getRepository(calendarType)
|
||||
.createQueryBuilder("calendarType")
|
||||
.where("calendarType.type IN (:...names)", { names: names })
|
||||
.getMany()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("calendarTypes not found by names", err);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ export type PermissionModule =
|
|||
| "executive_position"
|
||||
| "communication"
|
||||
| "membership_status"
|
||||
| "calendar_type"
|
||||
| "user"
|
||||
| "role";
|
||||
|
||||
|
@ -45,12 +46,13 @@ export const permissionModules: Array<PermissionModule> = [
|
|||
"executive_position",
|
||||
"communication",
|
||||
"membership_status",
|
||||
"calendar_type",
|
||||
"user",
|
||||
"role",
|
||||
];
|
||||
export const permissionTypes: Array<PermissionType> = ["read", "create", "update", "delete"];
|
||||
export const sectionsAndModules: SectionsAndModulesObject = {
|
||||
club: ["member", "calendar", "newsletter", "protocol"],
|
||||
settings: ["qualification", "award", "executive_position", "communication", "membership_status"],
|
||||
settings: ["qualification", "award", "executive_position", "communication", "membership_status", "calendar_type"],
|
||||
user: ["user", "role"],
|
||||
};
|
||||
|
|
14
src/viewmodel/admin/calendar.models.ts
Normal file
14
src/viewmodel/admin/calendar.models.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { CalendarTypeViewModel } from "./calendarType.models";
|
||||
|
||||
export interface CalendarViewModel {
|
||||
id: string;
|
||||
starttime: Date;
|
||||
endtime: Date;
|
||||
title: string;
|
||||
content: string;
|
||||
location: string;
|
||||
allDay: boolean;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
type: CalendarTypeViewModel;
|
||||
}
|
6
src/viewmodel/admin/calendarType.models.ts
Normal file
6
src/viewmodel/admin/calendarType.models.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export interface CalendarTypeViewModel {
|
||||
id: number;
|
||||
type: string;
|
||||
nscdr: boolean;
|
||||
color: string;
|
||||
}
|
Loading…
Reference in a new issue