[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) <qsm@odoo.com>
This commit is contained in:
Younn Olivier
2022-09-15 18:22:06 +02:00
parent 507db4e179
commit 7b16b06838
3 changed files with 26 additions and 21 deletions
@@ -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;
@@ -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,
@@ -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) {