diff options
| author | Aaron Bohy <aab@odoo.com> | 2015-10-12 16:29:01 +0200 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2015-10-13 11:26:22 +0200 |
| commit | e82deb5ae17d38799f5bb1592fab9323d02b2460 (patch) | |
| tree | 1e049a57087f9ad8a8f47c4f73c0a751a65e1f38 /addons/web/static/src/js | |
| parent | 1cf83427dacf343fd91d5f1fecf35189913e0265 (diff) | |
[FIX] web: action_manager: restore internal state on rejected action
When an error occured while executing an action (e.g. access rights), the
action manager's state was inconsistent as inner_action, inner_widget and
action_stack were all updated before trying to execute the action. Then, if the
user tried to open another action, the screen was split into two because the
reference of the previous action was lost, and thus it couldn't be detached.
We now restore inner_action, inner_widget and action_stack to their previous
state in the case of a rejected deferred.
A better fix would be to update all three variables once the deferred is
resolved, but it would require a refactoring of the way the action manager
and the view manager communicate to perform the do_push_state and to compute
the breadcrumbs. Indeed, those operations directly rely on the internal state
of the action manager, and they are performed before the callbacks in
push_state are called. Such a refactoring should probably not be done in
stable.
Partly fixes #8886.
Diffstat (limited to 'addons/web/static/src/js')
| -rw-r--r-- | addons/web/static/src/js/action_manager.js | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/addons/web/static/src/js/action_manager.js b/addons/web/static/src/js/action_manager.js index b2dfba2a395..54c7513295a 100644 --- a/addons/web/static/src/js/action_manager.js +++ b/addons/web/static/src/js/action_manager.js @@ -252,14 +252,13 @@ var ActionManager = Widget.extend({ */ push_action: function(widget, action_descr, options) { var self = this; - var to_destroy; var old_widget = this.inner_widget; var old_action = this.inner_action; + var old_action_stack = this.action_stack; options = options || {}; // Empty action_stack if requested if (options.clear_breadcrumbs) { - to_destroy = this.action_stack; this.action_stack = []; } @@ -278,7 +277,8 @@ var ActionManager = Widget.extend({ old_action.set_on_reverse_breadcrumb(options.on_reverse_breadcrumb); } - // Update action_stack + // Update action_stack (must be done before appendTo to properly + // compute the breadcrumbs and to perform do_push_state) this.action_stack.push(new_action); this.inner_action = new_action; this.inner_widget = widget; @@ -311,8 +311,14 @@ var ActionManager = Widget.extend({ old_widget.do_hide(); } if (options.clear_breadcrumbs) { - self.clear_action_stack(to_destroy); + self.clear_action_stack(old_action_stack); } + }).fail(function () { + // Destroy failed action and restore internal state + new_action.destroy(); + self.action_stack = old_action_stack; + self.inner_action = old_action; + self.inner_widget = old_widget; }); }, get_breadcrumbs: function () { |
