diff --git a/addons/web/static/src/views/basic_relational_model.js b/addons/web/static/src/views/basic_relational_model.js index bb855ab51eb..28e233eda71 100644 --- a/addons/web/static/src/views/basic_relational_model.js +++ b/addons/web/static/src/views/basic_relational_model.js @@ -286,9 +286,11 @@ export class Record extends DataPoint { } get dirtyFields() { - return Object.keys(this.model.__bm__.localData[this.__bm_handle__]._changes).map( - (change) => this.activeFields[change] - ); + const changes = this.model.__bm__.localData[this.__bm_handle__]._changes; + if (!changes) { + return []; + } + return Object.keys(changes).map((change) => this.activeFields[change]); } get translatableFields() { 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 69e857c31a9..12bf7a5fe93 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -7844,6 +7844,42 @@ QUnit.module("Views", (hooks) => { ); }); + QUnit.test("can save without any dirty translatable fields", async function (assert) { + serverData.models.partner.fields.foo.translate = true; + + patchWithCleanup(localization, { + multiLang: true, + }); + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
`, + resId: 1, + mockRPC(route, args) { + assert.step(args.method); + }, + }); + + assert.verifySteps(["get_views", "read"]); + await clickEdit(target); + assert.containsOnce(target, ".o_form_editable"); + // o_field_translate is on the input and on the translate button + assert.containsN(target, "div[name='foo'] > .o_field_translate", 2); + await clickSave(target); + assert.containsNone( + target, + ".alert .o_field_translate", + "should not have a translation alert" + ); + assert.containsOnce(target, ".o_form_readonly"); + assert.verifySteps([]); + }); + QUnit.test("translation alerts are preserved on pager change", async function (assert) { serverData.models.partner.fields.foo.translate = true;