From 2d28239f9bb893799ed46e5d6fd73f233d7e8d94 Mon Sep 17 00:00:00 2001 From: luvi Date: Thu, 23 Mar 2023 09:58:28 +0000 Subject: [PATCH] [IMP] web: SelectMenu has multiSelect props This commit adds the ability to select multiple values from the SelectMenu component. A list of tags are displayed in the toggler to remove already selected values, and selected values are colored in the list of choices. This feature is similar to how jquery select2 handles multiple selections, by adding the values in the input toggler. The feature will be used by the studio sidebar during the refactor. Part-of: odoo/odoo#115799 --- .../src/core/select_menu/select_menu.js | 34 ++++++++++++++++++- .../src/core/select_menu/select_menu.scss | 4 +++ .../src/core/select_menu/select_menu.xml | 23 ++++++++----- .../src/views/calendar/calendar_controller.js | 2 +- 4 files changed, 53 insertions(+), 10 deletions(-) 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"),