From 34f1274fe69f37da3fcafb8502048e973b598db0 Mon Sep 17 00:00:00 2001 From: Patrick Hoste Date: Thu, 5 May 2022 08:50:37 +0000 Subject: [PATCH] [IMP] mass_mailing: add a mobile preview to mailing editor PURPOSE With this commit you can now see how the mailing you're creating will look like on a mobile. LINKS Task-2818037 closes odoo/odoo#101822 X-original-commit: 2b195390e15c9ed3b54f0adf0afc439f06429616 Signed-off-by: Thibault Delavallee (tde) --- addons/mass_mailing/__manifest__.py | 2 + addons/mass_mailing/controllers/main.py | 14 +++- .../static/src/js/mass_mailing_html_field.js | 13 ++++ .../src/js/mass_mailing_mobile_preview.js | 43 ++++++++++++ .../src/scss/mass_mailing_mobile_preview.scss | 65 +++++++++++++++++++ addons/mass_mailing/views/snippets_themes.xml | 3 + 6 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 addons/mass_mailing/static/src/js/mass_mailing_mobile_preview.js create mode 100644 addons/mass_mailing/static/src/scss/mass_mailing_mobile_preview.scss diff --git a/addons/mass_mailing/__manifest__.py b/addons/mass_mailing/__manifest__.py index abb42bde154..6e679ee78c6 100644 --- a/addons/mass_mailing/__manifest__.py +++ b/addons/mass_mailing/__manifest__.py @@ -89,11 +89,13 @@ 'mass_mailing/static/src/scss/mailing_filter_widget.scss', 'mass_mailing/static/src/scss/mass_mailing.scss', 'mass_mailing/static/src/scss/mass_mailing_mobile.scss', + 'mass_mailing/static/src/scss/mass_mailing_mobile_preview.scss', 'mass_mailing/static/src/css/email_template.css', 'mass_mailing/static/src/views/*.js', 'mass_mailing/static/src/js/mailing_m2o_filter.js', 'mass_mailing/static/src/js/mass_mailing.js', 'mass_mailing/static/src/js/mass_mailing_design_constants.js', + 'mass_mailing/static/src/js/mass_mailing_mobile_preview.js', 'mass_mailing/static/src/js/mass_mailing_html_field.js', 'mass_mailing/static/src/js/mailing_mailing_view_form_full_width.js', 'mass_mailing/static/src/js/mailing_portal.js', diff --git a/addons/mass_mailing/controllers/main.py b/addons/mass_mailing/controllers/main.py index 5f6a42b11ec..05401375eb1 100644 --- a/addons/mass_mailing/controllers/main.py +++ b/addons/mass_mailing/controllers/main.py @@ -7,7 +7,7 @@ import werkzeug from odoo import _, exceptions, http, tools from odoo.http import request from odoo.tools import consteq -from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequest, NotFound class MassMailController(http.Controller): @@ -216,3 +216,15 @@ class MassMailController(http.Controller): _("""Requested de-blacklisting via unsubscription page.""")) return True return 'error' + + # ------------------------------------------------------------ + # MISCELLANEOUS + # ------------------------------------------------------------ + + @http.route('/mailing/get_preview_assets', type='json', auth='user') + def get_mobile_preview_styling(self): + """ This route allows a rpc call to get the styling needed for email template conversion. + We do this to avoid duplicating the template.""" + if not request.env.user.has_group('mass_mailing.group_mass_mailing_user'): + raise NotFound + return request.env['ir.qweb']._render('mass_mailing.iframe_css_assets_edit') diff --git a/addons/mass_mailing/static/src/js/mass_mailing_html_field.js b/addons/mass_mailing/static/src/js/mass_mailing_html_field.js index 6e22e4d8566..21f86b1a657 100644 --- a/addons/mass_mailing/static/src/js/mass_mailing_html_field.js +++ b/addons/mass_mailing/static/src/js/mass_mailing_html_field.js @@ -12,6 +12,7 @@ import { buildQuery } from "web.rpc"; import { HtmlField } from "@web_editor/js/backend/html_field"; import { getWysiwygClass } from 'web_editor.loader'; import { device } from 'web.config'; +import { MassMailingMobilePreviewDialog } from "./mass_mailing_mobile_preview"; const { useEffect, @@ -24,6 +25,7 @@ export class MassMailingHtmlField extends HtmlField { this.action = useService('action'); this.rpc = useService('rpc'); + this.dialog = useService('dialog'); onWillUpdateProps(() => { if (this.props.record.data.mailing_model_id && this.wysiwyg) { @@ -212,6 +214,17 @@ export class MassMailingHtmlField extends HtmlField { this.onIframeUpdated(); }); + $snippetsSideBar.on('click', '.o_mobile_preview_btn', () => { + let mailingHtml = new DOMParser().parseFromString(this.wysiwyg.getValue(), 'text/html'); + [...mailingHtml.querySelectorAll('a')].forEach(el => { + el.style.setProperty('pointer-events', 'none'); + }); + this.mobilePreview = this.dialog.add(MassMailingMobilePreviewDialog, { + title: this.env._t("Mobile Preview"), + preview: mailingHtml.body.innerHTML, + }); + }); + if ($themes.length === 0) { return; } diff --git a/addons/mass_mailing/static/src/js/mass_mailing_mobile_preview.js b/addons/mass_mailing/static/src/js/mass_mailing_mobile_preview.js new file mode 100644 index 00000000000..fa29ac7c7d0 --- /dev/null +++ b/addons/mass_mailing/static/src/js/mass_mailing_mobile_preview.js @@ -0,0 +1,43 @@ +/** @odoo-module **/ + +import { useService } from "@web/core/utils/hooks"; +import { Dialog } from "@web/core/dialog/dialog"; +const { useEffect, onWillStart } = owl; + +export class MassMailingMobilePreviewDialog extends Dialog { + setup() { + super.setup(); + this.rpc = useService("rpc"); + onWillStart(async () => { + this.styleSheets = await this.rpc("/mailing/get_preview_assets"); + }); + useEffect((modalEl) => { + if (modalEl) { + const modalBody = modalEl.querySelector('.modal-body'); + const invertIcon = document.createElement("span"); + invertIcon.className = "fa fa-refresh"; + const iframe = document.createElement("iframe"); + iframe.srcdoc = this._getSourceDocument(); + + modalEl.classList.add('o_mailing_mobile_preview'); + modalEl.querySelector('.modal-title').append(invertIcon); + modalEl.querySelector('.modal-header').addEventListener('click', () => modalBody.classList.toggle('o_invert_orientation')); + modalBody.append(iframe); + } + }, () => [document.querySelector('.o_dialog')]); + } + + _getSourceDocument() { + return '' + + '' + this.styleSheets + '' + + '' + this.props.preview + '' + + ''; + } +} + +MassMailingMobilePreviewDialog.props = { + ...Dialog.props, + preview: { type: String }, + close: Function, +}; +delete MassMailingMobilePreviewDialog.props.slots; diff --git a/addons/mass_mailing/static/src/scss/mass_mailing_mobile_preview.scss b/addons/mass_mailing/static/src/scss/mass_mailing_mobile_preview.scss new file mode 100644 index 00000000000..675da25c00b --- /dev/null +++ b/addons/mass_mailing/static/src/scss/mass_mailing_mobile_preview.scss @@ -0,0 +1,65 @@ +.o_mailing_mobile_preview { + text-align: center; + user-select: none; + + .modal-dialog { + display: inline-block; + width: auto; + + .modal-content { + background-color: black!important; + border: 3px outset gray; + border-radius: 20px; + + .modal-header { + border: none; + color: white; + cursor: pointer; + font-family: $o-we-font-family; + + .btn-close { + filter: invert(1) grayscale(100%) brightness(200%); + } + + h4 { + font-family: inherit; + font-weight: normal; + color: inherit; + + .fa { + margin-left: $grid-gutter-width/2; + } + } + } + + .modal-body { + background-color: inherit!important; + border-radius: 20px; + padding: 15px; + + $mobile-preview-width: 30vh; + $mobile-preview-height: 70vh; + + display: flex; + width: $mobile-preview-width + 15; + height: $mobile-preview-height; + transition: all 400ms ease 0s; + + &.o_invert_orientation { + width: $mobile-preview-height; + height: $mobile-preview-width + 15; + } + + > iframe { + display: block; + width: 100%; + border: none; + } + } + + .modal-footer { + display: none; + } + } + } +} diff --git a/addons/mass_mailing/views/snippets_themes.xml b/addons/mass_mailing/views/snippets_themes.xml index e5582c16bb4..21d34284545 100644 --- a/addons/mass_mailing/views/snippets_themes.xml +++ b/addons/mass_mailing/views/snippets_themes.xml @@ -7,6 +7,9 @@ +