[FIX] web: restore formview mode when coming back (breadcrumbs)

Before this commit, when the user is in a form view (edit mode) and
click on a stat button, a new action is added to the action stack.  When
the user then comes back to the form view by clicking on the breadcrumb,
it is supposed to be in readonly mode.  Before this commit, this was not
the case.

This bug comes from the action manager refactoring, which removed the
view manager. With this commit, we add a new action lifecycle method
which is called when the action is restored.

Note that this commit implicitely changes the semantic of actions with
'target=inline'. As far as I can tell, this only applies to the settings
form view, which can easily be fixed by overriding the restore hook.

closes odoo/odoo#28663
This commit is contained in:
Géry Debongnie
2018-11-14 11:19:40 +00:00
parent 79d29c51df
commit aa18aaa292
8 changed files with 58 additions and 8 deletions
@@ -32,6 +32,13 @@ var AbstractAction = Widget.extend({
* Called each time the action is detached from the DOM.
*/
on_detach_callback: function () {},
/**
* Called by the action manager when action is restored (typically, when the
* user clicks on the action in the breadcrumb)
*
* @returns {Deferred|undefined}
*/
willRestore: function () {},
//--------------------------------------------------------------------------
// Public
@@ -646,8 +646,10 @@ ActionManager.include({
});
} else {
viewOptions = _.extend(viewOptions || {}, action.env);
return controller.widget.reload(viewOptions).then(function () {
return controller;
return $.when(controller.widget.willRestore()).then(function () {
return controller.widget.reload(viewOptions).then(function () {
return controller;
});
});
}
});
@@ -40,6 +40,15 @@ var FormController = BasicController.extend({
this.hasSidebar = params.hasSidebar;
this.toolbarActions = params.toolbarActions || {};
},
/**
* Force mode back to readonly. Whenever we leave a form view, it is saved,
* and should no longer be in edit mode.
*
* @override
*/
willRestore: function () {
this.mode = 'readonly';
},
//--------------------------------------------------------------------------
// Public
@@ -242,7 +251,7 @@ var FormController = BasicController.extend({
* @override
*/
update: function (params, options) {
params = _.extend({viewType: 'form'}, params);
params = _.extend({viewType: 'form', mode: this.mode}, params);
return this._super(params, options);
},
@@ -179,7 +179,6 @@ var GraphController = AbstractController.extend(GroupByMenuInterfaceMixin,{
*/
_onButtonClick: function (event) {
var $target = $(event.target);
var parent;
var field;
if ($target.hasClass('o_graph_button')) {
this._setMode($target.data('mode'));
@@ -6,11 +6,8 @@ odoo.define('web.GraphModel', function (require) {
* server. It basically just do a read_group and format/normalize data.
*/
var core = require('web.core');
var AbstractModel = require('web.AbstractModel');
var _t = core._t;
return AbstractModel.extend({
/**
* @override
@@ -2878,6 +2878,31 @@ QUnit.module('ActionManager', {
actionManager.destroy();
});
QUnit.test('form views are restored in readonly when coming back in breadcrumbs', function (assert) {
assert.expect(2);
var actionManager = createActionManager({
actions: this.actions,
archs: this.archs,
data: this.data,
});
actionManager.doAction(3);
// open a record in form view
actionManager.$('.o_list_view .o_data_row:first').click();
// switch to edit mode
$('.o_control_panel .o_form_button_edit').click();
assert.ok(actionManager.$('.o_form_view').hasClass('o_form_editable'));
// do some other action
actionManager.doAction(4);
// go back to form view
$('.o_control_panel .breadcrumb a').last().click();
assert.ok(actionManager.$('.o_form_view').hasClass('o_form_readonly'));
actionManager.destroy();
});
QUnit.test('honor group_by specified in actions context', function (assert) {
assert.expect(5);
@@ -354,6 +354,15 @@ var BaseSettingController = FormController.extend({
this.disableAutofocus = true;
this.renderer.activeSettingTab = this.initialState.context.module;
},
/**
* Settings view should always be in edit mode, so we have to override
* default behaviour
*
* @override
*/
willRestore: function () {
this.mode = 'edit';
},
});
var BaseSettingsModel = BasicModel.extend({
@@ -87,7 +87,7 @@ QUnit.module('base_settings_tests', {
});
QUnit.test('settings views does not read existing id when coming back in breadcrumbs', function (assert) {
assert.expect(7);
assert.expect(8);
var actions = [{
id: 1,
@@ -127,6 +127,8 @@ QUnit.module('base_settings_tests', {
actionManager.doAction(1);
actionManager.$('button[name="4"]').click();
$('.o_control_panel .breadcrumb-item a').click();
assert.ok(actionManager.$('.o_form_view').hasClass('o_form_editable'),
'settings view should still be in edit mode');
assert.verifySteps([
'load_views', // initial setting action
'default_get', // this is a setting view => create new record