diff --git a/addons/spreadsheet/static/src/global_filters/components/filter_value/filter_value.js b/addons/spreadsheet/static/src/global_filters/components/filter_value/filter_value.js index 8c557a496ca..097dc4c2e2b 100644 --- a/addons/spreadsheet/static/src/global_filters/components/filter_value/filter_value.js +++ b/addons/spreadsheet/static/src/global_filters/components/filter_value/filter_value.js @@ -1,16 +1,18 @@ /** @odoo-module */ -import { RecordsSelector } from "../records_selector/records_selector"; +import { MultiRecordSelector } from "@web/core/record_selectors/multi_record_selector"; import { RELATIVE_DATE_RANGE_TYPES } from "@spreadsheet/helpers/constants"; import { DateFilterValue } from "../filter_date_value/filter_date_value"; import { Component } from "@odoo/owl"; import { _t } from "@web/core/l10n/translation"; +import { useService } from "@web/core/utils/hooks"; export class FilterValue extends Component { setup() { this.getters = this.props.model.getters; this.relativeDateRangesTypes = RELATIVE_DATE_RANGE_TYPES; + this.nameService = useService("name"); } onDateInput(id, value) { this.props.model.dispatch("SET_GLOBAL_FILTER_VALUE", { id, value }); @@ -20,15 +22,19 @@ export class FilterValue extends Component { this.props.model.dispatch("SET_GLOBAL_FILTER_VALUE", { id, value }); } - onTagSelected(id, values) { - if (!values.length) { + async onTagSelected(id, resIds) { + if (!resIds.length) { // force clear, even automatic default values this.clear(id); } else { + const displayNames = await this.nameService.loadDisplayNames( + this.props.filter.modelName, + resIds + ); this.props.model.dispatch("SET_GLOBAL_FILTER_VALUE", { id, - value: values.map((record) => record.id), - displayNames: values.map((record) => record.display_name), + value: resIds, + displayNames: Object.values(displayNames), }); } } @@ -42,7 +48,7 @@ export class FilterValue extends Component { } } FilterValue.template = "spreadsheet_edition.FilterValue"; -FilterValue.components = { RecordsSelector, DateFilterValue }; +FilterValue.components = { DateFilterValue, MultiRecordSelector }; FilterValue.props = { filter: Object, model: Object, diff --git a/addons/spreadsheet/static/src/global_filters/components/filter_value/filter_value.xml b/addons/spreadsheet/static/src/global_filters/components/filter_value/filter_value.xml index 2db0fd4d5d4..dc457faf319 100644 --- a/addons/spreadsheet/static/src/global_filters/components/filter_value/filter_value.xml +++ b/addons/spreadsheet/static/src/global_filters/components/filter_value/filter_value.xml @@ -6,7 +6,7 @@ + t-value="getters.getGlobalFilterValue(filter.id) || []"/>
- + update="(resIds) => this.onTagSelected(filter.id, resIds)" />
} */ - this.displayNames = {}; - /** @type {import("@web/core/orm_service").ORM}*/ - this.orm = useService("orm"); - onWillStart(() => this.fetchMissingDisplayNames(this.props.resModel, this.props.resIds)); - onWillUpdateProps((nextProps) => - this.fetchMissingDisplayNames(nextProps.resModel, nextProps.resIds) - ); - } - - get tags() { - return this.props.resIds.map((id) => ({ - text: this.displayNames[id], - onDelete: () => this.removeRecord(id), - })); - } - - onKeydown(ev) { - if (this.props.resIds.length === 0) { - return; - } - if (ev.key.toUpperCase() === "BACKSPACE") { - this.removeRecord(this.props.resIds[this.props.resIds.length - 1]); - } - } - - searchDomain() { - return Domain.not([["id", "in", this.props.resIds]]).toList(); - } - - /** - * @param {number} recordId - */ - removeRecord(recordId) { - delete this.displayNames[recordId]; - this.notifyChange(this.props.resIds.filter((id) => id !== recordId)); - } - - /** - * @param {{ id: number; display_name?: string}[]} records - */ - update(records) { - for (const record of records.filter((record) => record.display_name)) { - this.displayNames[record.id] = record.display_name; - } - this.notifyChange(this.props.resIds.concat(records.map(({ id }) => id))); - } - - /** - * @param {number[]} selectedIds - */ - notifyChange(selectedIds) { - this.props.onValueChanged( - selectedIds.map((id) => ({ id, display_name: this.displayNames[id] })) - ); - } - - /** - * @param {string} resModel - * @param {number[]} recordIds - */ - async fetchMissingDisplayNames(resModel, recordIds) { - const missingNameIds = recordIds.filter((id) => !(id in this.displayNames)); - if (missingNameIds.length === 0) { - return; - } - const results = await this.orm.read(resModel, missingNameIds, ["display_name"]); - for (const { id, display_name } of results) { - this.displayNames[id] = display_name; - } - } -} -RecordsSelector.components = { TagsList, Many2XAutocomplete }; -RecordsSelector.template = "spreadsheet.RecordsSelector"; -RecordsSelector.props = { - /** - * Callback called when a record is selected or removed. - * (selectedRecords: Array<{ id: number; display_name: string }>) => void - **/ - onValueChanged: Function, - resModel: String, - /** - * Array of selected record ids - */ - resIds: { - optional: true, - type: Array, - }, - placeholder: { - optional: true, - type: String, - }, -}; -RecordsSelector.defaultProps = { - resIds: [], -}; diff --git a/addons/spreadsheet/static/src/global_filters/components/records_selector/records_selector.xml b/addons/spreadsheet/static/src/global_filters/components/records_selector/records_selector.xml deleted file mode 100644 index 2ef06114845..00000000000 --- a/addons/spreadsheet/static/src/global_filters/components/records_selector/records_selector.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -
-
- -
- -
-
-
-
diff --git a/addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet_extended.dark.scss b/addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet_extended.dark.scss index e8112f5c13f..fb6c5d4c180 100644 --- a/addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet_extended.dark.scss +++ b/addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet_extended.dark.scss @@ -14,7 +14,7 @@ .o-selection-statistic { background-color: #fff !important; } - .o_field_tags .badge { + .o_multi_record_selector .badge { background-color: #e6dddd !important; color: #3c3c3c !important; } diff --git a/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_action.scss b/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_action.scss index 244f0a07dd3..e8799dcdb60 100644 --- a/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_action.scss +++ b/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_action.scss @@ -68,7 +68,7 @@ min-height: 25px; min-width: 100px; - .o_field_many2many_tags { + .o_multi_record_selector { width: 100%; } diff --git a/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_action_test.js b/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_action_test.js index 745af57f904..3857c4fec77 100644 --- a/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_action_test.js +++ b/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_action_test.js @@ -205,7 +205,7 @@ QUnit.test("Can delete record tag in the filter by hitting Backspace", async fun const serverData = getServerData(spreadsheetData); const fixture = getFixture(); await createSpreadsheetDashboard({ serverData }); - const filter = fixture.querySelector(".o_control_panel_actions div.o_field_tags"); + const filter = fixture.querySelector(".o_control_panel_actions div.o_multi_record_selector"); const autoCompleteInput = filter.querySelector(".o-autocomplete--input.o_input"); assert.equal(filter.querySelectorAll(".o_tag").length, 1);