diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js index c4d3f591545..bed9673d44c 100644 --- a/addons/web/static/src/js/chrome/action_manager.js +++ b/addons/web/static/src/js/chrome/action_manager.js @@ -358,6 +358,10 @@ var ActionManager = Widget.extend({ // toggle the fullscreen mode for actions in target='fullscreen' self._toggleFullscreen(); + // store the action into the sessionStorage so that it can be + // fully restored on F5 + self.call('session_storage', 'setItem', 'current_action', action._originalAction); + return action; }) .fail(function () { @@ -763,6 +767,8 @@ var ActionManager = Widget.extend({ * @param {Object} options see @doAction options */ _preprocessAction: function (action, options) { + action._originalAction = JSON.stringify(action); + action.jsID = _.uniqueId('action_'); action.pushState = options.pushState; diff --git a/addons/web/static/src/js/chrome/action_manager_act_window.js b/addons/web/static/src/js/chrome/action_manager_act_window.js index 4e636de6355..be6ac5e2230 100644 --- a/addons/web/static/src/js/chrome/action_manager_act_window.js +++ b/addons/web/static/src/js/chrome/action_manager_act_window.js @@ -91,6 +91,15 @@ ActionManager.include({ type: 'ir.actions.act_window', views: [[state.view_id || false, 'form']], }; + } else if (state.model && state.view_type) { + // this is a window action on a multi-record view, so restore it + // from the session storage + var storedAction = this.call('session_storage', 'getItem', 'current_action'); + var lastAction = JSON.parse(storedAction || '{}'); + if (lastAction.res_model === state.model) { + action = lastAction; + options.viewType = state.view_type; + } } if (action) { return this.doAction(action, options); diff --git a/addons/web/static/tests/chrome/action_manager_tests.js b/addons/web/static/tests/chrome/action_manager_tests.js index c805da4e67c..9d15e729094 100644 --- a/addons/web/static/tests/chrome/action_manager_tests.js +++ b/addons/web/static/tests/chrome/action_manager_tests.js @@ -4,9 +4,11 @@ odoo.define('web.action_manager_tests', function (require) { var ReportClientAction = require('report.client_action'); var AbstractAction = require('web.AbstractAction'); +var AbstractStorageService = require('web.AbstractStorageService'); var ControlPanelMixin = require('web.ControlPanelMixin'); var core = require('web.core'); var ListController = require('web.ListController'); +var RamStorage = require('web.RamStorage'); var ReportService = require('web.ReportService'); var testUtils = require('web.test_utils'); var Widget = require('web.Widget'); @@ -1030,6 +1032,64 @@ QUnit.module('ActionManager', { delete core.action_registry.map.ClientAction; }); + QUnit.test('load a window action without id (in a multi-record view)', function (assert) { + assert.expect(14); + + var RamStorageService = AbstractStorageService.extend({ + name: 'session_storage', + storage: new RamStorage(), + }); + + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + services: [RamStorageService], + mockRPC: function (route, args) { + assert.step(args.method || route); + return this._super.apply(this, arguments); + }, + }); + + testUtils.intercept(actionManager, 'call_service', function (ev) { + if (ev.data.service === 'session_storage') { + assert.step(ev.data.method); + } + }, true); + + actionManager.doAction(4); + + assert.strictEqual(actionManager.$('.o_kanban_view').length, 1, + "should display a kanban view"); + assert.strictEqual($('.o_control_panel .breadcrumb li').text(), 'Partners Action 4', + "breadcrumbs should display the display_name of the action"); + + actionManager.loadState({ + model: 'partner', + view_type: 'list', + }); + + assert.strictEqual($('.o_control_panel .breadcrumb li').text(), 'Partners Action 4', + "should still be in the same action"); + assert.strictEqual(actionManager.$('.o_kanban_view').length, 0, + "should no longer display a kanban view"); + assert.strictEqual(actionManager.$('.o_list_view').length, 1, + "should display a list view"); + + assert.verifySteps([ + '/web/action/load', // action 3 + 'load_views', // action 3 + '/web/dataset/search_read', // action 3 + 'setItem', // action 3 + 'getItem', // loadState + 'load_views', // loaded action + '/web/dataset/search_read', // loaded action + 'setItem', // loaded action + ]); + + actionManager.destroy(); + }); + QUnit.module('Concurrency management'); QUnit.test('drop previous actions if possible', function (assert) {