diff --git a/api/__tests__/mock/mail_template.ts b/api/__tests__/mock/mail_template.ts index 7313c3bff..a08da1af5 100644 --- a/api/__tests__/mock/mail_template.ts +++ b/api/__tests__/mock/mail_template.ts @@ -3,20 +3,21 @@ import { prisma } from "./prisma"; export async function initialiseMailTemplate() { const mailTemplate1 = { name: "Vuilnis", - mail_subject: "Vuilnis in $(building)", - content: "In $(building) ligt er vuilnis op de grond", + mail_subject: "Vuilnis in $(gebouw_naam)", + content: "In $(gebouw_naam) ligt er vuilnis op de grond", }; const mailTemplate2 = { name: "Code", - mail_subject: "Code werkt niet in $(building)", - content: "In $(building) werkt $(code) niet meer", + mail_subject: "Code werkt niet in $(gebouw_naam)", + content: "In $(gebouw_naam) werkt de code niet meer", }; const mailTemplate3 = { name: "Ivago", - mail_subject: "Ivago is niet langs $(building) gekomen", - content: "Ivago heeft $(garbage_type) niet meegenomen bij $(building)", + mail_subject: "Ivago is niet langs $(gebouw_naam) gekomen", + content: + "Ivago heeft de ingeplande container niet meegenomen bij $(gebouw_naam)", }; await prisma.mailTemplate.createMany({ data: [mailTemplate1, mailTemplate2, mailTemplate3], diff --git a/api/__tests__/routes/mail_template.test.ts b/api/__tests__/routes/mail_template.test.ts index 9dc68f14a..a2fa6e804 100644 --- a/api/__tests__/routes/mail_template.test.ts +++ b/api/__tests__/routes/mail_template.test.ts @@ -34,8 +34,8 @@ describe("Mail Template tests", () => { test("POST /mail_template", async () => { const newMailTemplate = { name: "new mail template", - mail_subject: "new mail template subject $(building)", - content: "new content for $(building)", + mail_subject: "new mail template subject $(gebouw_naam)", + content: "new content for $(gebouw_naam)", }; await runner.post({ @@ -48,22 +48,22 @@ describe("Mail Template tests", () => { test("GET /mail_template", async () => { const expected = [ { - content: "In $(building) ligt er vuilnis op de grond", + content: "In $(gebouw_naam) ligt er vuilnis op de grond", id: 1, - mail_subject: "Vuilnis in $(building)", + mail_subject: "Vuilnis in $(gebouw_naam)", name: "Vuilnis", }, { - content: "In $(building) werkt $(code) niet meer", + content: "In $(gebouw_naam) werkt de code niet meer", id: 2, - mail_subject: "Code werkt niet in $(building)", + mail_subject: "Code werkt niet in $(gebouw_naam)", name: "Code", }, { content: - "Ivago heeft $(garbage_type) niet meegenomen bij $(building)", + "Ivago heeft de ingeplande container niet meegenomen bij $(gebouw_naam)", id: 3, - mail_subject: "Ivago is niet langs $(building) gekomen", + mail_subject: "Ivago is niet langs $(gebouw_naam) gekomen", name: "Ivago", }, ]; @@ -74,16 +74,16 @@ describe("Mail Template tests", () => { test("GET /mail_template with filter", async () => { const expected = [ { - content: "In $(building) werkt $(code) niet meer", + content: "In $(gebouw_naam) werkt de code niet meer", id: 2, - mail_subject: "Code werkt niet in $(building)", + mail_subject: "Code werkt niet in $(gebouw_naam)", name: "Code", }, { content: - "Ivago heeft $(garbage_type) niet meegenomen bij $(building)", + "Ivago heeft de ingeplande container niet meegenomen bij $(gebouw_naam)", id: 3, - mail_subject: "Ivago is niet langs $(building) gekomen", + mail_subject: "Ivago is niet langs $(gebouw_naam) gekomen", name: "Ivago", }, ]; @@ -99,8 +99,8 @@ describe("Mail Template tests", () => { { id: 1, name: "Vuilnis", - mail_subject: "Vuilnis in $(building)", - content: "In $(building) ligt er vuilnis op de grond", + mail_subject: "Vuilnis in $(gebouw_naam)", + content: "In $(gebouw_naam) ligt er vuilnis op de grond", }, ]; @@ -118,8 +118,8 @@ describe("Mail Template tests", () => { const expected = { id: 1, name: "Updated name mail template", - mail_subject: "Vuilnis in $(building)", - content: "In $(building) ligt er vuilnis op de grond", + mail_subject: "Vuilnis in $(gebouw_naam)", + content: "In $(gebouw_naam) ligt er vuilnis op de grond", }; await runner.patch({ @@ -137,15 +137,15 @@ describe("Mail Template tests", () => { { id: 2, name: "Code", - mail_subject: "Code werkt niet in $(building)", - content: "In $(building) werkt $(code) niet meer", + mail_subject: "Code werkt niet in $(gebouw_naam)", + content: "In $(gebouw_naam) werkt de code niet meer", }, { id: 3, name: "Ivago", - mail_subject: "Ivago is niet langs $(building) gekomen", + mail_subject: "Ivago is niet langs $(gebouw_naam) gekomen", content: - "Ivago heeft $(garbage_type) niet meegenomen bij $(building)", + "Ivago heeft de ingeplande container niet meegenomen bij $(gebouw_naam)", }, ]; await runner.get({ diff --git a/web/src/layouts/MainLayout.vue b/web/src/layouts/MainLayout.vue index 52978f004..a75b67eb6 100644 --- a/web/src/layouts/MainLayout.vue +++ b/web/src/layouts/MainLayout.vue @@ -136,6 +136,12 @@ title="Rondes" value="rounds" > + diff --git a/web/src/router/index.ts b/web/src/router/index.ts index c61d94beb..e736d0089 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -14,6 +14,7 @@ import BuildingScreen from "@/views/building/BuildingScreen.vue"; import BuildingFollowup from "@/views/building/BuildingFollowup.vue"; import GarbageMaker from "@/views/building/GarbageMaker.vue"; import UserOverview from "@/views/dashboard/Users.vue"; +import TemplateOverview from "@/views/dashboard/Template.vue"; import BuildingOverview from "@/views/dashboard/Buildings.vue"; import RoundOverview from "@/views/dashboard/Round.vue"; import ContactSyndicus from "@/views/contact/ContactSyndicus.vue"; @@ -186,7 +187,7 @@ const routes: any[] = [ }, }, { - path: "/contact", + path: "/contact/:id?", name: "contact_syndicus", component: ContactSyndicus, meta: { @@ -270,7 +271,7 @@ const routes: any[] = [ }, }, { - path: "/template/nieuw", + path: "/sjabloon/nieuw/:id?", component: TemplateBuilder, name: "template_new", meta: { @@ -283,6 +284,20 @@ const routes: any[] = [ ) => superstudent || admin, }, }, + { + path: "/sjabloon", + component: TemplateOverview, + name: "template_overview", + meta: { + title: "Sjablonen", + auth: ( + student: boolean, + superstudent: boolean, + syndicus: boolean, + admin: boolean, + ) => superstudent || admin, + }, + }, { path: "/:pathMatch(.*)*", component: PageNotFound, diff --git a/web/src/types/Template.ts b/web/src/types/Template.ts new file mode 100644 index 000000000..596233fb9 --- /dev/null +++ b/web/src/types/Template.ts @@ -0,0 +1,71 @@ +import { Header } from "@/components/table/Header"; +import { TableEntity } from "@/components/table/TableEntity"; +import { RowType } from "@/components/table/RowType"; +import { MailTemplateQuery, Result } from "@selab-2/groep-1-query"; +import { tryOrAlertAsync } from "@/try"; +import router from "@/router"; + +export class Template implements TableEntity> { + headers(): Array>> { + return Template.headers(); + } + + static headers(): Array>> { + return [ + { + id: 0, + name: "Template naam", + fit: false, + get: (e: Result) => e.name, + type: RowType.TEXT, + sortable: true, + }, + { + id: 1, + name: "", + fit: true, + get: () => "mdi-pencil", + type: RowType.ICONBUTTON, + sortable: false, + onClick: (e: Result) => { + router.push({ name: "template_new", params: { id: e.id } }); + }, + }, + { + id: 2, + name: "", + fit: true, + get: () => "mdi-delete", + type: RowType.ICONBUTTON, + sortable: false, + onClick: ( + e: Result, + list: Array | null>, + ) => { + tryOrAlertAsync(async () => { + await new MailTemplateQuery().deleteOne({ id: e.id }); + const index = list.findIndex((x) => x === e); + list[index] = null; + }); + }, + }, + ].map((e) => new Header>(e)); + } + + route(item: Result): { + name: string; + params: { id: number }; + } { + return Template.route(item); + } + + static route(item: Result): { + name: string; + params: { id: number }; + } { + return { + name: "building_id", + params: { id: item.id }, + }; + } +} diff --git a/web/src/views/building/BuildingScreen.vue b/web/src/views/building/BuildingScreen.vue index aa4b9f42a..61bf8b69a 100644 --- a/web/src/views/building/BuildingScreen.vue +++ b/web/src/views/building/BuildingScreen.vue @@ -256,18 +256,16 @@ function getBuildingDescription(): string { return castedBuilding.description; } +function mail() { + router.push({ name: "contact_syndicus", params: { id: building.value?.id } }); +} + function call(number: string | undefined) { if (number) { location.href = "tel:" + number; } } -function mail(address: string | undefined) { - if (address) { - location.href = "mailto:" + address; - } -} - function tomaps() { window.open( `https://maps.google.com/maps?q=${building.value?.address.number}+${building.value?.address.street},+${building.value?.address.city},+${building.value?.address.zip_code}`, diff --git a/web/src/views/contact/ContactSyndicus.vue b/web/src/views/contact/ContactSyndicus.vue index bd1adf3c3..714107485 100644 --- a/web/src/views/contact/ContactSyndicus.vue +++ b/web/src/views/contact/ContactSyndicus.vue @@ -41,16 +41,17 @@ - + @@ -63,35 +64,20 @@ class="flex-grow-1 flex-shrink-0 py-0 my-0" > - - Versturen @@ -106,47 +93,65 @@ diff --git a/web/src/views/contact/TemplateBuilder.vue b/web/src/views/contact/TemplateBuilder.vue index b059d0a0a..80e8497e3 100644 --- a/web/src/views/contact/TemplateBuilder.vue +++ b/web/src/views/contact/TemplateBuilder.vue @@ -24,6 +24,7 @@ style="min-width: 100px; max-width: 100%" class="flex-grow-1 flex-shrink-0 py-0 my-0 mx-3" > @@ -64,6 +65,7 @@ prepend-icon="mdi-content-save" variant="tonal" class="mb-6 ml-6" + @click="saveTemplate()" >Opslaan (""); const subject = ref(""); const body = ref(""); +const route = useRoute(); +const templateId: number = Number(route.params.id); + +if (templateId) { + tryOrAlertAsync(async () => { + const thisTemplate: Result = + await new MailTemplateQuery().getOne(templateId); + + templateName.value = thisTemplate.name; + subject.value = thisTemplate.mail_subject; + body.value = thisTemplate.content; + }); +} + const variables: { name: string; description: string }[] = [ { name: "$(syndicus_voornaam)", description: "Voornaam van een syndicus" }, { @@ -111,6 +131,35 @@ const variables: { name: string; description: string }[] = [ { name: "$(gebouw_adres)", description: "Adres van het gebouw" }, { name: "$(ivago_id)", description: "Ivago ID van het gebouw" }, ]; + +function saveTemplate() { + if (!templateId) { + tryOrAlertAsync(async () => { + await new MailTemplateQuery().createOne({ + name: templateName.value, + mail_subject: subject.value, + content: body.value, + }); + }); + clearForm(); + } else { + tryOrAlertAsync(async () => { + await new MailTemplateQuery().updateOne({ + id: templateId, + name: templateName.value, + mail_subject: subject.value, + content: body.value, + }); + }); + clearForm(); + } +} + +function clearForm() { + templateName.value = ""; + subject.value = ""; + body.value = ""; +}