summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Kühn <aku@odoo.com>2018-07-16 11:03:47 +0200
committerAlexandre Kühn <aku@odoo.com>2018-07-16 14:08:40 +0200
commit3210f108272be89f1a7b01f4e1816b7f04ae0a3b (patch)
tree41ecf1123079212bf15149dd419f51dd628ed477
parent0b7851604752b9c76028326ad3024b745857cd7b (diff)
[IMP] web: provide infos for close action
With this commit, when we perform a close action, we can provide infos to the `on_close` handler, so that it can handle different cases that caused the close action.
-rw-r--r--addons/web/static/src/js/chrome/action_manager.js49
-rw-r--r--addons/web/static/src/js/core/dialog.js14
-rw-r--r--addons/web/static/tests/chrome/action_manager_tests.js24
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);