diff --git a/apps/ops/package-lock.json b/apps/ops/package-lock.json index 225624c..4b0a620 100644 --- a/apps/ops/package-lock.json +++ b/apps/ops/package-lock.json @@ -22,6 +22,7 @@ "sip.js": "^0.21.2", "vue": "^3.4.21", "vue-chartjs": "^5.3.3", + "vue-email-editor": "^2.2.0", "vue-router": "^4.3.0", "vuedraggable": "^4.1.0" }, @@ -2909,6 +2910,12 @@ "dev": true, "license": "ISC" }, + "node_modules/@unlayer/types": { + "version": "1.413.0", + "resolved": "https://registry.npmjs.org/@unlayer/types/-/types-1.413.0.tgz", + "integrity": "sha512-pOE9lKvP7ofnmfWZN+PTizw2GrwZNtePiMH3Yl8OSt/nYQL52X7N4SHd7dDd2c7ecJwWVWo8MfPY8QTon+44lw==", + "license": "MIT" + }, "node_modules/@vitejs/plugin-vue": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.4.tgz", @@ -9606,6 +9613,17 @@ } } }, + "node_modules/vue-email-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vue-email-editor/-/vue-email-editor-2.2.0.tgz", + "integrity": "sha512-aEXm0OHjZgeQqGsssfukqJm7kubfGBOPo9ddwGHMXLbzegJDZ0ou2h7NmRvPR+XaoRGYHdZXf9p7zVae5ACgWA==", + "dependencies": { + "@unlayer/types": "^1.394.0" + }, + "peerDependencies": { + "vue": "^3.2.13" + } + }, "node_modules/vue-eslint-parser": { "version": "9.4.3", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", diff --git a/apps/ops/package.json b/apps/ops/package.json index 08ea24d..bfec0b7 100644 --- a/apps/ops/package.json +++ b/apps/ops/package.json @@ -24,6 +24,7 @@ "sip.js": "^0.21.2", "vue": "^3.4.21", "vue-chartjs": "^5.3.3", + "vue-email-editor": "^2.2.0", "vue-router": "^4.3.0", "vuedraggable": "^4.1.0" }, diff --git a/apps/ops/src/api/campaigns.js b/apps/ops/src/api/campaigns.js index 979c2ac..bdaae66 100644 --- a/apps/ops/src/api/campaigns.js +++ b/apps/ops/src/api/campaigns.js @@ -107,10 +107,13 @@ export function getTemplate (name) { return hubFetch(`/campaigns/templates/${encodeURIComponent(name)}`) } -// saveTemplate(name, content) — content interpreted as HTML by default. -// Pass { format: 'mjml' } to send as MJML source (hub compiles to HTML). -export function saveTemplate (name, content, { format = 'html' } = {}) { +// saveTemplate(name, content, opts) — content is HTML by default. +// Optional opts.design = Unlayer design JSON (persisted alongside HTML so the +// editor can re-load the visual state on next open). +// Legacy opts.format = 'mjml' still supported for older callers (sends mjml). +export function saveTemplate (name, content, { format = 'html', design = null } = {}) { const body = format === 'mjml' ? { mjml: content } : { html: content } + if (design) body.design = design return hubFetch(`/campaigns/templates/${encodeURIComponent(name)}`, { method: 'PUT', body, diff --git a/apps/ops/src/modules/campaigns/pages/TemplateEditorPage.vue b/apps/ops/src/modules/campaigns/pages/TemplateEditorPage.vue index 443f00d..31fdc7c 100644 --- a/apps/ops/src/modules/campaigns/pages/TemplateEditorPage.vue +++ b/apps/ops/src/modules/campaigns/pages/TemplateEditorPage.vue @@ -1,40 +1,38 @@