odoo18/addons/web/static/src/webclient/menus/menu_helpers.js

86 lines
2.8 KiB
JavaScript

/**
* Traverses the given menu tree, executes the given callback for each node with
* the node itself and the list of its ancestors as arguments.
*
* @param {Object} tree tree of menus as exported by the menus service
* @param {Function} cb
* @param {[Object]} [parents] the ancestors of the tree root, if any
*/
function traverseMenuTree(tree, cb, parents = []) {
cb(tree, parents);
tree.childrenTree.forEach((c) => traverseMenuTree(c, cb, parents.concat([tree])));
}
/**
* Computes the "apps" and "menuItems" from a given menu tree.
*
* @param {Object} menuTree tree of menus as exported by the menus service
* @returns {Object} with keys "apps" and "menuItems" (HomeMenu props)
*/
export function computeAppsAndMenuItems(menuTree) {
const apps = [];
const menuItems = [];
traverseMenuTree(menuTree, (menuItem, parents) => {
if (!menuItem.id || !menuItem.actionID) {
return;
}
const isApp = menuItem.id === menuItem.appID;
const item = {
parents: parents
.slice(1)
.map((p) => p.name)
.join(" / "),
label: menuItem.name,
id: menuItem.id,
xmlid: menuItem.xmlid,
actionID: menuItem.actionID,
href: `/odoo/${menuItem.actionPath || "action-" + menuItem.actionID}`,
appID: menuItem.appID,
};
if (isApp) {
if (menuItem.webIconData) {
item.webIconData = menuItem.webIconData;
} else {
const [iconClass, color, backgroundColor] = (menuItem.webIcon || "").split(",");
if (backgroundColor !== undefined) {
// Could split in three parts?
item.webIcon = { iconClass, color, backgroundColor };
} else {
item.webIconData = "/web/static/img/default_icon_app.png";
}
}
} else {
item.menuID = parents[1].id;
}
if (isApp) {
apps.push(item);
} else {
menuItems.push(item);
}
});
return { apps, menuItems };
}
/**
* @param {Array} order
* Sorts the apps in the homescreen menu according to the given order as an array of xmlid strings
*/
export function reorderApps(apps, order) {
apps.sort((a, b) => {
const aIndex = order.indexOf(a.xmlid);
const bIndex = order.indexOf(b.xmlid);
if (aIndex === -1 && bIndex === -1) {
// if both items are not present, sort by original order
return apps.indexOf(a) - apps.indexOf(b);
}
// not found items always before found ones
if (aIndex === -1) {
return -1;
}
if (bIndex === -1) {
return 1;
}
return aIndex - bIndex; // sort by order array
});
}