From aa18aaa2925badcace4a3b88607b8f332e99d2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Wed, 14 Nov 2018 09:44:53 +0000 Subject: [PATCH] [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 --- .../static/src/js/chrome/abstract_action.js | 7 ++++++ .../js/chrome/action_manager_act_window.js | 6 +++-- .../src/js/views/form/form_controller.js | 11 +++++++- .../src/js/views/graph/graph_controller.js | 1 - .../static/src/js/views/graph/graph_model.js | 3 --- .../tests/chrome/action_manager_tests.js | 25 +++++++++++++++++++ .../base/static/src/js/res_config_settings.js | 9 +++++++ .../base/static/tests/base_settings_tests.js | 4 ++- 8 files changed, 58 insertions(+), 8 deletions(-) diff --git a/addons/web/static/src/js/chrome/abstract_action.js b/addons/web/static/src/js/chrome/abstract_action.js index 5b0f7e3aeca..c4755338bf0 100644 --- a/addons/web/static/src/js/chrome/abstract_action.js +++ b/addons/web/static/src/js/chrome/abstract_action.js @@ -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 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 d121ec929f0..0f6c88a1188 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 @@ -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; + }); }); } }); diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js index 7586dcc4bab..b7c8e8a6214 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -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); }, diff --git a/addons/web/static/src/js/views/graph/graph_controller.js b/addons/web/static/src/js/views/graph/graph_controller.js index 48f15de8902..4e998377fa7 100644 --- a/addons/web/static/src/js/views/graph/graph_controller.js +++ b/addons/web/static/src/js/views/graph/graph_controller.js @@ -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')); diff --git a/addons/web/static/src/js/views/graph/graph_model.js b/addons/web/static/src/js/views/graph/graph_model.js index adefe1e8953..26c1aec6545 100644 --- a/addons/web/static/src/js/views/graph/graph_model.js +++ b/addons/web/static/src/js/views/graph/graph_model.js @@ -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 diff --git a/addons/web/static/tests/chrome/action_manager_tests.js b/addons/web/static/tests/chrome/action_manager_tests.js index 9233229a984..7424d31f365 100644 --- a/addons/web/static/tests/chrome/action_manager_tests.js +++ b/addons/web/static/tests/chrome/action_manager_tests.js @@ -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); diff --git a/odoo/addons/base/static/src/js/res_config_settings.js b/odoo/addons/base/static/src/js/res_config_settings.js index 855b03452ae..9514d431141 100644 --- a/odoo/addons/base/static/src/js/res_config_settings.js +++ b/odoo/addons/base/static/src/js/res_config_settings.js @@ -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({ diff --git a/odoo/addons/base/static/tests/base_settings_tests.js b/odoo/addons/base/static/tests/base_settings_tests.js index e0ee5dd6380..eb9726b9fa6 100644 --- a/odoo/addons/base/static/tests/base_settings_tests.js +++ b/odoo/addons/base/static/tests/base_settings_tests.js @@ -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