diff --git a/addons/web/static/src/core/select_menu/select_menu.js b/addons/web/static/src/core/select_menu/select_menu.js index f0f4e15efec..804519fbaed 100644 --- a/addons/web/static/src/core/select_menu/select_menu.js +++ b/addons/web/static/src/core/select_menu/select_menu.js @@ -8,16 +8,18 @@ import { shallowEqual } from "@web/core/utils/objects"; import { useDebounced } from "@web/core/utils/timing"; import { scrollTo } from "@web/core/utils/scrolling"; import { fuzzyLookup } from "@web/core/utils/search"; +import { TagsList } from "@web/views/fields/many2many_tags/tags_list"; export class SelectMenu extends Component { static template = "web.SelectMenu"; - static components = { Dropdown, DropdownItem }; + static components = { Dropdown, DropdownItem, TagsList }; static defaultProps = { value: undefined, class: "", togglerClass: "", + multiSelect: false, onSelect: () => {}, required: false, searchable: true, @@ -64,6 +66,7 @@ export class SelectMenu extends Component { searchable: { type: Boolean, optional: true }, searchPlaceholder: { type: String, optional: true }, value: { optional: true }, + multiSelect: { type: Boolean, optional: true }, onSelect: { type: Function, optional: true }, slots: { type: Object, optional: true }, }; @@ -101,6 +104,24 @@ export class SelectMenu extends Component { return ""; } + get multiSelectChoices() { + const choices = [ + ...this.props.choices, + ...this.props.groups.flatMap((g) => g.choices), + ].filter((c) => this.props.value.includes(c.value)); + return choices.map((c) => { + return { + id: c.value, + text: c.label, + onDelete: () => { + const values = [...this.props.value]; + values.splice(values.indexOf(c.value), 1); + this.props.onSelect(values); + }, + }; + }); + } + onOpened() { // Using useAutofocus inside the dropdown does not // work properly so we set the focus manually. @@ -115,6 +136,9 @@ export class SelectMenu extends Component { } isOptionSelected(choice) { + if (this.props.multiSelect) { + return this.props.value.includes(choice.value); + } return this.props.value === choice.value; } @@ -214,6 +238,14 @@ export class SelectMenu extends Component { return choices.flatMap((choice, index) => (index === 0 ? 0 : choice.isGroup ? index : [])); } + onItemSelected(value) { + if (this.props.multiSelect) { + this.props.onSelect([...this.props.value, value]); + } else { + this.props.onSelect(value); + } + } + // ========================================================================================== // # Scroll # // ========================================================================================== diff --git a/addons/web/static/src/core/select_menu/select_menu.scss b/addons/web/static/src/core/select_menu/select_menu.scss index d8c1c56042d..ac8b6a39915 100644 --- a/addons/web/static/src/core/select_menu/select_menu.scss +++ b/addons/web/static/src/core/select_menu/select_menu.scss @@ -23,6 +23,10 @@ top: 40px; } } + + .o_tag { + margin: 2px; + } } .dropup .o_select_menu_menu { diff --git a/addons/web/static/src/core/select_menu/select_menu.xml b/addons/web/static/src/core/select_menu/select_menu.xml index 0616aa26704..1709c6525e8 100644 --- a/addons/web/static/src/core/select_menu/select_menu.xml +++ b/addons/web/static/src/core/select_menu/select_menu.xml @@ -12,13 +12,20 @@ onScroll.bind="onScroll" > - - - - - - - + +
+ +
+
+ + + + + + + + + @@ -45,7 +52,7 @@ diff --git a/addons/web/static/src/views/calendar/calendar_controller.js b/addons/web/static/src/views/calendar/calendar_controller.js index c0e655cd1dc..f83a1aa7c3f 100644 --- a/addons/web/static/src/views/calendar/calendar_controller.js +++ b/addons/web/static/src/views/calendar/calendar_controller.js @@ -15,7 +15,7 @@ import { CalendarQuickCreate } from "./quick_create/calendar_quick_create"; import { Component, useState } from "@odoo/owl"; -const SCALE_LABELS = { +export const SCALE_LABELS = { day: _lt("Day"), week: _lt("Week"), month: _lt("Month"),