diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 3687c622039..2e14ee56e8d 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -726,8 +726,13 @@ var FieldMany2One = AbstractField.extend({ readonly: !self.can_write, on_saved: function (record, changed) { if (changed) { - self._setValue(self.value.data, {forceChange: true}).then(function() { - self.trigger_up('reload', {db_id: self.value.id}); + const _setValue = self._setValue.bind(self, self.value.data, { + forceChange: true, + }); + self.trigger_up('reload', { + db_id: self.value.id, + onSuccess: _setValue, + onFailure: _setValue, }); } }, diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js index df1a03e0f42..7639d2dea99 100644 --- a/addons/web/static/src/js/views/basic/basic_controller.js +++ b/addons/web/static/src/js/views/basic/basic_controller.js @@ -705,21 +705,25 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { * re-render (reload the whole form by default) * @param {string[]} [ev.data.fieldNames] list of the record's fields to * reload + * @param {Function} [ev.data.onSuccess] callback executed after reload is resolved + * @param {Function} [ev.data.onFailure] callback executed when reload is rejected */ _onReload: function (ev) { ev.stopPropagation(); // prevent other controllers from handling this request var data = ev && ev.data || {}; var handle = data.db_id; + var prom; if (handle) { // reload the relational field given its db_id - this.model.reload(handle).then(this._confirmSave.bind(this, handle)); + prom = this.model.reload(handle).then(this._confirmSave.bind(this, handle)); } else { // no db_id given, so reload the main record - this.reload({ + prom = this.reload({ fieldNames: data.fieldNames, keepChanges: data.keepChanges || false, }); } + prom.then(ev.data.onSuccess).guardedCatch(ev.data.onFailure); }, /** * Resequence records in the given order. diff --git a/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js b/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js index a8743a4cddf..081bd4e3598 100644 --- a/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js +++ b/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js @@ -557,7 +557,7 @@ QUnit.module('fields', {}, function () { // save the modal and make sure an onchange is triggered await testUtils.dom.click($('.modal .modal-footer .btn-primary').first()); - assert.verifySteps(['read', 'get_formview_id', 'load_views', 'read', 'write', 'onchange', 'read']); + assert.verifySteps(['read', 'get_formview_id', 'load_views', 'read', 'write', 'read', 'onchange']); // save the main record, and check that no extra rpcs are done (record // is not dirty, only a related record was modified) diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index 141a98e9a80..32c868a9bb0 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -6074,6 +6074,48 @@ QUnit.module('Views', { list.destroy(); }); + QUnit.test('editable list: edit many2one from external link', async function (assert) { + assert.expect(2); + + const list = await createView({ + arch: ` + + + `, + archs: { + 'bar,false,form': '
', + }, + data: this.data, + mockRPC: function (route, args) { + if (args.method === 'get_formview_id') { + return Promise.resolve(false); + } + return this._super(route, args); + }, + model: 'foo', + View: ListView, + }); + + await testUtils.dom.click(list.$('thead .o_list_record_selector:first input')); + await testUtils.dom.click(list.$('.o_data_row:first .o_data_cell:eq(0)')); + await testUtils.dom.click(list.$('.o_external_button:first')); + + // Change the M2O value in the Form dialog + await testUtils.fields.editInput($('.modal input:first'), "OOF"); + await testUtils.dom.click($('.modal .btn-primary')); + + assert.strictEqual($('.modal .o_field_widget[name=m2o]').text(), "OOF", + "Value of the m2o should be updated in the confirmation dialog"); + + // Close the confirmation dialog + await testUtils.dom.click($('.modal .btn-primary')); + + assert.strictEqual(list.$('.o_data_cell:first').text(), "OOF", + "Value of the m2o should be updated in the list"); + + list.destroy(); + }); + QUnit.test('list grouped by date:month', async function (assert) { assert.expect(1);