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