From 7b16b0683895bf6d35cda0f27399df8ecc2e598a Mon Sep 17 00:00:00 2001 From: Younn Olivier Date: Tue, 13 Sep 2022 08:06:02 +0000 Subject: [PATCH] [FIX] website: do not set a current website when fetching websites Before this commit, the website service method fetchWebsites was not clearly defined: it was fetching the user groups, the websites, the current website and it was also setting the service's current website. There is a difference between the get_current_website backend method and the getter from the website service, introduced in [1]: the websiteService.currentWebsite value referes to the website currently edited in the WebsitePreview client action. From that value depend other components visibility (like the contextual menus). So when a fetchWebsites call was done from outside the client action, from a PageListController with [2], it was breaking the flow by setting a currentWebsite outside the client action and it could lead to bugged flows: - Go to the "Pages" list view => The contextual "This page" menu is not shown, it's correct - Refresh the page => The "This Page" menu is shown (and broken). To fix that, the fetchWebsites method is divided into a fetchUserGroups, the searchRead on the websites, and another call to get_current_website, located in the client action. It allows to load the client action iframe with the last viewed/edited website. Also, the menu "This Page" is shown only when there is a pageDocument at the website service level. [1]: https://github.com/odoo/odoo/commit/31cc10b91dc7762e23b4bde9b945be0c4ce3fe3b [2]: https://github.com/odoo/odoo/commit/940f4ee875332dafa1f379970a7683be6b3ee606 task-2687506 closes odoo/odoo#100055 Signed-off-by: Quentin Smetz (qsm) --- .../website_preview/website_preview.js | 16 ++++++++--- .../src/services/website_custom_menus.js | 3 +- .../static/src/services/website_service.js | 28 ++++++++----------- 3 files changed, 26 insertions(+), 21 deletions(-) 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 e41021159ed..86e6194e049 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 @@ -6,6 +6,7 @@ import core from 'web.core'; import { AceEditorAdapterComponent } from '../../components/ace_editor/ace_editor'; import { WebsiteEditorComponent } from '../../components/editor/editor'; import { WebsiteTranslator } from '../../components/translator/translator'; +import { unslugHtmlDataObject } from '../../services/website_service'; import {OptimizeSEODialog} from '@website/components/dialog/seo'; import { routeToUrl } from "@web/core/browser/router_service"; @@ -22,6 +23,7 @@ export class WebsitePreview extends Component { this.user = useService('user'); this.router = useService('router'); this.action = useService('action'); + this.orm = useService('orm'); this.iframeFallbackUrl = '/website/iframefallback'; @@ -38,7 +40,13 @@ export class WebsitePreview extends Component { useBus(this.websiteService.bus, 'UNBLOCK', () => this.unblock()); onWillStart(async () => { - await this.websiteService.fetchWebsites(); + const [backendWebsiteRepr] = await Promise.all([ + this.orm.call('website', 'get_current_website'), + this.websiteService.fetchWebsites(), + this.websiteService.fetchUserGroups(), + ]); + this.backendWebsiteId = unslugHtmlDataObject(backendWebsiteRepr).id; + const encodedPath = encodeURIComponent(this.path); if (this.websiteDomain && this.websiteDomain !== window.location.origin) { window.location.href = `${this.websiteDomain}/web#action=website.website_preview&path=${encodedPath}&website_id=${this.websiteId}`; @@ -126,10 +134,10 @@ export class WebsitePreview extends Component { get websiteId() { let websiteId = this.props.action.context.params && this.props.action.context.params.website_id; // When no parameter is passed to the client action, the current - // website from the website service is taken. By default, it will be - // the one from the session. + // website from the backend (which is the last viewed/edited) will be + // taken. if (!websiteId) { - websiteId = this.websiteService.currentWebsite && this.websiteService.currentWebsite.id; + websiteId = this.backendWebsiteId; } if (!websiteId) { websiteId = this.websiteService.websites[0].id; diff --git a/addons/website/static/src/services/website_custom_menus.js b/addons/website/static/src/services/website_custom_menus.js index 20a60496062..10f9a18bac5 100644 --- a/addons/website/static/src/services/website_custom_menus.js +++ b/addons/website/static/src/services/website_custom_menus.js @@ -61,7 +61,8 @@ registry.category('website_custom_menus').add('website.menu_optimize_seo', { && !!env.services.website.currentWebsite.metadata.mainObject, }); registry.category('website_custom_menus').add('website.menu_current_page', { - isDisplayed: (env) => !!env.services.website.currentWebsite, + isDisplayed: (env) => !!env.services.website.currentWebsite + && !!env.services.website.pageDocument, },); registry.category('website_custom_menus').add('website.menu_ace_editor', { openWidget: (services) => services.website.context.showAceEditor = true, diff --git a/addons/website/static/src/services/website_service.js b/addons/website/static/src/services/website_service.js index 72762c44a45..e4621adbe22 100644 --- a/addons/website/static/src/services/website_service.js +++ b/addons/website/static/src/services/website_service.js @@ -53,10 +53,6 @@ export const websiteService = { }); const bus = new EventBus(); - const setCurrentWebsiteId = id => { - currentWebsiteId = id; - websiteSystrayRegistry.trigger('EDIT-WEBSITE'); - }; hotkey.add("escape", () => { // Toggle fullscreen mode when pressing escape. if (currentWebsiteId) { @@ -75,8 +71,15 @@ export const websiteService = { }); return { set currentWebsiteId(id) { - setCurrentWebsiteId(id); + currentWebsiteId = id; + websiteSystrayRegistry.trigger('EDIT-WEBSITE'); }, + /** + * This represents the current website being edited in the + * WebsitePreview client action. Multiple components based their + * visibility on this value, which is falsy if the client action is + * not displayed. + */ get currentWebsite() { const currentWebsite = websites.find(w => w.id === currentWebsiteId); if (currentWebsite) { @@ -174,23 +177,16 @@ export const websiteService = { }, }); }, - async fetchWebsites() { + async fetchUserGroups() { // Fetch user groups, before fetching the websites. [isRestrictedEditor, isDesigner, hasMultiWebsites] = await Promise.all([ user.hasGroup('website.group_website_restricted_editor'), user.hasGroup('website.group_website_designer'), user.hasGroup('website.group_multi_website'), ]); - - const [currentWebsiteRepr, allWebsites] = await Promise.all([ - orm.call('website', 'get_current_website'), - hasMultiWebsites ? orm.searchRead('website', [], ['domain', 'id', 'name']) : [], - ]); - websites = [...allWebsites]; - setCurrentWebsiteId(unslugHtmlDataObject(currentWebsiteRepr).id); - if (!websites.length) { - websites = [{ id: currentWebsiteId }]; - } + }, + async fetchWebsites() { + websites = [...(await orm.searchRead('website', [], ['domain', 'id', 'name']))]; }, async loadWysiwyg() { if (!Wysiwyg) {