From beb02b5c8e43fcbc867776cf590031b85149b84c Mon Sep 17 00:00:00 2001 From: Renaud Thiry Date: Wed, 8 Mar 2023 07:32:34 +0000 Subject: [PATCH] [FIX] mass_mailing: hide menu on mobile closes odoo/odoo#114543 Signed-off-by: Thibault Delavallee (tde) --- .../static/src/js/mass_mailing_html_field.js | 21 ++- .../tours/mass_mailing_snippets_menu_tabs.js | 141 ++++++++++++++++++ .../static/src/scss/mass_mailing.wysiwyg.scss | 7 +- addons/mass_mailing/tests/test_mailing_ui.py | 6 + addons/mass_mailing/views/snippets_themes.xml | 3 +- .../static/src/js/editor/snippets.editor.js | 68 ++++++--- .../static/src/js/wysiwyg/wysiwyg.js | 1 + 7 files changed, 218 insertions(+), 29 deletions(-) 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 9b11a75dcc5..ec769a058b5 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 @@ -46,10 +46,11 @@ export class MassMailingHtmlField extends HtmlField { return { ...super.wysiwygOptions, onIframeUpdated: () => this.onIframeUpdated(), + foldSnippets: device.isMobile, snippets: 'mass_mailing.email_designer_snippets', resizable: false, defaultDataForLinkTools: { isNewWindow: true }, - toolbarTemplate: 'mass_mailing.web_editor_toolbar', + toolbarTemplate: device.isMobile ? 'web_editor.toolbar' : 'mass_mailing.web_editor_toolbar', ...this.props.wysiwygOptions, }; } @@ -226,11 +227,6 @@ export class MassMailingHtmlField extends HtmlField { // Overide `d-flex` class which style is `!important` $snippetsSideBar.find(`.o_we_website_top_actions > *:not(${selectorToKeep})`).attr('style', 'display: none!important'); - if (device.isMobile) { - $snippetsSideBar.hide(); - this.wysiwyg.$iframe.attr('style', 'padding-left: 0px !important'); - } - if (!odoo.debug) { $snippetsSideBar.find('.o_codeview_btn').hide(); } @@ -269,7 +265,11 @@ export class MassMailingHtmlField extends HtmlField { if (!this._themeParams) { // Initialize theme parameters. this._themeClassNames = ""; - this._themeParams = _.map($themes, (theme) => { + const displayableThemes = + device.isMobile ? + _.filter($themes, theme => !$(theme).data("hideFromMobile")) : + $themes; + this._themeParams = _.map(displayableThemes, (theme) => { const $theme = $(theme); const name = $theme.data("name"); const classname = "o_" + name + "_theme"; @@ -335,6 +335,8 @@ export class MassMailingHtmlField extends HtmlField { const editableAreaIsEmpty = value === "" || value === blankEditable; if (editableAreaIsEmpty) { + // unfold to prevent toolbar from going over the menu + this.wysiwyg.snippetsMenu.setFolded(false); $themeSelectorNew.appendTo(this.wysiwyg.$iframeBody); } @@ -350,6 +352,9 @@ export class MassMailingHtmlField extends HtmlField { this.wysiwyg.$iframeBody.closest('body').removeClass("o_force_mail_theme_choice"); $themeSelectorNew.remove(); + if (device.isMobile) { + this.wysiwyg.snippetsMenu.setFolded(true); + } this._switchImages(themeParams, $snippets); @@ -375,6 +380,8 @@ export class MassMailingHtmlField extends HtmlField { selection.removeAllRanges(); selection.addRange(range); } + // mark selection done for tour testing + $editable.addClass('theme_selection_done'); }, 0); }); diff --git a/addons/mass_mailing/static/src/js/tours/mass_mailing_snippets_menu_tabs.js b/addons/mass_mailing/static/src/js/tours/mass_mailing_snippets_menu_tabs.js index 31a91c04f3b..5e3c0b3051a 100644 --- a/addons/mass_mailing/static/src/js/tours/mass_mailing_snippets_menu_tabs.js +++ b/addons/mass_mailing/static/src/js/tours/mass_mailing_snippets_menu_tabs.js @@ -51,3 +51,144 @@ registry.category("web_tour.tours").add('mass_mailing_snippets_menu_tabs', { }, ...stepUtils.discardForm(), ]}); + + + +registry.category("web_tour.tours").add('mass_mailing_snippets_menu_toolbar_new_mailing_mobile', { + test: true, + url: '/web', + steps: [ + stepUtils.showAppsMenuItem(), { + content: "Select the 'Email Marketing' app.", + trigger: '.o_app[data-menu-xmlid="mass_mailing.mass_mailing_menu_root"]', + }, + { + content: "Click on the create button to create a new mailing.", + trigger: 'button.o_list_button_add', + mobile: true, + }, + { + content: "Check templates available in theme selector", + trigger: 'iframe .o_mail_theme_selector_new', + run: function () { + if (this.$anchor[0].querySelector('#empty')) { + console.error('The empty template should not be visible on mobile.'); + } + }, + mobile: true, + }, + { + content: "Make sure the toolbar isn't floating", + trigger: 'iframe', + run: function () { + const iframeDocument = this.$anchor[0].contentDocument; + if (iframeDocument.querySelector('#toolbar.oe-floating')) { + console.error('There should not be a floating toolbar in the iframe'); + } + }, + mobile: true, + }, + { + content: "Click on the 'Start From Scratch' template.", + trigger: 'iframe #default', + mobile: true, + }, + { + content: "Select an editable element", + trigger: 'iframe .s_text_block', + mobile: true, + }, + { + content: "Make sure the snippets menu is hidden", + trigger: 'iframe', + run: function () { + const iframeDocument = this.$anchor[0].contentDocument; + if (!iframeDocument.querySelector('#oe_snippets.d-none')) { + console.error('The snippet menu should be hidden'); + } + }, + mobile: true, + }, + { + content: "Make sure the toolbar is there", + trigger: 'iframe #toolbar.oe-floating', + run: () => null, // it's a check + mobile: true, + }, + ...stepUtils.discardForm().map(command => ({...command, mobile: true})), + ] +}); + +registry.category("web_tour.tours").add('mass_mailing_snippets_menu_toolbar', { + test: true, + url: '/web', + steps: [ + stepUtils.showAppsMenuItem(), { + content: "Select the 'Email Marketing' app.", + trigger: '.o_app[data-menu-xmlid="mass_mailing.mass_mailing_menu_root"]', + }, + { + content: "Click on the create button to create a new mailing.", + trigger: 'button.o_list_button_add', + }, + { + content: "Wait for the theme selector to load.", + trigger: 'iframe .o_mail_theme_selector_new', + }, + { + content: "Make sure there does not exist a floating toolbar", + trigger: 'iframe', + run: function () { + const iframeDocument = this.$anchor[0].contentDocument; + if (iframeDocument.querySelector('#toolbar.oe-floating')) { + console.error('There should not be a floating toolbar in the iframe'); + } + }, + }, + { + content: "Make sure the empty template is an option on non-mobile devices.", + trigger: 'iframe #empty', + run: () => null, + }, + { + content: "Click on the default 'welcome' template.", + trigger: 'iframe #default', + }, + { // necessary to wait for the cursor to be placed in the first p + // and to avoid leaving the page before the selection is added + content: "Wait for template selection event to be over.", + trigger: 'iframe .o_editable.theme_selection_done', + }, + { + content: "Make sure the snippets menu is not hidden", + trigger: 'iframe #oe_snippets:not(.d-none)', + run: () => null, + }, + { + content: "Wait for .s_text_block to be populated", + trigger: 'iframe .s_text_block p', + run: () => null, + }, + { + content: "Click and select p block inside the editor", + trigger: 'iframe', + run: function () { + const iframeWindow = this.$anchor[0].contentWindow; + const iframeDocument = iframeWindow.document; + const p = iframeDocument.querySelector('.s_text_block p'); + p.click(); + const selection = iframeWindow.getSelection(); + const range = iframeDocument.createRange(); + range.selectNodeContents(p); + selection.removeAllRanges(); + selection.addRange(range); + }, + }, + { + content: "Make sure the toolbar is there", + trigger: 'iframe #oe_snippets .o_we_customize_panel #toolbar', + run: () => null, + }, + ...stepUtils.discardForm(), + ], +}); diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.wysiwyg.scss b/addons/mass_mailing/static/src/scss/mass_mailing.wysiwyg.scss index abdeb37b90e..3110f492044 100644 --- a/addons/mass_mailing/static/src/scss/mass_mailing.wysiwyg.scss +++ b/addons/mass_mailing/static/src/scss/mass_mailing.wysiwyg.scss @@ -1,10 +1,13 @@ -.o_mass_mailing_iframe body { +// padding for snippets only if editor has snippets (not on mobile) +// (not reactive as hiding the menu itself isn't reactive) +.o_mass_mailing_iframe body.editor_has_snippets { padding-right: $o-we-sidebar-width !important; #web_editor-top-edit .note-popover .popover { right: $o-we-sidebar-width !important; } - +} +.o_mass_mailing_iframe body { .modal:not(.o_technical_modal) { top: 0 !important; // set z-index so customize options visible on dialog. diff --git a/addons/mass_mailing/tests/test_mailing_ui.py b/addons/mass_mailing/tests/test_mailing_ui.py index f04e4422cbd..a02b1b52640 100644 --- a/addons/mass_mailing/tests/test_mailing_ui.py +++ b/addons/mass_mailing/tests/test_mailing_ui.py @@ -27,3 +27,9 @@ class TestUi(HttpCaseWithUserDemo): def test_02_mass_mailing_snippets_menu_tabs(self): self.start_tour("/web", 'mass_mailing_snippets_menu_tabs', login="demo") + + def test_03_mass_mailing_snippets_toolbar_mobile_hide(self): + self.start_tour("/web", 'mass_mailing_snippets_menu_toolbar_new_mailing_mobile', login="demo") + + def test_04_mass_mailing_snippets_menu_hide(self): + self.start_tour("/web", 'mass_mailing_snippets_menu_toolbar', login="demo") diff --git a/addons/mass_mailing/views/snippets_themes.xml b/addons/mass_mailing/views/snippets_themes.xml index 839ac65ccd5..078cf2ff991 100644 --- a/addons/mass_mailing/views/snippets_themes.xml +++ b/addons/mass_mailing/views/snippets_themes.xml @@ -34,7 +34,8 @@
+ data-images-info='{"logo": {"format": "png"}}' + data-hide-from-mobile="true">
'); + const $title = $("" + titleText + ""); + this._$toolbarContainer.append($title); + this._$toolbarContainer.append(this.options.wysiwyg.toolbar.$el); + $(this.customizePanel).append(this._$toolbarContainer); - // Create toolbar custom container. - this._$toolbarContainer = $(''); - const $title = $("" + titleText + ""); - - this._$toolbarContainer.append($title); - this._$toolbarContainer.append(this.options.wysiwyg.toolbar.$el); - $(this.customizePanel).append(this._$toolbarContainer); - - // Create table-options custom container. - const $customizeTableBlock = $(QWeb.render('web_editor.toolbar.table-options')); - this.options.wysiwyg.odooEditor.bindExecCommand($customizeTableBlock[0]); - - $(this.customizePanel).append($customizeTableBlock); - - this._$removeFormatButton = this._$removeFormatButton || this.options.wysiwyg.toolbar.$el.find('#removeFormat'); - $title.append(this._$removeFormatButton); + // Create table-options custom container. + const $customizeTableBlock = $(QWeb.render('web_editor.toolbar.table-options')); + this.options.wysiwyg.odooEditor.bindExecCommand($customizeTableBlock[0]); + $(this.customizePanel).append($customizeTableBlock); + this._$removeFormatButton = this.options.wysiwyg.toolbar.$el.find('#removeFormat'); + $title.append(this._$removeFormatButton); + this._$toolbarContainer.append(this.options.wysiwyg.toolbar.$el); + } this._checkEditorToolbarVisibility(); }, + _addToolbarToOriginalPosition: function () { + const toolbar = this.options.wysiwyg.toolbar.el; + toolbar.classList.add('oe-floating'); + if (this.options.wysiwyg.odooEditor.isMobile) { + const editorEditable = this.options.wysiwyg.odooEditor.editable; + editorEditable.before(toolbar); + } else if (this.options.autohideToolbar) { + document.body.appendChild(toolbar); + } + }, /** * Update editor UI visibility based on the current range. */ diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index d3381c0a788..fd5e93eb1a3 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -224,6 +224,7 @@ const Wysiwyg = Widget.extend({ collaborationClientAvatarUrl: `${browser.location.origin}/web/image?model=res.users&field=avatar_128&id=${this.getSession().uid}`, renderingClasses: ['o_dirty', 'o_transform_removal', 'oe_edited_link', 'o_menu_loading'], dropImageAsAttachment: options.dropImageAsAttachment, + foldSnippets: !!options.foldSnippets, }, editorCollaborationOptions)); this.odooEditor.addEventListener('contentChanged', function () {