diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index 8fab67c638a..5517dcd4c1d 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -252,6 +252,7 @@ export class MockServer { } const editableView = editable && this._editableNode(doc, modelName); const onchangeAbleView = this._onchangeAbleView(doc); + const modifiersFromModel = this._modifiersFromModel(doc); const inTreeView = ["tree", "list"].includes(doc.tagName); const inFormView = doc.tagName === "form"; // mock _postprocess_access_rights @@ -286,7 +287,8 @@ export class MockServer { } const defaultValues = {}; const stateExceptions = {}; // what is this ? - ((editableView && modifiersNames) || ["invisible"]).forEach((attr) => { + + modifiersFromModel.forEach((attr) => { stateExceptions[attr] = []; defaultValues[attr] = !!field[attr]; }); @@ -496,6 +498,14 @@ export class MockServer { } } + _modifiersFromModel(node) { + const modifiersNames = ['invisible']; + if (['kanban', 'tree', 'form'].includes(node.tagName)) { + modifiersNames.push(...['readonly', 'required']); + } + return modifiersNames; + } + /** * Converts an Object representing a record to actual return Object of the * python `onchange` method. diff --git a/addons/web/static/tests/views/fields/color_field_tests.js b/addons/web/static/tests/views/fields/color_field_tests.js index f71c5572e94..a1576b7a741 100644 --- a/addons/web/static/tests/views/fields/color_field_tests.js +++ b/addons/web/static/tests/views/fields/color_field_tests.js @@ -119,6 +119,26 @@ QUnit.module("Fields", (hooks) => { ); }); + QUnit.test("color field read-only in model definition, in non-editable list", async function (assert) { + serverData.models.partner.fields.hex_color.readonly = true; + await makeView({ + type: "list", + serverData, + resModel: "partner", + arch: ` + + + `, + }); + + assert.containsN( + target, + '.o_field_color input:disabled', + 2, + "the field should not be editable" + ); + }); + QUnit.test("color field change via another field's onchange", async (assert) => { serverData.models.partner.onchanges = { foo: (rec) => { diff --git a/odoo/addons/base/models/ir_ui_view.py b/odoo/addons/base/models/ir_ui_view.py index 5c26c00d457..f3fd90e8738 100644 --- a/odoo/addons/base/models/ir_ui_view.py +++ b/odoo/addons/base/models/ir_ui_view.py @@ -59,10 +59,9 @@ def att_names(name): yield f"t-attf-{name}" -def transfer_field_to_modifiers(field, modifiers, view_editable=True): +def transfer_field_to_modifiers(field, modifiers, attributes): default_values = {} state_exceptions = {} - attributes = ('invisible', 'readonly', 'required') if view_editable else ('invisible',) for attr in attributes: state_exceptions[attr] = [] default_values[attr] = bool(field.get(attr)) @@ -1155,6 +1154,7 @@ actual arch. root_info = { 'view_type': root.tag, 'view_editable': editable and self._editable_node(root, name_manager), + 'view_modifiers_from_model': self._modifiers_from_model(root), 'mobile': options.get('mobile'), } @@ -1301,7 +1301,7 @@ actual arch. field_info = name_manager.field_info.get(node.get('name')) if field_info: - transfer_field_to_modifiers(field_info, node_info['modifiers'], node_info['view_editable']) + transfer_field_to_modifiers(field_info, node_info['modifiers'], node_info['view_modifiers_from_model']) def _postprocess_tag_form(self, node, name_manager, node_info): result = name_manager.model.view_header_get(False, node.tag) @@ -1382,6 +1382,12 @@ actual arch. def _onchange_able_view_kanban(self, node): return True + def _modifiers_from_model(self, node): + modifier_names = ['invisible'] + if node.tag in ('kanban', 'tree', 'form'): + modifier_names += ['readonly', 'required'] + return modifier_names + #------------------------------------------------------------------- # view validation #------------------------------------------------------------------- diff --git a/odoo/addons/base/tests/test_views.py b/odoo/addons/base/tests/test_views.py index 9d97ea71889..a3e6952404d 100644 --- a/odoo/addons/base/tests/test_views.py +++ b/odoo/addons/base/tests/test_views.py @@ -1738,7 +1738,7 @@ class TestViews(ViewCase): def _test_modifiers(what, expected): modifiers = {} if isinstance(what, dict): - transfer_field_to_modifiers(what, modifiers) + transfer_field_to_modifiers(what, modifiers, ['invisible', 'readonly', 'required']) else: node = etree.fromstring(what) if isinstance(what, str) else what transfer_node_to_modifiers(node, modifiers)