From e38808e1a77dab291beb4020a2bf3c248f88cdef Mon Sep 17 00:00:00 2001 From: "Robin Lejeune (role)" Date: Wed, 23 Aug 2023 17:23:13 +0200 Subject: [PATCH] [IMP] website, *: add user profile to website navbar *: test_website_modules, website_sale When one starts a trial with the website app, they arrive on a webpage in edit mode. Many users struggle to understand they need to save before accessing the Odoo navbar (app switcher, creation of new page, etc.). Additionally, if they want to navigate through Odoo, not having to discard could save some time. It was therefore decided to land on the homepage without editor after creating a website. The first step of the homepage tour should then be to click on the edit button. When creating an empty website (skipping the configurator), the website loader is shown until the page is ready, to avoid the user leaving the page before the first step is displayed. On another related note, if one wants to try out the Odoo website builder, they might create multiple DB, one per website, which is OK. In such a case, the link to 'my database' is not visible from the website app because the user profile was hidden. The user menu is therefore added to the navbar on the website app. In order to make sure the header and its dropdowns always stay on top of the website's elements regardless of their z-index, `.o_website_preview` is blocked in its own stacking context with `isolation: isolate;`. task-3381773 closes odoo/odoo#133031 Related: odoo/enterprise#46992 Signed-off-by: Benjamin Vray (bvr) --- .../static/tests/tours/configurator_flow.js | 10 ++++------ addons/website/models/ir_module_module.py | 4 ++-- .../configurator/configurator.js | 2 +- .../website_preview/website_preview.js | 4 ++++ .../website_preview/website_preview.scss | 1 + .../static/src/components/editor/editor.js | 1 - .../static/src/components/navbar/navbar.js | 2 ++ .../website/static/src/js/tours/tour_utils.js | 18 ++++++++++-------- .../static/tests/tours/automatic_editor.js | 8 ++++---- .../tests/tours/configurator_translation.js | 10 +++++++--- .../tours/website_sale_remove_product_image.js | 6 +++--- 11 files changed, 38 insertions(+), 28 deletions(-) diff --git a/addons/test_website_modules/static/tests/tours/configurator_flow.js b/addons/test_website_modules/static/tests/tours/configurator_flow.js index 49ed9d9ef46..65707c04652 100644 --- a/addons/test_website_modules/static/tests/tours/configurator_flow.js +++ b/addons/test_website_modules/static/tests/tours/configurator_flow.js @@ -1,7 +1,6 @@ /** @odoo-module **/ import { registry } from "@web/core/registry"; -import wTourUtils from "@website/js/tours/tour_utils"; registry.category("web_tour.tours").add('configurator_flow', { test: true, @@ -72,12 +71,11 @@ registry.category("web_tour.tours").add('configurator_flow', { trigger: '.o_website_loader_container', run: function () {}, // it's a check }, { - content: "Wait untill the configurator is finished", - trigger: '#oe_snippets.o_loaded', + content: "Wait until the configurator is finished", + trigger: ".o_website_preview[data-view-xmlid='website.homepage']", timeout: 30000, - }, - ...wTourUtils.clickOnSave(), - { + isCheck: true, + }, { content: "check menu and footer links are correct", trigger: 'body:not(.editor_enable)', // edit mode left run: function () { diff --git a/addons/website/models/ir_module_module.py b/addons/website/models/ir_module_module.py index 8bf2c5f86ea..2ac7b3935ce 100644 --- a/addons/website/models/ir_module_module.py +++ b/addons/website/models/ir_module_module.py @@ -404,8 +404,8 @@ class IrModuleModule(models.Model): if active_todo: result = active_todo.action_launch() else: - result = website.button_go_website(mode_edit=True) - if result.get('tag') == 'website_preview' and result.get('context', {}).get('params', {}).get('enable_editor'): + result = website.button_go_website() + if result.get('tag') == 'website_preview' and result.get('context', {}).get('params'): result['context']['params']['with_loader'] = True return result diff --git a/addons/website/static/src/client_actions/configurator/configurator.js b/addons/website/static/src/client_actions/configurator/configurator.js index e2beaa6737e..e426de9e331 100644 --- a/addons/website/static/src/client_actions/configurator/configurator.js +++ b/addons/website/static/src/client_actions/configurator/configurator.js @@ -388,7 +388,7 @@ class ApplyConfiguratorScreen extends Component { // Here the website service goToWebsite method is not used because // the web client needs to be reloaded after the new modules have // been installed. - window.location.replace(`/web#action=website.website_preview&website_id=${encodeURIComponent(resp.website_id)}&enable_editor=1`); + window.location.replace(`/web#action=website.website_preview&website_id=${encodeURIComponent(resp.website_id)}`); } } } diff --git a/addons/website/static/src/client_actions/website_preview/website_preview.js b/addons/website/static/src/client_actions/website_preview/website_preview.js index 7205a7dc508..0ac11509606 100644 --- a/addons/website/static/src/client_actions/website_preview/website_preview.js +++ b/addons/website/static/src/client_actions/website_preview/website_preview.js @@ -353,6 +353,10 @@ export class WebsitePreview extends Component { this.websiteService.context.showAceEditor = false; this.lastHiddenPageURL = undefined; } + if (this.props.action.context.params?.with_loader) { + this.websiteService.hideLoader(); + this.props.action.context.params.with_loader = false; + } this.iframe.el.contentWindow.addEventListener('beforeunload', this._onPageUnload.bind(this)); this._replaceBrowserUrl(); this.iframe.el.contentWindow.addEventListener('hashchange', this._replaceBrowserUrl.bind(this)); diff --git a/addons/website/static/src/client_actions/website_preview/website_preview.scss b/addons/website/static/src/client_actions/website_preview/website_preview.scss index a034827b836..f0389e212c4 100644 --- a/addons/website/static/src/client_actions/website_preview/website_preview.scss +++ b/addons/website/static/src/client_actions/website_preview/website_preview.scss @@ -11,6 +11,7 @@ .o_website_preview { position: relative; + isolation: isolate; height: 100%; transition: margin-right ease 400ms; diff --git a/addons/website/static/src/components/editor/editor.js b/addons/website/static/src/components/editor/editor.js index 6468b203bf4..5b99457a5c7 100644 --- a/addons/website/static/src/components/editor/editor.js +++ b/addons/website/static/src/components/editor/editor.js @@ -86,7 +86,6 @@ export class WebsiteEditorComponent extends Component { } this.wysiwygOptions.invalidateSnippetCache = false; this.websiteService.unblockPreview(); - this.websiteService.hideLoader(); } /** * Prepares the editor for reload. Copies the widget element tree diff --git a/addons/website/static/src/components/navbar/navbar.js b/addons/website/static/src/components/navbar/navbar.js index 296e071e27d..c7676f59cca 100644 --- a/addons/website/static/src/components/navbar/navbar.js +++ b/addons/website/static/src/components/navbar/navbar.js @@ -4,9 +4,11 @@ import { NavBar } from '@web/webclient/navbar/navbar'; import { useService, useBus } from '@web/core/utils/hooks'; import { registry } from "@web/core/registry"; import { patch } from "@web/core/utils/patch"; +import { UserMenu } from "@web/webclient/user_menu/user_menu"; import { useEffect } from "@odoo/owl"; const websiteSystrayRegistry = registry.category('website_systray'); +websiteSystrayRegistry.add("UserMenu", { Component: UserMenu }, { sequence: 14 }); patch(NavBar.prototype, { setup() { diff --git a/addons/website/static/src/js/tours/tour_utils.js b/addons/website/static/src/js/tours/tour_utils.js index 4d2c3a35ad3..919f405cec3 100644 --- a/addons/website/static/src/js/tours/tour_utils.js +++ b/addons/website/static/src/js/tours/tour_utils.js @@ -160,13 +160,14 @@ function clickOnElement(elementName, selector) { */ function clickOnEditAndWaitEditMode(position = "bottom") { return [{ - content: _t("Click Edit to start designing your homepage."), + content: markup(_t("Click Edit to start designing your homepage.")), trigger: ".o_menu_systray .o_edit_website_container a", position: position, }, { content: "Check that we are in edit mode", trigger: ".o_website_preview.editor_enable.editor_has_snippets", - run: () => null, // it's a check + auto: true, // Checking step only for automated tests + isCheck: true, }]; } @@ -357,15 +358,16 @@ function registerThemeHomepageTour(name, steps) { } return registerWebsitePreviewTour(name, { url: '/', - edition: true, - sequence: 1010, + sequence: 50, saveAs: "homepage", }, - () => - prepend_trigger( + () => [ + ...clickOnEditAndWaitEditMode(), + ...prepend_trigger( steps().concat(clickOnSave()), - ".o_website_preview[data-view-xmlid='website.homepage'] " - )); + ".o_website_preview[data-view-xmlid='website.homepage'] " + ), + ]); } function registerBackendAndFrontendTour(name, options, steps) { diff --git a/addons/website/static/tests/tours/automatic_editor.js b/addons/website/static/tests/tours/automatic_editor.js index 0a86c9f0ca5..8ddf948df14 100644 --- a/addons/website/static/tests/tours/automatic_editor.js +++ b/addons/website/static/tests/tours/automatic_editor.js @@ -80,10 +80,10 @@ wTourUtils.registerWebsitePreviewTour('automatic_editor_on_new_website', { trigger: 'button[name="button_choose_theme"]' }, { - content: "Check that the editor is loaded", - trigger: 'iframe body.editor_enable', + content: "Check that the homepage is loaded", + trigger: ".o_website_preview[data-view-xmlid='website.homepage']", + extra_trigger: ".o_menu_systray .o_user_menu", timeout: 30000, - run: () => null, // it's a check + isCheck: true, }, - ...wTourUtils.clickOnSave(), ]); diff --git a/addons/website/static/tests/tours/configurator_translation.js b/addons/website/static/tests/tours/configurator_translation.js index 6f08fe4edd1..e28065b9e3b 100644 --- a/addons/website/static/tests/tours/configurator_translation.js +++ b/addons/website/static/tests/tours/configurator_translation.js @@ -1,6 +1,7 @@ /** @odoo-module */ import { registry } from "@web/core/registry"; +import wTourUtils from "@website/js/tours/tour_utils"; registry.category("web_tour.tours").add('configurator_translation', { test: true, @@ -57,10 +58,13 @@ registry.category("web_tour.tours").add('configurator_translation', { trigger: '.o_website_loader_container', run: function () {}, // it's a check }, { - content: "Wait untill the configurator is finished", - trigger: '#oe_snippets.o_loaded', + content: "Wait until the configurator is finished", + trigger: ".o_website_preview[data-view-xmlid='website.homepage']", timeout: 30000, - }, { + isCheck: true, + }, + ...wTourUtils.clickOnEditAndWaitEditMode(), + { // Check the content of the save button to make sure the website is in // Parseltongue. (The editor should be in the website's default language, // which should be parseltongue in this test.) diff --git a/addons/website_sale/static/tests/tours/website_sale_remove_product_image.js b/addons/website_sale/static/tests/tours/website_sale_remove_product_image.js index 736655dd066..376c1a1082c 100644 --- a/addons/website_sale/static/tests/tours/website_sale_remove_product_image.js +++ b/addons/website_sale/static/tests/tours/website_sale_remove_product_image.js @@ -13,7 +13,7 @@ const clickOnImgAndWaitForLoad = [ run: () => null, }, ]; -const enterEditModeOfTestProduct = [ +const enterEditModeOfTestProduct = () => [ { content: "Click on the product anchor", trigger: "iframe a:contains('Test Remove Image')", @@ -39,7 +39,7 @@ wTourUtils.registerWebsitePreviewTour("add_and_remove_main_product_image_no_vari url: "/shop?search=Test Remove Image", test: true, }, () => [ - ...enterEditModeOfTestProduct, + ...enterEditModeOfTestProduct(), { content: "Double click on the product image", trigger: "iframe #o-carousel-product img[alt='Test Remove Image']", @@ -60,7 +60,7 @@ wTourUtils.registerWebsitePreviewTour("remove_main_product_image_with_variant", url: "/shop?search=Test Remove Image", test: true, }, () => [ - ...enterEditModeOfTestProduct, + ...enterEditModeOfTestProduct(), ...clickOnImgAndWaitForLoad, ...wTourUtils.clickOnSave(), ...wTourUtils.clickOnEditAndWaitEditMode(),