From 7de75a96004673b1e5a9d5860f86e72b7331f3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A0n=20Todorovich?= Date: Tue, 19 Jul 2022 14:39:40 -0300 Subject: [PATCH] [FIX] web_advanced_search: Implement 'Add Custom Filter' for owl widgets (pivot, graph) Steps to reproduce: 1. Go to any Pivot or Graph view. 2. Add a custom filter, for example, Company. 3. Use the "is equal to" operator. Result: Uncaught Promise > Cannot find the definition of component "RecordPicker" --- This happens because in Odoo 15.0 there are two versions of the FilterMenu and CustomFilterItem widgets: one implemented in the legacy widget framework [^1] and another implemented in Owl [^2]. The legacy version is used for `tree` views, for example; whilst the Owl version is used for `pivot` and `graph` views. Confusing as it is, before this commit only the legacy version was being overriden, making it work for `tree` views (most common case), but not for `pivot` views. Since both versions share the same QWeb template, though, not only it wasn't working for `pivot`, but it also raised an Exception. [^1]: https://github.com/odoo/odoo/blob/21a2dfd90/addons/web/static/src/legacy/js/control_panel/custom_filter_item.js#L45 [^2]: https://github.com/odoo/odoo/blob/21a2dfd90/addons/web/static/src/search/filter_menu/custom_filter_item.js#L107 --- .../static/src/js/RecordPicker.esm.js | 3 + .../src/js/legacy/CustomFilterItem.esm.js | 7 +- .../static/src/js/legacy/FilterMenu.esm.js | 7 +- .../static/src/js/owl/CustomFilterItem.esm.js | 87 +++++++++++++++++++ .../static/src/js/owl/FilterMenu.esm.js | 21 +++++ 5 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 web_advanced_search/static/src/js/owl/CustomFilterItem.esm.js create mode 100644 web_advanced_search/static/src/js/owl/FilterMenu.esm.js diff --git a/web_advanced_search/static/src/js/RecordPicker.esm.js b/web_advanced_search/static/src/js/RecordPicker.esm.js index 83011139d..607c0a829 100644 --- a/web_advanced_search/static/src/js/RecordPicker.esm.js +++ b/web_advanced_search/static/src/js/RecordPicker.esm.js @@ -105,6 +105,9 @@ export const FakeMany2oneFieldWidget = FieldMany2One.extend(FieldManagerMixin, { }); export class FakeMany2oneFieldWidgetAdapter extends ComponentAdapter { + setup() { + this.env = owl.Component.env; + } async updateWidget() { /* eslint-disable no-empty-function */ } diff --git a/web_advanced_search/static/src/js/legacy/CustomFilterItem.esm.js b/web_advanced_search/static/src/js/legacy/CustomFilterItem.esm.js index a29fad4ad..d26913bb1 100644 --- a/web_advanced_search/static/src/js/legacy/CustomFilterItem.esm.js +++ b/web_advanced_search/static/src/js/legacy/CustomFilterItem.esm.js @@ -4,7 +4,12 @@ import {patch} from "@web/core/utils/patch"; import CustomFilterItem from "web.CustomFilterItem"; import {RecordPicker} from "../RecordPicker.esm"; - +/** + * Patches the CustomFilterItem for legacy widgets. + * + * Tree views still use this old legacy widget, so we need to patch it. + * This is likely to dissapear in 16.0 + */ patch(CustomFilterItem.prototype, "web_advanced_search.legacy.CustomFilterItem", { /** * Ideally we'd want this in setup, but CustomFilterItem does its initialization diff --git a/web_advanced_search/static/src/js/legacy/FilterMenu.esm.js b/web_advanced_search/static/src/js/legacy/FilterMenu.esm.js index a32d9c40b..8f11ad0f8 100644 --- a/web_advanced_search/static/src/js/legacy/FilterMenu.esm.js +++ b/web_advanced_search/static/src/js/legacy/FilterMenu.esm.js @@ -4,7 +4,12 @@ import {patch} from "@web/core/utils/patch"; import FilterMenu from "web.FilterMenu"; import AdvancedFilterItem from "../AdvancedFilterItem.esm"; - +/** + * Patches the FilterMenu for legacy widgets. + * + * Tree views still use this old legacy widget, so we need to patch it. + * This is likely to dissapear in 16.0 + */ patch(FilterMenu, "web_advanced_search.legacy.FilterMenu", { components: { ...FilterMenu.components, diff --git a/web_advanced_search/static/src/js/owl/CustomFilterItem.esm.js b/web_advanced_search/static/src/js/owl/CustomFilterItem.esm.js new file mode 100644 index 000000000..f4d4c6468 --- /dev/null +++ b/web_advanced_search/static/src/js/owl/CustomFilterItem.esm.js @@ -0,0 +1,87 @@ +/** @odoo-module **/ + +import {patch} from "@web/core/utils/patch"; +import {CustomFilterItem} from "@web/search/filter_menu/custom_filter_item"; +import {RecordPicker} from "../RecordPicker.esm"; + +/** + * Patches the CustomFilterItem for owl widgets. + * + * Pivot and Graph views use this new owl widget, so we need to patch it. + * Other views like Tree use the old legacy widget that will probably dissapear + * in 16.0. Until then, we need to patch both. + */ +patch(CustomFilterItem.prototype, "web_advanced_search.CustomFilterItem", { + /** + * @override + */ + setup() { + this._super.apply(this, arguments); + this.OPERATORS.relational = this.OPERATORS.char; + this.FIELD_TYPES.many2one = "relational"; + }, + /** + * @override + */ + setDefaultValue(condition) { + const res = this._super.apply(this, arguments); + const fieldType = this.fields[condition.field].type; + const genericType = this.FIELD_TYPES[fieldType]; + if (genericType === "relational") { + condition.value = 0; + condition.displayedValue = ""; + } + return res; + }, + /** + * Add displayed value to preFilters for "relational" types. + * + * @override + */ + onApply() { + // To avoid the complete override, we patch this.conditions.map() + const originalMapFn = this.conditions.map; + const self = this; + this.conditions.map = function () { + const preFilters = originalMapFn.apply(this, arguments); + for (const condition of this) { + const field = self.fields[condition.field]; + const type = self.FIELD_TYPES[field.type]; + if (type === "relational") { + const idx = this.indexOf(condition); + const preFilter = preFilters[idx]; + const operator = self.OPERATORS[type][condition.operator]; + const descriptionArray = [ + field.string, + operator.description, + `"${condition.displayedValue}"`, + ]; + preFilter.description = descriptionArray.join(" "); + } + } + return preFilters; + }; + const res = this._super.apply(this, arguments); + // Restore original map() + this.conditions.map = originalMapFn; + return res; + }, + /** + * @private + * @param {Object} condition + * @param {OwlEvent} ev + */ + onRelationalChanged(condition, ev) { + condition.value = ev.detail.id; + condition.displayedValue = ev.detail.display_name; + }, +}); + +patch(CustomFilterItem, "web_advanced_search.CustomFilterItem", { + components: { + ...CustomFilterItem.components, + RecordPicker, + }, +}); + +export default CustomFilterItem; diff --git a/web_advanced_search/static/src/js/owl/FilterMenu.esm.js b/web_advanced_search/static/src/js/owl/FilterMenu.esm.js new file mode 100644 index 000000000..4afecd8c9 --- /dev/null +++ b/web_advanced_search/static/src/js/owl/FilterMenu.esm.js @@ -0,0 +1,21 @@ +/** @odoo-module **/ + +import {patch} from "@web/core/utils/patch"; +import {FilterMenu} from "@web/search/filter_menu/filter_menu"; +import AdvancedFilterItem from "../AdvancedFilterItem.esm"; + +/** + * Patches the FilterMenu for owl widgets. + * + * Pivot and Graph views use this new owl widget, so we need to patch it. + * Other views like Tree use the old legacy widget that will probably dissapear + * in 16.0. Until then, we need to patch both. + */ +patch(FilterMenu, "web_advanced_search.FilterMenu", { + components: { + ...FilterMenu.components, + AdvancedFilterItem, + }, +}); + +export default FilterMenu;