141 lines
6.8 KiB
JavaScript
141 lines
6.8 KiB
JavaScript
/** @odoo-module **/
|
|
|
|
import { _t } from "@web/core/l10n/translation";
|
|
import { registry } from "@web/core/registry";
|
|
import { EditMenuDialog } from '@website/components/dialog/edit_menu';
|
|
import { OptimizeSEODialog } from '@website/components/dialog/seo';
|
|
import {PagePropertiesDialog} from '@website/components/dialog/page_properties';
|
|
|
|
/**
|
|
* This service displays contextual menus, depending of the state of the
|
|
* website. These menus are defined in xml with the "website_preview" action,
|
|
* which is overriden here for displaying dialogs, or regular components that
|
|
* are not client actions.
|
|
*/
|
|
export const websiteCustomMenus = {
|
|
dependencies: ['website', 'orm', 'dialog', 'ui'],
|
|
start(env, { website, orm, dialog, ui }) {
|
|
const services = { website, orm, dialog, ui };
|
|
return {
|
|
get(xmlId) {
|
|
return registry.category('website_custom_menus').get(xmlId, null);
|
|
},
|
|
async open(customMenu) {
|
|
const menuConfig = this.get(customMenu.xmlid);
|
|
if (menuConfig.openWidget) {
|
|
return menuConfig.openWidget(services);
|
|
}
|
|
const menuProps = {
|
|
...(menuConfig.getProps && (await menuConfig.getProps(services))),
|
|
// Values on 'dynamicProps' are retrieved after the content is loaded (e.g. id of
|
|
// the content menu to be edited).
|
|
...customMenu.dynamicProps,
|
|
};
|
|
return dialog.add(
|
|
menuConfig.Component,
|
|
menuProps,
|
|
);
|
|
},
|
|
addCustomMenus(sections) {
|
|
const filteredSections = [];
|
|
for (const section of sections) {
|
|
const isWebsiteCustomMenu = !!this.get(section.xmlid);
|
|
const displayWebsiteCustomMenu = isWebsiteCustomMenu && website.isRestrictedEditor && this.get(section.xmlid).isDisplayed(env);
|
|
if (!isWebsiteCustomMenu || displayWebsiteCustomMenu) {
|
|
let subSections = [];
|
|
if (section.childrenTree.length) {
|
|
subSections = this.addCustomMenus(section.childrenTree);
|
|
}
|
|
if (section.xmlid === 'website.custom_menu_edit_menu') {
|
|
// Hack: this code will simulate an XML pre-configured navbar menuitem to edit each
|
|
// content menu found on the current page by duplicating one menuitem with
|
|
// different data (name, dialog props...). this will prevent breaking the current
|
|
// 'navbar menus' display system.
|
|
filteredSections.push(...website.currentWebsite.metadata.contentMenus.map((menu, index) => ({
|
|
...section,
|
|
name: _t("Edit %s", menu[0]),
|
|
dynamicProps: {rootID: parseInt(menu[1], 10)},
|
|
// Prevent a 't-foreach' duplicate key on menus template.
|
|
id: `${section.id}-${index}`,
|
|
})));
|
|
} else {
|
|
filteredSections.push(Object.assign({}, section, {childrenTree: subSections}));
|
|
}
|
|
}
|
|
}
|
|
for (const section of filteredSections) {
|
|
section.childrenTree = section.childrenTree.filter(
|
|
// Exclude non-leaf node having no visible sub-element.
|
|
tree => !(tree.children.length && !tree.childrenTree.length)
|
|
);
|
|
}
|
|
return filteredSections;
|
|
},
|
|
};
|
|
}
|
|
};
|
|
registry.category('services').add('website_custom_menus', websiteCustomMenus);
|
|
|
|
registry.category('website_custom_menus').add('website.menu_edit_menu', {
|
|
Component: EditMenuDialog,
|
|
isDisplayed: (env) => !!env.services.website.currentWebsite
|
|
&& env.services.website.isDesigner
|
|
&& !env.services.website.currentWebsite.metadata.translatable,
|
|
});
|
|
registry.category('website_custom_menus').add('website.menu_optimize_seo', {
|
|
Component: OptimizeSEODialog,
|
|
isDisplayed: (env) => env.services.website.currentWebsite
|
|
&& env.services.website.isRestrictedEditor
|
|
&& !!env.services.website.currentWebsite.metadata.canOptimizeSeo,
|
|
});
|
|
registry.category('website_custom_menus').add('website.menu_ace_editor', {
|
|
openWidget: (services) => services.website.context.showResourceEditor = true,
|
|
isDisplayed: (env) => env.services.website.currentWebsite
|
|
&& env.services.website.currentWebsite.metadata.viewXmlid
|
|
&& !env.services.ui.isSmall,
|
|
});
|
|
registry.category('website_custom_menus').add('website.menu_page_properties', {
|
|
Component: PagePropertiesDialog,
|
|
isDisplayed: (env) => env.services.website.currentWebsite
|
|
&& env.services.website.isDesigner
|
|
&& !!env.services.website.currentWebsite.metadata.mainObject,
|
|
getProps: async ({ orm, website }) => {
|
|
const mainObject = website.currentWebsite.metadata.mainObject;
|
|
const isPage = mainObject.model === "website.page";
|
|
const model = isPage ? "website.page.properties" : "website.page.properties.base";
|
|
return {
|
|
resId: await orm.call(model, "create", [
|
|
isPage
|
|
? {
|
|
target_model_id: mainObject.id,
|
|
website_id: website.currentWebsite.id,
|
|
}
|
|
: {
|
|
target_model_id: `${mainObject.model},${mainObject.id}`,
|
|
url: window.location.pathname,
|
|
website_id: website.currentWebsite.id,
|
|
},
|
|
]),
|
|
resModel: model,
|
|
onRecordSaved: async (record) => {
|
|
const page = isPage
|
|
? (await orm.read("website.page", [mainObject.id], ["website_id", "url"]))[0]
|
|
: undefined;
|
|
return website.goToWebsite({
|
|
websiteId: page?.website_id?.[0] ?? website.currentWebsite.id,
|
|
path: page?.url ?? website.currentWebsite.metadata.path,
|
|
});
|
|
},
|
|
};
|
|
},
|
|
});
|
|
registry.category('website_custom_menus').add('website.custom_menu_edit_menu', {
|
|
Component: EditMenuDialog,
|
|
// 'isDisplayed' === true => at least 1 content menu was found on the page. This
|
|
// menuitem will be cloned (in 'addCustomMenus()') to edit every content menu using
|
|
// the 'EditMenuDialog' component.
|
|
isDisplayed: (env) => env.services.website.currentWebsite
|
|
&& env.services.website.currentWebsite.metadata.contentMenus
|
|
&& env.services.website.currentWebsite.metadata.contentMenus.length,
|
|
});
|