diff --git a/addons/survey/static/src/question_page/question_page_one2many_field.js b/addons/survey/static/src/question_page/question_page_one2many_field.js index 67671a1313b..22a96f0ce3c 100644 --- a/addons/survey/static/src/question_page/question_page_one2many_field.js +++ b/addons/survey/static/src/question_page/question_page_one2many_field.js @@ -86,6 +86,7 @@ class QuestionPageOneToManyField extends X2ManyField { } openRecord(params); }; + this.canOpenRecord = true; } /** diff --git a/addons/web/static/src/views/fields/x2many/x2many_field.js b/addons/web/static/src/views/fields/x2many/x2many_field.js index 166070a30df..a282337a18c 100644 --- a/addons/web/static/src/views/fields/x2many/x2many_field.js +++ b/addons/web/static/src/views/fields/x2many/x2many_field.js @@ -91,6 +91,9 @@ export class X2ManyField extends Component { }, }); }; + this.canOpenRecord = + this.viewMode === "list" ? !(archInfo.editable || this.props.editable) : true; + const selectCreate = useSelectCreate({ resModel: this.props.value.resModel, activeActions: this.activeActions, @@ -237,7 +240,9 @@ export class X2ManyField extends Component { } async openRecord(record) { - return this._openRecord({ record, mode: this.props.readonly ? "readonly" : "edit" }); + if (this.canOpenRecord) { + return this._openRecord({ record, mode: this.props.readonly ? "readonly" : "edit" }); + } } } X2ManyField.components = { Pager, KanbanRenderer, ListRenderer, ViewButton }; diff --git a/addons/web/static/tests/views/fields/one2many_field_tests.js b/addons/web/static/tests/views/fields/one2many_field_tests.js index 3da9cb6d49b..80246fa777a 100644 --- a/addons/web/static/tests/views/fields/one2many_field_tests.js +++ b/addons/web/static/tests/views/fields/one2many_field_tests.js @@ -2861,6 +2861,31 @@ QUnit.module("Fields", (hooks) => { assert.containsNone(target, ".o_field_x2many_list_row_add"); }); + QUnit.test( + "one2many list: cannot open record in editable list and form in readonly mode", + async function (assert) { + serverData.models.partner.records[0].p = [2]; + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
`, + resId: 1, + }); + + assert.containsOnce(target, ".o_data_cell[name='display_name']"); + await click(target, ".o_data_cell[name='display_name']"); + assert.containsNone(target, ".modal-dialog"); + } + ); + QUnit.test("one2many list: conditional create/delete actions", async function (assert) { serverData.models.partner.records[0].p = [2, 4]; await makeView({ diff --git a/addons/web/static/tests/views/form/form_view_tests.js b/addons/web/static/tests/views/form/form_view_tests.js index 528764a3977..4fb480c09f8 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -670,7 +670,7 @@ QUnit.module("Views", (hooks) => { arch: `