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); }, }; },