From a3ce4cd29dd201ca3ba1cdf5fcb7bf2e68c3c2c2 Mon Sep 17 00:00:00 2001 From: "Louis (loco)" <loco@odoo.com> Date: Tue, 21 Mar 2023 15:58:18 +0000 Subject: [PATCH] [FIX] *: display the correct eye icon of the invisible elements *web_editor, website Steps to reproduce the bug: - Add a Text-Image snippet. - Change its visibility to "Conditionally". - Save. - Edit again. => The eye icon indicates that the snippet is not visible but the snippet is displayed. Note that [1] introduced a mechanism to solve this problem (the `cleanForSave()` of the `ConditionalVisibility` option) but the code was not working correctly since [2]. Let's first remember that when calling `toggleTargetVisibility()`, two main actions are performed: - The addition or suppression of the `data-invisible` attribute from the dataset of an invisible element. This attribute is responsible for the crossed or not of the eye icon in the "Invisible Elements" panel. - The call to `onTargetHide()` or `onTargetShow()` that performs among other things the addition or the suppression of the `o_conditional_hidden` class on an invisible element. This class is responsible for the visibility of the element on the page in edit mode. This being said, here is what happened at the "Save" before this commit: - `cleanForSave()` of `snippetEditor` is called. If the related element has the `o_snippet_invisible` class, `toggleTargetVisibility(false)` is called (meaning that the `o_conditional_hidden` class and the `data-invisible` attribute are added to the element). - `cleanForSave()` of the `ConditionalVisibility` option is called and before [2], the `data-invisible` attribute was removed from the corresponding element. - At the `DOMContentLoaded`, the `o_conditional_hidden` class is removed from all the elements that have a conditional visibility. The visibility of those elements on the page now depends on the rule set by the user. The goal of this commit is to restore the mechansim of the remove of the `data-invisible` attribute from the conditionnal elements at the `cleanForSave()`. [1]: https://github.com/odoo/odoo/commit/1c442782f887a8c16bae05a43fae13a310ac05df [2]: https://github.com/odoo/odoo/commit/de3c29fab2bc5349da8a9418f9d0086d76e6f7de task-3203914 Part-of: odoo/odoo#113549 --- .../static/src/js/editor/snippets.editor.js | 4 + .../static/src/js/editor/snippets.options.js | 10 +-- .../tests/tours/conditional_visibility.js | 73 +++++++++++++++++++ addons/website/tests/test_ui.py | 1 + 4 files changed, 80 insertions(+), 8 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index d551682a3567..c73994f28951 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -1618,6 +1618,10 @@ var SnippetsMenu = Widget.extend({ .removeProp('contentEditable'); this.getEditableArea().find('.o_we_selected_image') .removeClass('o_we_selected_image'); + [...this.getEditableArea()].forEach(editableAreaEl => { + editableAreaEl.querySelectorAll("[data-visibility='conditional']") + .forEach(invisibleEl => delete invisibleEl.dataset.invisible); + }); }, /** * Load snippets. diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index a516ba9906c6..7d6de6ef4e89 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -3084,17 +3084,11 @@ options.registry.ConditionalVisibility = options.Class.extend({ async onTargetShow() { this.$target[0].classList.remove('o_conditional_hidden'); }, + // Todo: remove me in master. /** * @override */ - cleanForSave() { - // Kinda hacky: the snippet is forced hidden via onTargetHide on save - // but should be marked as visible as when entering edit mode later, the - // snippet will be shown naturally (as the CSS rules won't apply). - // Without this, the "eye" icon of the visibility panel would be shut - // when entering edit mode. - this.trigger_up('snippet_option_visibility_update', { show: true }); - }, + cleanForSave() {}, //-------------------------------------------------------------------------- // Options diff --git a/addons/website/static/tests/tours/conditional_visibility.js b/addons/website/static/tests/tours/conditional_visibility.js index 1487df688272..da7f2fa552a2 100644 --- a/addons/website/static/tests/tours/conditional_visibility.js +++ b/addons/website/static/tests/tours/conditional_visibility.js @@ -8,7 +8,27 @@ const snippets = [ id: 's_text_image', name: 'Text - Image', }, + { + id: "s_banner", + name: "Banner", + }, + { + id: "s_popup", + name: "Popup", + }, ]; +function checkEyeIcon(snippetName, visible) { + const eyeIcon = visible ? "fa-eye" : "fa-eye-slash"; + const openOrClose = visible ? "open" : "close"; + const endExplanation = `should be ${openOrClose} in the "Invisible Elements" panel`; + const invisibleElPanel = "o_we_invisible_el_panel"; + return { + content: `The eye icon of ${snippetName} ${endExplanation}`, + trigger: + `.${invisibleElPanel} .o_we_invisible_entry:contains("${snippetName}") i.${eyeIcon}`, + run: () => {}, // it is a check + }; +} tour.register('conditional_visibility_1', { test: true, url: '/', @@ -74,3 +94,56 @@ tour.register('conditional_visibility_2', { }, }, ]); + +tour.register("conditional_visibility_3", { + test: true, + url: "/", +}, +[ +...wTourUtils.clickOnEditAndWaitEditMode(), +checkEyeIcon("Text - Image", true), +// Drag a "Banner" snippet on the website. +wTourUtils.dragNDrop(snippets[1]), +// Click on the "Banner" snippet. +wTourUtils.clickOnSnippet(snippets[1]), +wTourUtils.changeOption("ConditionalVisibility", "we-toggler"), +wTourUtils.changeOption("ConditionalVisibility", '[data-name="visibility_conditional"]'), +checkEyeIcon("Banner", true), +{ + content: "click on 'Blocks'", + trigger: "#snippets_menu button:contains('Blocks')", +}, +// Drag a "Popup" snippet on the website. +wTourUtils.dragNDrop(snippets[2]), +{ + content: "Toggle the visibility of the popup", + in_modal: false, + trigger: ".o_we_invisible_el_panel .o_we_invisible_entry:contains('Popup')", +}, +checkEyeIcon("Popup", false), +{ + content: "Click on footer", + trigger: "body.editor_enable #wrapwrap footer", +}, +wTourUtils.changeOption("HideFooter", "we-checkbox"), +checkEyeIcon("Footer", false), +{ + content: "Click on Header", + trigger: "body.editor_enable #wrapwrap header", +}, +wTourUtils.changeOption("TopMenuVisibility", "we-toggler"), +wTourUtils.changeOption("TopMenuVisibility", '[data-visibility="hidden"]'), +checkEyeIcon("Header", false), +{ + content: "Toggle the visibility of the Banner snippet", + trigger: ".o_we_invisible_el_panel .o_we_invisible_entry:contains('Banner')", +}, +checkEyeIcon("Banner", false), +...wTourUtils.clickOnSave(), +...wTourUtils.clickOnEditAndWaitEditMode(), +checkEyeIcon("Header", false), +checkEyeIcon("Text - Image", true), +checkEyeIcon("Popup", false), +checkEyeIcon("Banner", true), +checkEyeIcon("Footer", false), +]); diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py index 57a0d6d33707..fb0086cba951 100644 --- a/addons/website/tests/test_ui.py +++ b/addons/website/tests/test_ui.py @@ -218,6 +218,7 @@ class TestUi(odoo.tests.HttpCase): def test_10_website_conditional_visibility(self): self.start_tour('/', 'conditional_visibility_1', login='admin') self.start_tour('/', 'conditional_visibility_2', login='admin') + self.start_tour('/', 'conditional_visibility_3', login='admin') def test_11_website_snippet_background_edition(self): self.env['ir.attachment'].create({ -- GitLab