Search code examples
javascriptmenuodooodoo-15

How can I add action menu in usermenu odoo15


In odoo 15, how can I add new action menu in user menu? In other odoo versions (13 and 14), it was possible by inheriting from UserMenu.Actions.

In odoo 15, I tried the following code but it is not working.

Thanks for any suggestion

/** @odoo-module **/

import { registry } from "@web/core/registry";
import { preferencesItem } from "@web/webclient/user_menu/user_menu_items";

export function UserLog(env) {
    return Object.assign(
        {},
        preferencesItem(env),
        {
            type: "item",
            id: "log",
            description: env._t("UserRecent Log"),
            callback: async function () {
                const actionDescription = await env.services.orm.call("user.recent.log", "action_get");
                actionDescription.res_id = env.services.user.userId;
                env.services.action.doAction(actionDescription);
            },
            sequence: 70,
        }
    );
}

registry.category("user_menuitems").add('profile', UserLog, { force: true })

This is my model code.

class UserRecentLog(models.Model):
    _name = 'user.recent.log'
    _order = "last_visited_on desc"

    
    @api.model
    def action_get(self):
        return self.env['ir.actions.act_window']._for_xml_id('user_recent_log.action_user_activity')

This is my xml view.

    <!-- actions opening views on models -->    
    <record model="ir.actions.act_window" id="action_user_activity">
        <field name="name">User Recent Log(s)</field>
        <field name="res_model">user.recent.log</field>
        <field name="view_mode">tree,form</field>
        <field name="view_id" ref="user_activity_view_tree"/>
    </record>


Solution

  • You don't need to change anything, your code should work. You can check the user preferences menu item in web module (similar to your menu item).

    export function preferencesItem(env) {
        return {
            type: "item",
            id: "settings",
            description: env._t("Preferences"),
            callback: async function () {
                const actionDescription = await env.services.orm.call("res.users", "action_get");
                actionDescription.res_id = env.services.user.userId;
                env.services.action.doAction(actionDescription);
            },
            sequence: 50,
        };
    }
    
    registry
        .category("user_menuitems")
        .add("profile", preferencesItem)
    

    There is another implementation in hr module:

    import { registry } from "@web/core/registry";
    import { preferencesItem } from "@web/webclient/user_menu/user_menu_items";
    
    export function hrPreferencesItem(env)  {
        return Object.assign(
            {}, 
            preferencesItem(env),
            {
                description: env._t('My Profile'),
            }
        );
    }
    
    registry.category("user_menuitems").add('profile', hrPreferencesItem, { force: true })
    

    So you can rewrite your code above as following:

    import { registry } from "@web/core/registry";
    import { preferencesItem } from "@web/webclient/user_menu/user_menu_items";
    
    export function UserLog(env) {
        return Object.assign(
            {},
            preferencesItem(env),
            {
                type: "item",
                id: "log",
                description: env._t("Log"),
                callback: async function () {
                    const actionDescription = await env.services.orm.call("res.users.log", "action_user_activity");
                    env.services.action.doAction(actionDescription);
                },
                sequence: 70,
            }
        );
    }
    
    registry.category("user_menuitems").add('profile', UserLog, { force: true })
    

    Edit:

    The tree view mode is ignored when executing the window action.

    The _executeActWindowAction will check for the tree view type in the views registry to construct the views object and unfortunately, the tree view mode was not added to that registry.

    To show the tree view, you can add [false, 'list'] to the views list and specify the view type (list) in the doAction options:

    actionDescription.views.push([actionDescription.view_id[0], 'list'])
    env.services.action.doAction(actionDescription, {viewType: 'list'});
    

    Or update the views list and change tree to list:

    actionDescription.views[0][1] = 'list';  
    

    Of course , you can do the same in the action_get method:

    action = self.env['ir.actions.act_window']._for_xml_id('user_recent_log.action_user_activity')
    action['views'][0] = action['view_id'][0], 'list'
    return action