diff --git a/addons/web/static/src/core/domain_selector/domain_selector.js b/addons/web/static/src/core/domain_selector/domain_selector.js index 8b76fac6558..ae1175d9bca 100644 --- a/addons/web/static/src/core/domain_selector/domain_selector.js +++ b/addons/web/static/src/core/domain_selector/domain_selector.js @@ -11,7 +11,7 @@ import { Component, onWillStart, onWillUpdateProps } from "@odoo/owl"; import { Domain } from "@web/core/domain"; import { Dropdown } from "@web/core/dropdown/dropdown"; import { DropdownItem } from "@web/core/dropdown/dropdown_item"; -import { getOperatorInfo } from "@web/core/domain_selector/domain_selector_operators"; +import { getOperatorInfo, toOperator } from "@web/core/domain_selector/domain_selector_operators"; import { Editor, PathEditor, @@ -207,8 +207,10 @@ export class DomainSelector extends Component { this.notifyChanges(); } - updateLeafOperator(node, operator) { + updateLeafOperator(node, operatorKey) { + const [operator, negate] = toOperator(operatorKey); const previousOperatorInfo = getOperatorInfo(node.operator); + node.negate = negate; node.operator = operator; const operatorInfo = getOperatorInfo(operator); if (previousOperatorInfo.valueCount !== operatorInfo.valueCount) { diff --git a/addons/web/static/src/core/domain_selector/domain_selector_operators.js b/addons/web/static/src/core/domain_selector/domain_selector_operators.js index df20141938b..b5b9eaf241d 100644 --- a/addons/web/static/src/core/domain_selector/domain_selector_operators.js +++ b/addons/web/static/src/core/domain_selector/domain_selector_operators.js @@ -1,8 +1,9 @@ /** @odoo-module **/ import { _lt } from "@web/core/l10n/translation"; -import { formatValue } from "@web/core/domain_tree"; +import { formatValue, toValue } from "@web/core/domain_tree"; import { sprintf } from "@web/core/utils/strings"; +import { parseExpr } from "@web/core/py_js/py"; /** * @typedef {Object} OperatorInfo @@ -41,6 +42,22 @@ export const OPERATOR_DESCRIPTIONS = { between: { label: _lt("is between"), valueCount: 2 }, }; +function toKey(operator, negate = false) { + if (!negate && typeof operator === "string" && operator in OPERATOR_DESCRIPTIONS) { + // this case is the main one. We keep it simple + return operator; + } + return JSON.stringify([formatValue(operator), negate]); +} + +export function toOperator(key) { + if (!key.includes("[")) { + return [key, false]; + } + const [expr, negate] = JSON.parse(key); + return [toValue(parseExpr(expr)), negate]; +} + /** * @param {import("@web/core/domain_tree").Value} operator * @param {boolean} [negate=false] @@ -48,12 +65,19 @@ export const OPERATOR_DESCRIPTIONS = { */ export function getOperatorInfo(operator, negate = false) { let operatorInfo; + const key = toKey(operator, negate); if (typeof operator === "string" && operator in OPERATOR_DESCRIPTIONS) { const { label, valueCount } = OPERATOR_DESCRIPTIONS[operator]; - operatorInfo = { key: operator, label: label.toString(), operator, negate, valueCount }; + operatorInfo = { + key, + label: label.toString(), + operator, + negate, + valueCount, + }; } else { operatorInfo = { - key: "__unknown__", + key, label: formatValue(operator), operator, negate, diff --git a/addons/web/static/tests/core/domain_selector_tests.js b/addons/web/static/tests/core/domain_selector_tests.js index d1606d6f085..6c2b1e1d5ce 100644 --- a/addons/web/static/tests/core/domain_selector_tests.js +++ b/addons/web/static/tests/core/domain_selector_tests.js @@ -1405,4 +1405,12 @@ QUnit.module("Components", (hooks) => { }); assert.strictEqual(target.querySelector(".o_domain_leaf").textContent, `Foo = uid`); }); + + QUnit.test("display of an operator without negation defined (edit)", async (assert) => { + await makeDomainSelector({ + resModel: "partner", + domain: `["!", (expr, "parent_of", "a")]`, + }); + assert.strictEqual(getSelectedOperator(target), `not parent of`); + }); });