diff options
| -rw-r--r-- | addons/web/static/src/js/chrome/action_manager.js | 49 | ||||
| -rw-r--r-- | addons/web/static/src/js/core/dialog.js | 14 | ||||
| -rw-r--r-- | addons/web/static/tests/chrome/action_manager_tests.js | 24 |
3 files changed, 70 insertions, 17 deletions
diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js index 2eb698b5424..5d6764381ba 100644 --- a/addons/web/static/src/js/chrome/action_manager.js +++ b/addons/web/static/src/js/chrome/action_manager.js @@ -279,17 +279,21 @@ var ActionManager = Widget.extend({ * Closes the current dialog, if any. Because we listen to the 'closed' * event triggered by the dialog when it is closed, this also destroys the * embedded controller and removes the reference to the corresponding action. - * This also executes the 'on_close' handler in some cases. + * This also executes the 'on_close' handler in some cases, and may also + * provide infos for closing this dialog. * * @private - * @param {boolean} [silent=false] if true, the 'on_close' handler won't be - * called ; this is in general the case when the current dialog is closed - * because another action is opened, so we don't want the former action - * to execute its handler as it won't be displayed anyway - */ - _closeDialog: function (silent) { + * @param {Object} options + * @param {Object} [options.infos] some infos related to the closing the + * dialog. + * @param {boolean} [options.silent=false] if true, the 'on_close' handler + * won't be called ; this is in general the case when the current dialog + * is closed because another action is opened, so we don't want the former + * action to execute its handler as it won't be displayed anyway + */ + _closeDialog: function (options) { if (this.currentDialogController) { - this.currentDialogController.dialog.destroy(silent); + this.currentDialogController.dialog.destroy(options); } }, /** @@ -340,7 +344,7 @@ var ActionManager = Widget.extend({ }) .then(function (controller) { if (self.currentDialogController) { - self._closeDialog(true); + self._closeDialog({ silent: true }); } // store the optional 'on_reverse_breadcrumb' handler @@ -394,7 +398,7 @@ var ActionManager = Widget.extend({ var prevDialogOnClose; if (self.currentDialogController) { prevDialogOnClose = self.currentDialogController.onClose; - self._closeDialog(true); + self._closeDialog({ silent: true }); } controller.onClose = prevDialogOnClose || options.on_close; @@ -404,11 +408,19 @@ var ActionManager = Widget.extend({ title: action.name, size: action.context.dialog_size, })); - dialog.on('closed', self, function (silent) { + /** + * @param {Object} [options] + * @param {Object} [options.infos] if provided and `silent` is + * unset, the `on_close` handler will pass this information, + * which gives some context for closing this dialog. + * @param {boolean} [options.silent=false] if set, do not call the + * `on_close` handler. + */ + dialog.on('closed', self, function (options) { self._removeAction(action.jsID); self.currentDialogController = null; - if (silent !== true) { - controller.onClose(); + if (options && options.silent !== true) { + controller.onClose(options.infos); } }); controller.dialog = dialog; @@ -486,17 +498,24 @@ var ActionManager = Widget.extend({ * Executes actions of type 'ir.actions.act_window_close', i.e. closes the * last opened dialog. * + * The action may also specify an effect to display right after the close + * action (e.g. rainbow man), or provide a reason for the close action. + * This is useful for decision making for the `on_close` handler. + * * @private * @param {Object} action + * @param {Object} [action.effect] effect to show up, e.g. rainbow man. + * @param {Object} [action.infos] infos on performing the close action. + * Useful for providing some context for the `on_close` handler. * @returns {Deferred} resolved immediately */ _executeCloseAction: function (action, options) { var result; if (!this.currentDialogController) { - result = options.on_close(); + result = options.on_close(action.infos); } - this._closeDialog(); + this._closeDialog({ infos: action.infos }); // display some effect (like rainbowman) on appropriate actions if (action.effect) { diff --git a/addons/web/static/src/js/core/dialog.js b/addons/web/static/src/js/core/dialog.js index 075c7359a55..847845ae17e 100644 --- a/addons/web/static/src/js/core/dialog.js +++ b/addons/web/static/src/js/core/dialog.js @@ -189,12 +189,22 @@ var Dialog = Widget.extend({ this.destroy(); }, - destroy: function (arg) { + /** + * Close and destroy the dialog. + * + * @param {Object} [options] + * @param {Object} [options.infos] if provided and `silent` is unset, the + * `on_close` handler will pass this information related to closing this + * information. + * @param {boolean} [options.silent=false] if set, do not call the + * `on_close` handler. + */ + destroy: function (options) { // Need to trigger before real destroy but if 'closed' handler destroys // the widget again, we want to avoid infinite recursion if (!this.__closed) { this.__closed = true; - this.trigger("closed", arg); + this.trigger('closed', options); } if (this.isDestroyed()) { diff --git a/addons/web/static/tests/chrome/action_manager_tests.js b/addons/web/static/tests/chrome/action_manager_tests.js index 7ad3007c87a..2f003c07577 100644 --- a/addons/web/static/tests/chrome/action_manager_tests.js +++ b/addons/web/static/tests/chrome/action_manager_tests.js @@ -3294,6 +3294,30 @@ QUnit.module('ActionManager', { }); }); + QUnit.test('close action with provided infos', function (assert) { + assert.expect(1); + + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + }); + + var options = { + on_close: function (infos) { + assert.strictEqual(infos, 'just for testing', + "should have the correct close infos"); + } + }; + + actionManager.doAction({ + type: 'ir.actions.act_window_close', + infos: 'just for testing', + }, options); + + actionManager.destroy(); + }); + QUnit.test('properly drop client actions after new action is initiated', function (assert) { assert.expect(1); |
