From 4255d16ac44ca5265fad0f74e29d1c692646d01a Mon Sep 17 00:00:00 2001 From: Younn Olivier Date: Fri, 31 Dec 2021 17:37:01 +0100 Subject: [PATCH] [IMP] website: patch navbar to display a specific website systray This commit adds a new website_systray registry, that the patched navbar will use when the user is editing the website through the WebsitePreview client action. This patch is subject to debate with the framework team, it will be discussed further post-merge. See merge commit for more information. task-2687506 Co-authored-by: Arthur Detroux --- addons/website/__manifest__.py | 1 + .../website_preview/website_preview.js | 13 ++++++- .../static/src/components/navbar/navbar.js | 39 +++++++++++++++++++ .../static/src/services/website_service.js | 31 ++++++++++++++- 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 addons/website/static/src/components/navbar/navbar.js diff --git a/addons/website/__manifest__.py b/addons/website/__manifest__.py index cd6553f1bdb..3792074940e 100644 --- a/addons/website/__manifest__.py +++ b/addons/website/__manifest__.py @@ -174,6 +174,7 @@ 'website/static/src/client_actions/*/*.js', 'website/static/src/client_actions/*/*.scss', 'website/static/src/services/website_service.js', + 'website/static/src/components/navbar/navbar.js', ], 'web.qunit_suite_tests': [ 'website/static/tests/dashboard_tests.js', 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 f74d98d5e84..c5716b08dfb 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 @@ -3,7 +3,7 @@ import { registry } from '@web/core/registry'; import { useService } from '@web/core/utils/hooks'; -const { Component, onWillStart, useRef } = owl; +const { Component, onWillStart, useRef, useEffect } = owl; export class WebsitePreview extends Component { setup() { @@ -19,10 +19,21 @@ export class WebsitePreview extends Component { const encodedPath = encodeURIComponent(this.path); this.initialUrl = `/website/force/${this.websiteId}?path=${encodedPath}`; }); + + useEffect(() => { + this.websiteService.currentWebsiteId = this.websiteId; + return () => this.websiteService.currentWebsiteId = null; + }, () => [this.props.action.context.params]); } 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. + if (!websiteId) { + websiteId = this.websiteService.currentWebsite && this.websiteService.currentWebsite.id; + } if (!websiteId) { websiteId = this.websiteService.websites[0].id; } diff --git a/addons/website/static/src/components/navbar/navbar.js b/addons/website/static/src/components/navbar/navbar.js new file mode 100644 index 00000000000..eb605d27c2c --- /dev/null +++ b/addons/website/static/src/components/navbar/navbar.js @@ -0,0 +1,39 @@ +/** @odoo-module **/ + +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.utils'; + +const websiteSystrayRegistry = registry.category('website_systray'); + +patch(NavBar.prototype, 'website_navbar', { + setup() { + this._super(); + this.websiteService = useService('website'); + + // The navbar is rerendered with an event, as it can not naturally be + // with props/state (the WebsitePreview client action and the navbar + // are not related). + useBus(websiteSystrayRegistry, 'EDIT-WEBSITE', () => this.render(true)); + + if (this.env.debug && !websiteSystrayRegistry.contains('web.debug_mode_menu')) { + websiteSystrayRegistry.add('web.debug_mode_menu', registry.category('systray').get('web.debug_mode_menu'), {sequence: 100}); + } + }, + + /** + * @override + */ + get systrayItems() { + if (this.websiteService.currentWebsite) { + return websiteSystrayRegistry + .getEntries() + .map(([key, value]) => ({ key, ...value })) + .filter((item) => ('isDisplayed' in item ? item.isDisplayed(this.env) : true)) + .reverse(); + } + return this._super(); + } +}); diff --git a/addons/website/static/src/services/website_service.js b/addons/website/static/src/services/website_service.js index bc347e4a005..6b5d18da657 100644 --- a/addons/website/static/src/services/website_service.js +++ b/addons/website/static/src/services/website_service.js @@ -2,17 +2,46 @@ import { registry } from '@web/core/registry'; +const websiteSystrayRegistry = registry.category('website_systray'); + +const unslugHtmlDataObject = (repr) => { + const match = repr && repr.match(/(.+)\((\d+),(.*)\)/); + if (!match) { + return null; + } + return { + model: match[1], + id: match[2] | 0, + }; +}; + export const websiteService = { dependencies: ['orm'], async start(env, { orm }) { let websites = []; + let currentWebsiteId; + + const setCurrentWebsiteId = id => { + currentWebsiteId = id; + websiteSystrayRegistry.trigger('EDIT-WEBSITE'); + }; return { + set currentWebsiteId(id) { + setCurrentWebsiteId(id); + }, + get currentWebsite() { + return websites.find(website => website.id === currentWebsiteId); + }, get websites() { return websites; }, async fetchWebsites() { - const allWebsites = await orm.searchRead('website', []); + const [currentWebsiteRepr, allWebsites] = await Promise.all([ + orm.call('website', 'get_current_website'), + orm.searchRead('website', []), + ]); websites = [...allWebsites]; + setCurrentWebsiteId(unslugHtmlDataObject(currentWebsiteRepr).id); }, }; },