[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) <tde@openerp.com>
This commit is contained in:
Patrick Hoste
2022-10-02 12:19:41 +02:00
committed by Jérémy Hennecart (jeh)
parent 6e81d6c278
commit 34f1274fe6
6 changed files with 139 additions and 1 deletions
+2
View File
@@ -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',
+13 -1
View File
@@ -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')
@@ -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;
}
@@ -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 '<!DOCTYPE html><html>' +
'<head>' + this.styleSheets + '</head>' +
'<body>' + this.props.preview + '</body>' +
'</html>';
}
}
MassMailingMobilePreviewDialog.props = {
...Dialog.props,
preview: { type: String },
close: Function,
};
delete MassMailingMobilePreviewDialog.props.slots;
@@ -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;
}
}
}
}
@@ -7,6 +7,9 @@
<button class="o_codeview_btn btn btn-primary">
<i class="fa fa-code"></i>
</button>
<button class="o_mobile_preview_btn btn btn-primary">
<i class="fa fa-lg fa-mobile"/>
</button>
<button class="o_fullscreen_btn btn btn-primary">
<img src="/web_editor/font_to_img/61541/rgb(255,255,255)/16" alt="Fullscreen"/>
</button>