[IMP] web: ActionManager: load window actions without id

Actions can be loaded from the state of the url (e.g. when pressing
F5). For window actions, it was working properly if the action id
or a record id (i.e. for form views) was given. In other words,
states like 'model=res.partner&view_type=kanban' couldn't be
loaded.

This can be explained by the fact that without an action id, the
context and domain of the action couldn't be obtained.

This rev. solves this problem by storing the current action into
the sessionStorage, so that important information like context,
domain and name can be retrieved if this action has to be restored
(i.e. if the user refreshes the page).
This commit is contained in:
Aaron Bohy
2018-03-23 09:02:49 +01:00
parent ee0605f405
commit 2a6ff8f8e4
3 changed files with 75 additions and 0 deletions
@@ -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;
@@ -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);
@@ -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) {