From 78a9d206c3e6c5e1a803ec6771762faf5c9dcef5 Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Sun, 22 Dec 2024 10:29:31 +0100 Subject: [PATCH] template storing --- .../settings/template/CreateTemplateModal.vue | 79 +++++++++ .../settings/template/DeleteTemplateModal.vue | 73 ++++++++ .../settings/template/TemplateListItem.vue | 54 ++++++ src/helpers/unlayerEditor.ts | 72 ++++++++ src/router/index.ts | 14 +- src/stores/admin/template.ts | 55 ++++++ src/types/permissionTypes.ts | 5 +- src/viewmodels/admin/template.models.ts | 24 +++ .../admin/settings/template/Template.vue | 86 ++++------ .../admin/settings/template/TemplateEdit.vue | 158 ++++++++++++++++++ .../admin/settings/template/UsageInfo.vue | 24 +++ 11 files changed, 581 insertions(+), 63 deletions(-) create mode 100644 src/components/admin/settings/template/CreateTemplateModal.vue create mode 100644 src/components/admin/settings/template/DeleteTemplateModal.vue create mode 100644 src/components/admin/settings/template/TemplateListItem.vue create mode 100644 src/stores/admin/template.ts create mode 100644 src/viewmodels/admin/template.models.ts create mode 100644 src/views/admin/settings/template/TemplateEdit.vue create mode 100644 src/views/admin/settings/template/UsageInfo.vue diff --git a/src/components/admin/settings/template/CreateTemplateModal.vue b/src/components/admin/settings/template/CreateTemplateModal.vue new file mode 100644 index 0000000..4f10366 --- /dev/null +++ b/src/components/admin/settings/template/CreateTemplateModal.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/components/admin/settings/template/DeleteTemplateModal.vue b/src/components/admin/settings/template/DeleteTemplateModal.vue new file mode 100644 index 0000000..cd42728 --- /dev/null +++ b/src/components/admin/settings/template/DeleteTemplateModal.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/components/admin/settings/template/TemplateListItem.vue b/src/components/admin/settings/template/TemplateListItem.vue new file mode 100644 index 0000000..a9ed5d4 --- /dev/null +++ b/src/components/admin/settings/template/TemplateListItem.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/src/helpers/unlayerEditor.ts b/src/helpers/unlayerEditor.ts index 1b5afb7..3fd1871 100644 --- a/src/helpers/unlayerEditor.ts +++ b/src/helpers/unlayerEditor.ts @@ -1,3 +1,4 @@ +import type { EmailEditor } from "vue-email-editor"; import type { EmailEditorProps } from "vue-email-editor/dist/components/types"; export const options: EmailEditorProps["options"] = { @@ -26,3 +27,74 @@ export const options: EmailEditorProps["options"] = { }, customJS: [window.location.origin + "/unlayerTool.js"], }; + +export function configureEditor(editor: typeof EmailEditor): void { + editor.editor.setBodyValues({ + contentWidth: "100%", + backgroundColor: "#ffffff", + linkStyle: { + linkColor: "#990b00", + linkHoverColor: "#bb1e10", + linkUnderline: false, + linkHoverUnderline: false, + }, + }); +} + +export function loadEditor(editor: typeof EmailEditor, design: object | undefined = undefined): void { + if (design === undefined) { + editor.editor.loadBlank(); + } else { + editor.editor.loadDesign(design); + } +} + +export function exportEditor(editor: typeof EmailEditor): { + design: object; + headerHTML: string; + bodyHTML: string; + footerHTML: string; +} { + let savedDesign: any = undefined; + let savedHeader: string = ""; + let savedBody: string = ""; + let savedFooter: string = ""; + + editor.editor.saveDesign((design: any) => { + savedDesign = design; + }); + + editor.editor.exportHtml( + (data: any) => { + savedHeader = data; + }, + { + minify: true, + onlyHeader: true, + } + ); + editor.editor.exportHtml( + (data: any) => { + savedBody = data; + }, + { + minify: true, + } + ); + editor.editor.exportHtml( + (data: any) => { + savedFooter = data; + }, + { + minify: true, + onlyFooter: true, + } + ); + + return { + design: savedDesign, + headerHTML: savedHeader, + bodyHTML: savedBody, + footerHTML: savedFooter, + }; +} diff --git a/src/router/index.ts b/src/router/index.ts index e0d4bd8..b520eeb 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -407,7 +407,7 @@ const router = createRouter({ path: "template", name: "admin-settings-template-route", component: () => import("@/views/RouterView.vue"), - // meta: { type: "read", section: "settings", module: "template" }, + meta: { type: "read", section: "settings", module: "template" }, beforeEnter: [abilityAndNavUpdate], children: [ { @@ -415,12 +415,18 @@ const router = createRouter({ name: "admin-settings-template", component: () => import("@/views/admin/settings/template/Template.vue"), }, + { + path: "info", + name: "admin-settings-template-info", + component: () => import("@/views/admin/settings/template/UsageInfo.vue"), + props: true, + }, { path: ":id/edit", name: "admin-settings-template-edit", - component: () => import("@/views/admin/settings/template/Template.vue"), - // meta: { type: "update", section: "settings", module: "template" }, - // beforeEnter: [abilityAndNavUpdate], + component: () => import("@/views/admin/settings/template/TemplateEdit.vue"), + meta: { type: "update", section: "settings", module: "template" }, + beforeEnter: [abilityAndNavUpdate], props: true, }, ], diff --git a/src/stores/admin/template.ts b/src/stores/admin/template.ts new file mode 100644 index 0000000..1dd0edc --- /dev/null +++ b/src/stores/admin/template.ts @@ -0,0 +1,55 @@ +import { defineStore } from "pinia"; +import { http } from "@/serverCom"; +import type { AxiosResponse } from "axios"; +import type { CreateTemplateViewModel, UpdateTemplateViewModel } from "../../viewmodels/admin/template.models"; + +export const useTemplateStore = defineStore("template", { + state: () => { + return { + templates: [] as Array, + loading: "loading" as "loading" | "fetched" | "failed", + }; + }, + actions: { + fetchTemplates() { + this.loading = "loading"; + http + .get("/admin/template") + .then((result) => { + this.templates = result.data; + this.loading = "fetched"; + }) + .catch((err) => { + this.loading = "failed"; + }); + }, + fetchTemplateById(id: number): Promise> { + return http.get(`/admin/template/${id}`); + }, + async createTemplate(template: CreateTemplateViewModel): Promise> { + const result = await http.post(`/admin/template`, { + template: template.template, + description: template.description, + }); + this.fetchTemplates(); + return result; + }, + async updateActiveTemplate(template: UpdateTemplateViewModel): Promise> { + const result = await http.patch(`/admin/template/${template.id}`, { + template: template.template, + description: template.description, + design: template.design, + headerHTML: template.headerHTML, + bodyHTML: template.bodyHTML, + footerHTML: template.footerHTML, + }); + this.fetchTemplates(); + return result; + }, + async deleteTemplate(template: number): Promise> { + const result = await http.delete(`/admin/template/${template}`); + this.fetchTemplates(); + return result; + }, + }, +}); diff --git a/src/types/permissionTypes.ts b/src/types/permissionTypes.ts index d5bb35e..62fbc51 100644 --- a/src/types/permissionTypes.ts +++ b/src/types/permissionTypes.ts @@ -14,7 +14,8 @@ export type PermissionModule = | "user" | "role" | "query" - | "query_store"; + | "query_store" + | "template"; export type PermissionType = "read" | "create" | "update" | "delete"; @@ -53,6 +54,7 @@ export const permissionModules: Array = [ "role", "query", "query_store", + "template", ]; export const permissionTypes: Array = ["read", "create", "update", "delete"]; export const sectionsAndModules: SectionsAndModulesObject = { @@ -65,6 +67,7 @@ export const sectionsAndModules: SectionsAndModulesObject = { "membership_status", "calendar_type", "query_store", + "template", ], user: ["user", "role"], }; diff --git a/src/viewmodels/admin/template.models.ts b/src/viewmodels/admin/template.models.ts new file mode 100644 index 0000000..65833c3 --- /dev/null +++ b/src/viewmodels/admin/template.models.ts @@ -0,0 +1,24 @@ +export interface TemplateViewModel { + id: number; + template: string; + description: string | null; + design: object; + headerHTML: string; + bodyHTML: string; + footerHTML: string; +} + +export interface CreateTemplateViewModel { + template: string; + description: string | null; +} + +export interface UpdateTemplateViewModel { + id: number; + template: string; + description: string | null; + design: object; + headerHTML: string; + bodyHTML: string; + footerHTML: string; +} diff --git a/src/views/admin/settings/template/Template.vue b/src/views/admin/settings/template/Template.vue index 44ff19f..56cea4b 100644 --- a/src/views/admin/settings/template/Template.vue +++ b/src/views/admin/settings/template/Template.vue @@ -3,22 +3,20 @@ @@ -26,61 +24,33 @@ + + diff --git a/src/views/admin/settings/template/UsageInfo.vue b/src/views/admin/settings/template/UsageInfo.vue new file mode 100644 index 0000000..7dc02b4 --- /dev/null +++ b/src/views/admin/settings/template/UsageInfo.vue @@ -0,0 +1,24 @@ + + +