[IMP] web,*: CP's CogMenu rework to add misc items from favorite
Part-of: odoo/odoo#116641
This commit is contained in:
@@ -5,7 +5,7 @@ import { registry } from "@web/core/registry";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { Component } from "@odoo/owl";
|
||||
|
||||
const favoriteMenuRegistry = registry.category("favoriteMenu");
|
||||
const cogMenuRegistry = registry.category("cogMenu");
|
||||
|
||||
/**
|
||||
* 'Import records' menu
|
||||
@@ -46,4 +46,4 @@ export const importRecordsItem = {
|
||||
!!JSON.parse(config.viewArch.getAttribute("create") || "1"),
|
||||
};
|
||||
|
||||
favoriteMenuRegistry.add("import-menu", importRecordsItem, { sequence: 1 });
|
||||
cogMenuRegistry.add("import-menu", importRecordsItem, { sequence: 1 });
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useAutofocus, useService } from "@web/core/utils/hooks";
|
||||
import { sprintf } from "@web/core/utils/strings";
|
||||
|
||||
const { Component, useState } = owl;
|
||||
const favoriteMenuRegistry = registry.category("favoriteMenu");
|
||||
const cogMenuRegistry = registry.category("cogMenu");
|
||||
|
||||
/**
|
||||
* 'Add to board' menu
|
||||
@@ -99,4 +99,4 @@ export const addToBoardItem = {
|
||||
isDisplayed: ({ config }) => config.actionType === "ir.actions.act_window" && config.actionId,
|
||||
};
|
||||
|
||||
favoriteMenuRegistry.add("add-to-board", addToBoardItem, { sequence: 10 });
|
||||
cogMenuRegistry.add("add-to-board", addToBoardItem, { sequence: 10 });
|
||||
|
||||
@@ -11,9 +11,10 @@ import { sprintf } from "@web/core/utils/strings";
|
||||
import { useModel } from "@web/views/model";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { SearchBar } from "@web/search/search_bar/search_bar";
|
||||
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
||||
|
||||
export class ActivityController extends Component {
|
||||
static components = { Layout, SearchBar };
|
||||
static components = { Layout, SearchBar, CogMenu };
|
||||
static props = {
|
||||
...standardViewProps,
|
||||
Model: Function,
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
<t t-name="mail.ActivityController" owl="1">
|
||||
<div t-att-class="props.className + (env.isSmall ? ' o_action_delegate_scroll': '')">
|
||||
<Layout display="props.display">
|
||||
<t t-set-slot="control-panel-additional-actions">
|
||||
<CogMenu/>
|
||||
</t>
|
||||
<t t-set-slot="layout-actions">
|
||||
<SearchBar/>
|
||||
</t>
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@
|
||||
|
||||
import { ActionMenus } from "@web/search/action_menus/action_menus";
|
||||
|
||||
|
||||
/**
|
||||
* Combined Action menus (or Action/Print bar, previously called 'Sidebar')
|
||||
*
|
||||
@@ -14,6 +15,6 @@ import { ActionMenus } from "@web/search/action_menus/action_menus";
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
export class CombinedActionMenus extends ActionMenus {
|
||||
static template = "web.CombinedActionMenus";
|
||||
export class ActionMenusItems extends ActionMenus {
|
||||
static template = "web.ActionMenusItems";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="web.ActionMenusItems" owl="1">
|
||||
<t t-if="printItems.length">
|
||||
<div class="dropdown-menu_group dropdown-header">
|
||||
<i class="me-md-1 fa fa-print"/>
|
||||
Print
|
||||
</div>
|
||||
<t t-foreach="printItems" t-as="item" t-key="item.key">
|
||||
<DropdownItem class="'o_menu_item'" onSelected="() => this.onItemSelected(item)">
|
||||
<t t-esc="item.description"/>
|
||||
</DropdownItem>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="actionItems.length">
|
||||
<div class="dropdown-menu_group dropdown-header">
|
||||
<i class="me-md-1 fa fa-cog"/>
|
||||
Action
|
||||
</div>
|
||||
<t t-foreach="actionItems" t-as="item" t-key="item.key">
|
||||
<t t-if="item.Component" t-component="item.Component" t-props="item.props" />
|
||||
<DropdownItem t-else="" class="'o_menu_item'" onSelected="() => this.onItemSelected(item)">
|
||||
<t t-esc="item.description"/>
|
||||
</DropdownItem>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -0,0 +1,48 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { Dropdown } from "@web/core/dropdown/dropdown";
|
||||
|
||||
import { Component } from "@odoo/owl";
|
||||
|
||||
const cogMenuRegistry = registry.category("cogMenu");
|
||||
|
||||
/**
|
||||
* Combined Action menus (or Action/Print bar, previously called 'Sidebar')
|
||||
*
|
||||
* This is a variation of the ActionMenus, combined into a single DropDown.
|
||||
*
|
||||
* The side bar is the group of dropdown menus located on the left side of the
|
||||
* control panel. Its role is to display a list of items depending on the view
|
||||
* type and selected records and to execute a set of actions on active records.
|
||||
* It is made out of 2 dropdown: Print and Action.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
export class CogMenu extends Component {
|
||||
static template = "web.CogMenu";
|
||||
static components = {
|
||||
Dropdown,
|
||||
}
|
||||
static props = {
|
||||
slots: { type: Object, optional: true },
|
||||
};
|
||||
|
||||
get hasItems() {
|
||||
return this.cogItems.length || !!this.props.slots?.default;
|
||||
}
|
||||
|
||||
get cogItems() {
|
||||
const registryMenus = [];
|
||||
for (const item of cogMenuRegistry.getAll()) {
|
||||
if ("isDisplayed" in item ? item.isDisplayed(this.env) : true) {
|
||||
registryMenus.push({
|
||||
Component: item.Component,
|
||||
groupNumber: item.groupNumber,
|
||||
key: item.Component.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
return registryMenus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="web.CogMenu" owl="1">
|
||||
<div t-if="hasItems" class="o_cp_action_menus d-flex pe-2 gap-1">
|
||||
<Dropdown togglerClass="'d-print-none btn btn-text ms-1 lh-sm'">
|
||||
<t t-set-slot="toggler">
|
||||
<i class="fa fa-cog"/>
|
||||
</t>
|
||||
<t t-foreach="cogItems" t-as="item" t-key="item.id or item.key">
|
||||
<t t-if="currentGroup !== null and currentGroup !== item.groupNumber">
|
||||
<div role="separator" class="dropdown-divider"/>
|
||||
</t>
|
||||
<t t-component="item.Component"/>
|
||||
<t t-set="currentGroup" t-value="item.groupNumber"/>
|
||||
</t>
|
||||
<t t-slot="default"/>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="web.CombinedActionMenus" owl="1">
|
||||
<div class="o_cp_action_menus d-flex pe-2 gap-1">
|
||||
<Dropdown togglerClass="'d-print-none btn btn-text ms-1 lh-sm'">
|
||||
<t t-set-slot="toggler">
|
||||
<i class="fa fa-cog"/>
|
||||
</t>
|
||||
<t t-if="printItems.length">
|
||||
<div class="dropdown-menu_group dropdown-header">
|
||||
<i class="me-md-1 fa fa-print"/>
|
||||
Print
|
||||
</div>
|
||||
<t t-foreach="printItems" t-as="item" t-key="item.key">
|
||||
<DropdownItem class="'o_menu_item'" onSelected="() => this.onItemSelected(item)">
|
||||
<t t-esc="item.description"/>
|
||||
</DropdownItem>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="actionItems.length">
|
||||
<div class="dropdown-menu_group dropdown-header">
|
||||
<i class="me-md-1 fa fa-cog"/>
|
||||
Action
|
||||
</div>
|
||||
<t t-foreach="actionItems" t-as="item" t-key="item.key">
|
||||
<t t-if="item.Component" t-component="item.Component" t-props="item.props" />
|
||||
<DropdownItem t-else="" class="'o_menu_item'" onSelected="() => this.onItemSelected(item)">
|
||||
<t t-esc="item.description"/>
|
||||
</DropdownItem>
|
||||
</t>
|
||||
</t>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -14,6 +14,7 @@ import { CalendarMobileFilterPanel } from "./mobile_filter_panel/calendar_mobile
|
||||
import { CalendarQuickCreate } from "./quick_create/calendar_quick_create";
|
||||
import { SearchBar } from "@web/search/search_bar/search_bar";
|
||||
import { ViewScaleSelector } from "@web/views/view_components/view_scale_selector";
|
||||
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
||||
|
||||
import { Component, useState } from "@odoo/owl";
|
||||
|
||||
@@ -220,5 +221,6 @@ CalendarController.components = {
|
||||
Layout,
|
||||
SearchBar,
|
||||
ViewScaleSelector,
|
||||
CogMenu,
|
||||
};
|
||||
CalendarController.template = "web.CalendarController";
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
<t t-name="web.CalendarController" owl="1">
|
||||
<div t-att-class="className" t-ref="root">
|
||||
<Layout className="model.useSampleModel ? 'o_view_sample_data' : ''" display="props.display">
|
||||
<t t-set-slot="control-panel-additional-actions">
|
||||
<CogMenu/>
|
||||
</t>
|
||||
<t t-set-slot="layout-buttons">
|
||||
<t t-call="{{ props.buttonTemplate }}"/>
|
||||
</t>
|
||||
|
||||
@@ -9,7 +9,6 @@ import { SIZES } from "@web/core/ui/ui_service";
|
||||
import { useBus, useService } from "@web/core/utils/hooks";
|
||||
import { omit } from "@web/core/utils/objects";
|
||||
import { createElement } from "@web/core/utils/xml";
|
||||
import { CombinedActionMenus } from "@web/search/combined_action_menus/combined_action_menus";
|
||||
import { Layout } from "@web/search/layout";
|
||||
import { usePager } from "@web/search/pager_hook";
|
||||
import { useModel } from "@web/views/model";
|
||||
@@ -21,6 +20,8 @@ import { FormStatusIndicator } from "./form_status_indicator/form_status_indicat
|
||||
import { ButtonBox } from "./button_box/button_box";
|
||||
import { ViewButton } from "@web/views/view_button/view_button";
|
||||
import { Field } from "@web/views/fields/field";
|
||||
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
||||
import { ActionMenusItems } from "@web/search/cog_menu/action_menus_items";
|
||||
|
||||
import { Component, onRendered, useEffect, useRef, useState } from "@odoo/owl";
|
||||
import { useViewCompiler } from "../view_compiler";
|
||||
@@ -496,12 +497,13 @@ export class FormController extends Component {
|
||||
|
||||
FormController.template = `web.FormView`;
|
||||
FormController.components = {
|
||||
CombinedActionMenus,
|
||||
FormStatusIndicator,
|
||||
Layout,
|
||||
ButtonBox,
|
||||
ViewButton,
|
||||
Field,
|
||||
CogMenu,
|
||||
ActionMenusItems,
|
||||
};
|
||||
FormController.props = {
|
||||
...standardViewProps,
|
||||
|
||||
@@ -30,16 +30,18 @@
|
||||
|
||||
<t t-set-slot="control-panel-additional-actions">
|
||||
<t t-if="props.info.actionMenus">
|
||||
<CombinedActionMenus
|
||||
getActiveIds="() => model.root.isNew ? [] : [model.root.resId]"
|
||||
context="props.context"
|
||||
items="actionMenuItems"
|
||||
isDomainSelected="model.root.isDomainSelected"
|
||||
resModel="model.root.resModel"
|
||||
domain="props.domain"
|
||||
onActionExecuted="() => model.load({ resId: model.root.resId, resIds: model.root.resIds })"
|
||||
shouldExecuteAction.bind="shouldExecuteAction"
|
||||
/>
|
||||
<CogMenu>
|
||||
<ActionMenusItems
|
||||
getActiveIds="() => model.root.isNew ? [] : [model.root.resId]"
|
||||
context="props.context"
|
||||
items="actionMenuItems"
|
||||
isDomainSelected="model.root.isDomainSelected"
|
||||
resModel="model.root.resModel"
|
||||
domain="props.domain"
|
||||
onActionExecuted="() => model.load({ resId: model.root.resId, resIds: model.root.resIds })"
|
||||
shouldExecuteAction.bind="shouldExecuteAction"
|
||||
/>
|
||||
</CogMenu>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useModel } from "@web/views/model";
|
||||
import { standardViewProps } from "@web/views/standard_view_props";
|
||||
import { useSetupView } from "@web/views/view_hook";
|
||||
import { SearchBar } from "@web/search/search_bar/search_bar";
|
||||
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
||||
|
||||
import { Component, useRef } from "@odoo/owl";
|
||||
|
||||
@@ -45,7 +46,7 @@ export class GraphController extends Component {
|
||||
}
|
||||
|
||||
GraphController.template = "web.GraphView";
|
||||
GraphController.components = { Layout, GroupByMenu, SearchBar };
|
||||
GraphController.components = { Layout, GroupByMenu, SearchBar, CogMenu };
|
||||
|
||||
GraphController.props = {
|
||||
...standardViewProps,
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
<t t-name="web.GraphView" owl="1">
|
||||
<div t-att-class="props.className" t-ref="root">
|
||||
<Layout className="model.useSampleModel ? 'o_view_sample_data' : ''" display="props.display">
|
||||
<t t-set-slot="control-panel-additional-actions">
|
||||
<CogMenu/>
|
||||
</t>
|
||||
<t t-set-slot="layout-actions">
|
||||
<SearchBar/>
|
||||
</t>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useViewButtons } from "@web/views/view_button/view_button_hook";
|
||||
import { useSetupView } from "@web/views/view_hook";
|
||||
import { KanbanRenderer } from "./kanban_renderer";
|
||||
import { SearchBar } from "@web/search/search_bar/search_bar";
|
||||
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
||||
|
||||
import { Component, reactive, useRef } from "@odoo/owl";
|
||||
|
||||
@@ -175,7 +176,7 @@ export class KanbanController extends Component {
|
||||
}
|
||||
|
||||
KanbanController.template = `web.KanbanView`;
|
||||
KanbanController.components = { Layout, KanbanRenderer, MultiRecordViewButton, SearchBar };
|
||||
KanbanController.components = { Layout, KanbanRenderer, MultiRecordViewButton, SearchBar, CogMenu };
|
||||
KanbanController.props = {
|
||||
...standardViewProps,
|
||||
defaultGroupBy: { validate: (dgb) => !dgb || typeof dgb === "string", optional: true },
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-set-slot="control-panel-additional-actions">
|
||||
<CogMenu/>
|
||||
</t>
|
||||
<t t-set-slot="layout-actions">
|
||||
<SearchBar/>
|
||||
</t>
|
||||
|
||||
@@ -23,6 +23,8 @@ import { ListConfirmationDialog } from "./list_confirmation_dialog";
|
||||
import { SearchBar } from "@web/search/search_bar/search_bar";
|
||||
import { Dropdown } from "@web/core/dropdown/dropdown";
|
||||
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
||||
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
||||
import { ActionMenusItems } from "@web/search/cog_menu/action_menus_items";
|
||||
|
||||
import { Component, onMounted, onWillStart, useEffect, useRef, useSubEnv } from "@odoo/owl";
|
||||
|
||||
@@ -589,7 +591,7 @@ export class ListController extends Component {
|
||||
}
|
||||
|
||||
ListController.template = `web.ListView`;
|
||||
ListController.components = { ActionMenus, Layout, ViewButton, MultiRecordViewButton, SearchBar, Dropdown, DropdownItem };
|
||||
ListController.components = { ActionMenus, Layout, ViewButton, MultiRecordViewButton, SearchBar, Dropdown, DropdownItem, CogMenu, ActionMenusItems };
|
||||
ListController.props = {
|
||||
...standardViewProps,
|
||||
allowSelectors: { type: Boolean, optional: true },
|
||||
|
||||
@@ -63,14 +63,21 @@
|
||||
</t>
|
||||
</div>
|
||||
<t t-else="">
|
||||
<Dropdown togglerClass="'d-print-none btn btn-text ms-1 lh-sm'">
|
||||
<t t-set-slot="toggler">
|
||||
<i class="fa fa-cog"/>
|
||||
</t>
|
||||
<CogMenu>
|
||||
<DropdownItem t-if="nbTotal and !nbSelected and activeActions.exportXlsx and isExportEnable" onSelected.bind="onDirectExportData">
|
||||
Export All
|
||||
</DropdownItem>
|
||||
</Dropdown>
|
||||
<t t-if="props.info.actionMenus">
|
||||
<ActionMenusItems
|
||||
getActiveIds="() => model.root.selection.map((r) => r.resId)"
|
||||
context="props.context"
|
||||
domain="props.domain"
|
||||
items="actionMenuItems"
|
||||
isDomainSelected="model.root.isDomainSelected"
|
||||
resModel="model.root.resModel"
|
||||
onActionExecuted="() => model.load()"/>
|
||||
</t>
|
||||
</CogMenu>
|
||||
</t>
|
||||
</t>
|
||||
<t t-component="props.Renderer" list="model.root" activeActions="activeActions" archInfo="archInfo" allowSelectors="props.allowSelectors" editable="editable" openRecord.bind="openRecord" noContentHelp="props.info.noContentHelp" onAdd.bind="createRecord"/>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useModel } from "@web/views/model";
|
||||
import { standardViewProps } from "@web/views/standard_view_props";
|
||||
import { useSetupView } from "@web/views/view_hook";
|
||||
import { SearchBar } from "@web/search/search_bar/search_bar";
|
||||
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
||||
|
||||
import { Component, useRef } from "@odoo/owl";
|
||||
|
||||
@@ -34,7 +35,7 @@ export class PivotController extends Component {
|
||||
}
|
||||
|
||||
PivotController.template = "web.PivotView";
|
||||
PivotController.components = { Layout, SearchBar };
|
||||
PivotController.components = { Layout, SearchBar, CogMenu };
|
||||
|
||||
PivotController.props = {
|
||||
...standardViewProps,
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
<t t-name="web.PivotView" owl="1">
|
||||
<div t-att-class="props.className" t-ref="root">
|
||||
<Layout className="model.useSampleModel ? 'o_view_sample_data' : ''" display="props.display">
|
||||
<t t-set-slot="control-panel-additional-actions">
|
||||
<CogMenu/>
|
||||
</t>
|
||||
<t t-set-slot="layout-actions">
|
||||
<SearchBar/>
|
||||
</t>
|
||||
|
||||
Reference in New Issue
Block a user