diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js index 7b279d44bcd..00a4631d3f7 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -14,6 +14,7 @@ var FormController = BasicController.extend({ custom_events: _.extend({}, BasicController.prototype.custom_events, { bounce_edit: '_onBounceEdit', button_clicked: '_onButtonClicked', + do_action: '_onDoAction', freeze_order: '_onFreezeOrder', open_one2many_record: '_onOpenOne2ManyRecord', open_record: '_onOpenRecord', @@ -434,6 +435,26 @@ var FormController = BasicController.extend({ _onDiscard: function () { this._discardChanges(); }, + /** + * Destroy subdialog widgets after an action is finished. + * + * @param {OdooEvent} event + * @private + */ + _onDoAction: function (event) { + var self=this; + // A priori, different widgets could write on the "on_success" key. + // Below we ensure that all the actions required by those widgets + // are executed in a suitable order before every cycle of destruction. + var callback = event.data.on_success || function () {}; + event.data.on_success = function () { + callback(); + function isDialog (widget) { + return (widget instanceof Dialog); + } + _.invoke(self.getChildren().filter(isDialog), 'destroy'); + }; + }, /** * Called when the user clicks on 'Duplicate Record' in the sidebar * diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 5b0dd69ddd4..bd1e5d0ffea 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -6585,6 +6585,102 @@ QUnit.module('Views', { form.destroy(); testUtils.unpatch(BasicModel); }); + + QUnit.test('a popup window should automatically close after a do_action event', function (assert) { + + // Having clicked on a one2many in a form view and clicked on a many2one + // field in the resulting popup window that popup window should automatically close. + + assert.expect(2); + + this.data.partner.records[0].product_ids = [37]; + this.data.product.records[0].partner_type_id = 12; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '' + + '' + + '' + + '', + res_id: 1, + mockRPC: function (route, args) { + if (args.method === 'get_formview_action' && args.model === 'partner_type') { + return $.when(); + } + return this._super(route, args); + }, + intercepts: { + do_action: function (event) { + event.data.on_success(); + } + }, + }); + // Open one2many + form.$('.o_data_row').click(); + assert.strictEqual($('.modal-content').length, 1, "a popup window should have opened"); + // Click on many2one and trigger do_action + $('.modal-content a[name="partner_type_id"]').click(); + assert.strictEqual($('.modal-content').length, 0, "the popup window should have closed"); + + form.destroy(); + }); + + QUnit.test('all popup windows should automatically close after a do_action event', function (assert) { + + // Having clicked successively on two different one2many in form views + // and clicked on a many2one in the last popup window all popup + // windows should automatically close. + + assert.expect(2); + + this.data.partner.records[0].p = [2]; + this.data.partner.records[1].product_ids = [37]; + this.data.product.records[0].partner_type_id = 12; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '' + + '' + + '
', + archs: { + 'partner,false,form': '
' + + '' + + '' + + '', + }, + res_id: 1, + mockRPC: function (route, args) { + if (args.method === 'get_formview_action' && args.model === 'partner_type') { + return $.when(); + } + return this._super(route, args); + }, + intercepts: { + do_action: function (event) { + event.data.on_success(); + } + }, + }); + // Open two one2manys + form.$('.o_data_row').click(); + $('.modal-content .o_data_row').click(); + assert.strictEqual($('.modal-content').length, 2, "Two popup windows should have opened."); + // Click on many2one and trigger do_action + $('.modal-content a[name="partner_type_id"]').click(); + assert.strictEqual($('.modal-content').length, 0, "All popup windows should have closed."); + + form.destroy(); + }); + + }); });