From 1ee5763ddaf7dccb3836ae99e6ef1c4ac3d9051e Mon Sep 17 00:00:00 2001 From: Simone Rubino Date: Mon, 5 Jan 2026 17:56:55 +0100 Subject: [PATCH] [FIX] web_domain_field: Accept empty domain Steps: 1. Create a domain field that contains `False` 2. Associate the created field to a relational field 3. In a form view, open the dropdown of the filtered relational field Before this change: The following client error is raised: > Error: second argument to Function.prototype.apply must be an array eval_domains/<@https://domain.com/web_domain_field/static/lib/js/pyeval.js:156:40 [...] After this change: All the records can be selected --- test-requirements.txt | 1 + web_domain_field/README.rst | 3 ++ web_domain_field/__manifest__.py | 4 +- web_domain_field/readme/CONTRIBUTORS.rst | 3 ++ .../static/description/index.html | 18 +++++--- web_domain_field/static/lib/js/pyeval.js | 2 +- .../static/tests/tours/false_domain.js | 31 ++++++++++++++ web_domain_field/tests/__init__.py | 3 ++ web_domain_field/tests/fake_model_views.xml | 29 +++++++++++++ web_domain_field/tests/ir.model.access.csv | 2 + web_domain_field/tests/models.py | 22 ++++++++++ web_domain_field/tests/test_domain_field.py | 42 +++++++++++++++++++ web_domain_field/views/web_domain_field.xml | 13 ++++++ 13 files changed, 165 insertions(+), 8 deletions(-) create mode 100644 test-requirements.txt create mode 100644 web_domain_field/static/tests/tours/false_domain.js create mode 100644 web_domain_field/tests/__init__.py create mode 100644 web_domain_field/tests/fake_model_views.xml create mode 100644 web_domain_field/tests/ir.model.access.csv create mode 100644 web_domain_field/tests/models.py create mode 100644 web_domain_field/tests/test_domain_field.py diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 000000000000..66bc2cbae3f9 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo_test_helper diff --git a/web_domain_field/README.rst b/web_domain_field/README.rst index bf8d31a5ffbb..adb554c01d3c 100644 --- a/web_domain_field/README.rst +++ b/web_domain_field/README.rst @@ -116,6 +116,9 @@ Contributors * Laurent Mignon * Denis Roussel * Raf Ven +* `PyTech `_: + + * Simone Rubino Maintainers ~~~~~~~~~~~ diff --git a/web_domain_field/__manifest__.py b/web_domain_field/__manifest__.py index ad868b8e456b..e0ea5e5dcd43 100644 --- a/web_domain_field/__manifest__.py +++ b/web_domain_field/__manifest__.py @@ -11,6 +11,8 @@ "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/web", "depends": ["web"], - "data": ["views/web_domain_field.xml"], + "data": [ + "views/web_domain_field.xml", + ], "installable": True, } diff --git a/web_domain_field/readme/CONTRIBUTORS.rst b/web_domain_field/readme/CONTRIBUTORS.rst index 1294ec29e0b3..7aa89ba5b055 100644 --- a/web_domain_field/readme/CONTRIBUTORS.rst +++ b/web_domain_field/readme/CONTRIBUTORS.rst @@ -1,3 +1,6 @@ * Laurent Mignon * Denis Roussel * Raf Ven +* `PyTech `_: + + * Simone Rubino diff --git a/web_domain_field/static/description/index.html b/web_domain_field/static/description/index.html index 8ddf0a71b422..4d9d080e95a8 100644 --- a/web_domain_field/static/description/index.html +++ b/web_domain_field/static/description/index.html @@ -1,4 +1,3 @@ - @@ -9,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -275,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -301,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -429,7 +429,7 @@

