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/AdvancedFilterItem.esm.js b/web_advanced_search/static/src/js/legacy/AdvancedFilterItem.esm.js
similarity index 97%
rename from web_advanced_search/static/src/js/AdvancedFilterItem.esm.js
rename to web_advanced_search/static/src/js/legacy/AdvancedFilterItem.esm.js
index 73360f387..0a837abda 100644
--- a/web_advanced_search/static/src/js/AdvancedFilterItem.esm.js
+++ b/web_advanced_search/static/src/js/legacy/AdvancedFilterItem.esm.js
@@ -1,6 +1,6 @@
/** @odoo-module **/
-import {getHumanDomain} from "./utils.esm";
+import {getHumanDomain} from "../utils.esm";
import config from "web.config";
import DomainSelectorDialog from "web.DomainSelectorDialog";
diff --git a/web_advanced_search/static/src/js/CustomFilterItem.esm.js b/web_advanced_search/static/src/js/legacy/CustomFilterItem.esm.js
similarity index 87%
rename from web_advanced_search/static/src/js/CustomFilterItem.esm.js
rename to web_advanced_search/static/src/js/legacy/CustomFilterItem.esm.js
index 7ed4d085c..d26913bb1 100644
--- a/web_advanced_search/static/src/js/CustomFilterItem.esm.js
+++ b/web_advanced_search/static/src/js/legacy/CustomFilterItem.esm.js
@@ -2,9 +2,15 @@
import {patch} from "@web/core/utils/patch";
import CustomFilterItem from "web.CustomFilterItem";
-import {RecordPicker} from "./RecordPicker.esm";
+import {RecordPicker} from "../RecordPicker.esm";
-patch(CustomFilterItem.prototype, "web_advanced_search.CustomFilterItem", {
+/**
+ * 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
* in the constructor, which can't be patched.
@@ -75,7 +81,7 @@ patch(CustomFilterItem.prototype, "web_advanced_search.CustomFilterItem", {
},
});
-patch(CustomFilterItem, "web_advanced_search.CustomFilterItem", {
+patch(CustomFilterItem, "web_advanced_search.legacy.CustomFilterItem", {
components: {
...CustomFilterItem.components,
RecordPicker,
diff --git a/web_advanced_search/static/src/js/FilterMenu.esm.js b/web_advanced_search/static/src/js/legacy/FilterMenu.esm.js
similarity index 55%
rename from web_advanced_search/static/src/js/FilterMenu.esm.js
rename to web_advanced_search/static/src/js/legacy/FilterMenu.esm.js
index 255e50e4a..578e88e08 100644
--- a/web_advanced_search/static/src/js/FilterMenu.esm.js
+++ b/web_advanced_search/static/src/js/legacy/FilterMenu.esm.js
@@ -4,7 +4,13 @@ import {patch} from "@web/core/utils/patch";
import FilterMenu from "web.FilterMenu";
import AdvancedFilterItem from "./AdvancedFilterItem.esm";
-patch(FilterMenu, "web_advanced_search.FilterMenu", {
+/**
+ * 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,
AdvancedFilterItem,
diff --git a/web_advanced_search/static/src/js/owl/AdvancedFilterItem.esm.js b/web_advanced_search/static/src/js/owl/AdvancedFilterItem.esm.js
new file mode 100644
index 000000000..71b740bbe
--- /dev/null
+++ b/web_advanced_search/static/src/js/owl/AdvancedFilterItem.esm.js
@@ -0,0 +1,57 @@
+/** @odoo-module **/
+
+import {getHumanDomain} from "../utils.esm";
+
+import config from "web.config";
+import DomainSelectorDialog from "web.DomainSelectorDialog";
+import Domain from "web.Domain";
+import {ComponentAdapter} from "web.OwlCompatibility";
+
+const {Component, hooks} = owl;
+const {useRef} = hooks;
+
+export default class AdvancedFilterItem extends Component {
+ setup() {
+ this.itemRef = useRef("dropdown-item");
+ }
+ /**
+ * Prevent propagation of dropdown-item-selected event, so that it
+ * doesn't reaches the FilterMenu onFilterSelected event handler.
+ */
+ mounted() {
+ $(this.itemRef.el).on("dropdown-item-selected", (event) =>
+ event.stopPropagation()
+ );
+ }
+ /**
+ * Open advanced search dialog
+ *
+ * @returns {DomainSelectorDialog} The opened dialog itself.
+ */
+ onClick() {
+ const adapterParent = new ComponentAdapter(null, {Component});
+ const dialog = new DomainSelectorDialog(
+ adapterParent,
+ this.env.searchModel.resModel,
+ "[]",
+ {
+ debugMode: config.isDebug(),
+ readonly: false,
+ }
+ );
+ // Add 1st domain node by default
+ dialog.opened(() => dialog.domainSelector._onAddFirstButtonClick());
+ // Configure handler
+ dialog.on("domain_selected", this, function (e) {
+ const preFilter = {
+ description: getHumanDomain(dialog.domainSelector),
+ domain: Domain.prototype.arrayToString(e.data.domain),
+ type: "filter",
+ };
+ this.env.searchModel.createNewFilters([preFilter]);
+ });
+ return dialog.open();
+ }
+}
+
+AdvancedFilterItem.template = "web_advanced_search.AdvancedFilterItem";
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..1e22fbb70
--- /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;
diff --git a/web_advanced_search/static/src/xml/FilterMenu.xml b/web_advanced_search/static/src/xml/FilterMenu.xml
index 34dd3d4b8..058a9b17b 100644
--- a/web_advanced_search/static/src/xml/FilterMenu.xml
+++ b/web_advanced_search/static/src/xml/FilterMenu.xml
@@ -10,4 +10,9 @@
+
+
+
+
+