Usage

) @api.depends('name') -def _compute_product_id_domain(self): +def _compute_product_id_domain(self): for rec in self: rec.product_id_domain = json.dumps( [('type', '=', 'product'), ('name', 'like', rec.name)] @@ -458,12 +458,18 @@

Contributors

  • Laurent Mignon <laurent.mignon@acsone.eu>
  • Denis Roussel <denis.roussel@acsone.eu>
  • Raf Ven <raf.ven@dynapps.be>
  • +
  • PyTech: +
  • Maintainers

    This module is maintained by the OCA.

    -Odoo Community Association + +Odoo Community Association +

    OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

    diff --git a/web_domain_field/static/lib/js/pyeval.js b/web_domain_field/static/lib/js/pyeval.js index 6f2b9f61b787..4184bfdedf4d 100644 --- a/web_domain_field/static/lib/js/pyeval.js +++ b/web_domain_field/static/lib/js/pyeval.js @@ -154,7 +154,7 @@ odoo.define('web.domain_field', function (require) { // Modified part or the original method if (domain in evaluation_context) { result_domain.push.apply( - result_domain, $.parseJSON(evaluation_context[domain])); + result_domain, $.parseJSON(evaluation_context[domain]) || []); return; } // End of modifications diff --git a/web_domain_field/static/tests/tours/false_domain.js b/web_domain_field/static/tests/tours/false_domain.js new file mode 100644 index 000000000000..735e65bf9db9 --- /dev/null +++ b/web_domain_field/static/tests/tours/false_domain.js @@ -0,0 +1,31 @@ +odoo.define("web_domain_field.false_domain_tour", function (require) { + "use strict"; + + var tour = require("web_tour.tour"); + + tour.register( + "web_domain_field.false_domain_tour", + { + test: true, + url: "/web", + }, + [ + tour.stepUtils.showAppsMenuItem(), + { + content: "Go to Fake Model menu", + trigger: '.o_app[data-menu-xmlid="web_domain_field.fake_model_menu"]', + run: "click", + }, + { + content: "Create a new record", + trigger: "button.o_list_button_add", + run: "click", + }, + { + content: "Click on partner label (opens dropdown)", + trigger: "div.o_form_sheet label:contains('Partner')", + run: "click", + }, + ] + ); +}); diff --git a/web_domain_field/tests/__init__.py b/web_domain_field/tests/__init__.py new file mode 100644 index 000000000000..c783e46dc60a --- /dev/null +++ b/web_domain_field/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_domain_field diff --git a/web_domain_field/tests/fake_model_views.xml b/web_domain_field/tests/fake_model_views.xml new file mode 100644 index 000000000000..38a2add00ae6 --- /dev/null +++ b/web_domain_field/tests/fake_model_views.xml @@ -0,0 +1,29 @@ + + + + + Form view for fake model + web_domain_field.fake.model + +
    + + + + + + +
    +
    +
    + + + Fake Model action + web_domain_field.fake.model + list,form + + + +
    diff --git a/web_domain_field/tests/ir.model.access.csv b/web_domain_field/tests/ir.model.access.csv new file mode 100644 index 000000000000..84fd8ae39f6f --- /dev/null +++ b/web_domain_field/tests/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +full_access,Full Access,model_web_domain_field_fake_model,,1,1,1,1 diff --git a/web_domain_field/tests/models.py b/web_domain_field/tests/models.py new file mode 100644 index 000000000000..bc6fb5e983e7 --- /dev/null +++ b/web_domain_field/tests/models.py @@ -0,0 +1,22 @@ +# Copyright 2025 Simone Rubino - PyTech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class FakeModel(models.Model): + _name = "web_domain_field.fake.model" + _description = "Fake model for testing web_domain_field" + + partner_id_false_domain = fields.Char( + compute="_compute_partner_id_false_domain", + readonly=True, + store=False, + ) + partner_id = fields.Many2one( + comodel_name="res.partner", + ) + + def _compute_partner_id_false_domain(self): + for record in self: + record.partner_id_false_domain = False diff --git a/web_domain_field/tests/test_domain_field.py b/web_domain_field/tests/test_domain_field.py new file mode 100644 index 000000000000..a49407724ac4 --- /dev/null +++ b/web_domain_field/tests/test_domain_field.py @@ -0,0 +1,42 @@ +# Copyright 2025 Simone Rubino - PyTech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo_test_helper import FakeModelLoader + +from odoo import tests, tools +from odoo.modules.module import get_resource_path + + +@tests.tagged("post_install", "-at_install") +class TestDomainField(tests.HttpSavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + + from .models import FakeModel + + cls.loader.update_registry((FakeModel,)) + tools.convert_file( + cls.env.cr, + "web_domain_field", + get_resource_path("web_domain_field", "tests", "fake_model_views.xml"), + {}, + kind="test", + ) + tools.convert_file( + cls.env.cr, + "web_domain_field", + get_resource_path("web_domain_field", "tests", "ir.model.access.csv"), + {}, + kind="test", + ) + + @classmethod + def tearDownClass(cls): + cls.loader.restore_registry() + super().tearDownClass() + + def test_false_domain(self): + self.start_tour("/web", "web_domain_field.false_domain_tour", login="admin") diff --git a/web_domain_field/views/web_domain_field.xml b/web_domain_field/views/web_domain_field.xml index 7102c526b258..a28c2b327143 100644 --- a/web_domain_field/views/web_domain_field.xml +++ b/web_domain_field/views/web_domain_field.xml @@ -1,4 +1,8 @@ + + +