diff options
Diffstat (limited to 'addons/web/static/src/js')
| -rw-r--r-- | addons/web/static/src/js/apps.js | 4 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/abstract_action.js | 67 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/action_manager.js | 23 | ||||
| -rw-r--r-- | addons/web/static/src/js/report/client_action.js | 4 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/abstract_controller.js | 20 | ||||
| -rw-r--r-- | addons/web/static/src/js/widgets/change_password.js | 4 |
6 files changed, 91 insertions, 31 deletions
diff --git a/addons/web/static/src/js/apps.js b/addons/web/static/src/js/apps.js index fa513372269..c49e4741093 100644 --- a/addons/web/static/src/js/apps.js +++ b/addons/web/static/src/js/apps.js @@ -1,16 +1,16 @@ odoo.define('web.Apps', function (require) { "use strict"; +var AbstractAction = require('web.AbstractAction'); var core = require('web.core'); var framework = require('web.framework'); var session = require('web.session'); -var Widget = require('web.Widget'); var _t = core._t; var apps_client = null; -var Apps = Widget.extend({ +var Apps = AbstractAction.extend({ template: 'EmptyComponent', remote_action_tag: 'loempia.embed', failback_action_id: 'base.open_module_tree', diff --git a/addons/web/static/src/js/chrome/abstract_action.js b/addons/web/static/src/js/chrome/abstract_action.js new file mode 100644 index 00000000000..eb305b3a0d0 --- /dev/null +++ b/addons/web/static/src/js/chrome/abstract_action.js @@ -0,0 +1,67 @@ +odoo.define('web.AbstractAction', function (require) { +"use strict"; + +/** + * We define here the generic notion of Action (from the point of view of the + * web client). In short, an action is a widget which controls the main part + * of the screen (everything below the control panel). + * + * More precisely, the action manager is the component that coordinates a stack + * of actions. Whenever the user navigates in the interface, switches views, + * open different menus, the action manager creates/updates/destroys special + * widgets which are actions. These actions need to answer to a standardised + * API, which is the reason this AbstractAction class. + * + * In practice, most actions are view controllers (coming from a + * ir.action.act_window). However, some actions are 'client actions'. They + * also need to be an AbstractAction for a better cooperation with the action + * manager. + * + * @module web.AbstractAction + */ + +var Widget = require('web.Widget'); + +var AbstractAction = Widget.extend({ + + /** + * Called each time the action is attached into the DOM. + */ + on_attach_callback: function () {}, + /** + * Called each time the action is detached from the DOM. + */ + on_detach_callback: function () {}, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * In some situations, we need confirmation from the controller that the + * current state can be destroyed without prejudice to the user. For + * example, if the user has edited a form, maybe we should ask him if we + * can discard all his changes when we switch to another action. In that + * case, the action manager will call this method. If the returned + * deferred is succesfully resolved, then we can destroy the current action, + * otherwise, we need to stop. + * + * @returns {Deferred} resolved if the action can be removed, rejected otherwise + */ + canBeRemoved: function () { + return $.when(); + }, + /** + * Renders the buttons to append, in most cases, to the control panel (in + * the bottom left corner). When the action is rendered in a dialog, those + * buttons might be moved to the dialog's footer. + * + * @param {jQuery Node} $node + */ + renderButtons: function ($node) { + }, +}); + +return AbstractAction; + +}); diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js index 1651e5d72d9..e213b55189d 100644 --- a/addons/web/static/src/js/chrome/action_manager.js +++ b/addons/web/static/src/js/chrome/action_manager.js @@ -9,6 +9,7 @@ odoo.define('web.ActionManager', function (require) { * coordinated. */ +var AbstractAction = require('web.AbstractAction'); var Bus = require('web.Bus'); var concurrency = require('web.concurrency'); var Context = require('web.Context'); @@ -79,7 +80,7 @@ var ActionManager = Widget.extend({ on_attach_callback: function() { this.isInDOM = true; var currentController = this.getCurrentController(); - if (currentController && currentController.widget.on_attach_callback) { + if (currentController) { currentController.widget.on_attach_callback(); } }, @@ -89,7 +90,7 @@ var ActionManager = Widget.extend({ on_detach_callback: function() { this.isInDOM = false; var currentController = this.getCurrentController(); - if (currentController && currentController.widget.on_detach_callback) { + if (currentController) { currentController.widget.on_detach_callback(); } }, @@ -109,13 +110,8 @@ var ActionManager = Widget.extend({ */ clearUncommittedChanges: function () { var currentController = this.getCurrentController(); - // AAB: with AbstractAction, the second part of the condition won't be - // necessary anymore, as there will be such a function it its API - if (currentController && currentController.widget.discardChanges) { - return currentController.widget.discardChanges(undefined, { - // AAB: get rid of this option when on_hashchange mechanism is improved - readonlyIfRealDiscard: true, - }); + if (currentController) { + return currentController.widget.canBeRemoved(); } return $.when(); }, @@ -405,11 +401,7 @@ var ActionManager = Widget.extend({ in_DOM: true, callbacks: [{widget: dialog}], }); - // AAB: renderButtons will be a function of AbstractAction, so this - // test won't be necessary anymore - if (widget.renderButtons) { - widget.renderButtons(dialog.$footer); - } + widget.renderButtons(dialog.$footer); self.currentDialogController = controller; @@ -435,6 +427,9 @@ var ActionManager = Widget.extend({ console.error("Could not find client action " + action.tag, action); return $.Deferred().reject(); } + if (!(ClientAction.prototype instanceof AbstractAction)) { + console.warn('The client action ' + action.tag + ' should be an instance of AbstractAction!'); + } if (!(ClientAction.prototype instanceof Widget)) { // the client action might be a function, which is executed and // whose returned value might be another action to execute diff --git a/addons/web/static/src/js/report/client_action.js b/addons/web/static/src/js/report/client_action.js index 2fd2ccd44b3..7041913c286 100644 --- a/addons/web/static/src/js/report/client_action.js +++ b/addons/web/static/src/js/report/client_action.js @@ -1,11 +1,11 @@ odoo.define('report.client_action', function (require) { 'use strict'; +var AbstractAction = require('web.AbstractAction'); var config = require('web.config'); var core = require('web.core'); var ControlPanelMixin = require('web.ControlPanelMixin'); var session = require('web.session'); -var Widget = require('web.Widget'); var utils = require('report.utils'); var QWeb = core.qweb; @@ -17,7 +17,7 @@ var AUTHORIZED_MESSAGES = [ 'report:do_action', ]; -var ReportAction = Widget.extend(ControlPanelMixin, { +var ReportAction = AbstractAction.extend(ControlPanelMixin, { template: 'report.client_action', diff --git a/addons/web/static/src/js/views/abstract_controller.js b/addons/web/static/src/js/views/abstract_controller.js index f1356f72a81..995a5102c37 100644 --- a/addons/web/static/src/js/views/abstract_controller.js +++ b/addons/web/static/src/js/views/abstract_controller.js @@ -14,11 +14,11 @@ odoo.define('web.AbstractController', function (require) { var ControlPanelMixin = require('web.ControlPanelMixin'); var core = require('web.core'); -var Widget = require('web.Widget'); +var AbstractAction = require('web.AbstractAction'); var QWeb = core.qweb; -var AbstractController = Widget.extend(ControlPanelMixin, { +var AbstractController = AbstractAction.extend(ControlPanelMixin, { custom_events: { open_record: '_onOpenRecord', switch_view: '_onSwitchView', @@ -108,6 +108,13 @@ var AbstractController = Widget.extend(ControlPanelMixin, { //-------------------------------------------------------------------------- /** + * @override + */ + canBeRemoved: function () { + // AAB: get rid of this option when on_hashchange mechanism is improved + return this.discardChanges(undefined, {readonlyIfRealDiscard: true}); + }, + /** * Discards the changes made on the record associated to the given ID, or * all changes made by the current controller if no recordID is given. For * example, when the user opens the 'home' screen, the action manager calls @@ -168,15 +175,6 @@ var AbstractController = Widget.extend(ControlPanelMixin, { return this.update(params || {}); }, /** - * Renders the buttons to append, in most cases, to the control panel (in - * the bottom left corner). When the view is rendered in a dialog, those - * buttons might be moved to the dialog's footer. - * - * @param {jQuery Node} $node - */ - renderButtons: function ($node) { - }, - /** * For views that require a pager, this method will be called to allow the * controller to instantiate and render a pager. Note that in theory, the * controller can actually render whatever he wants in the pager zone. If diff --git a/addons/web/static/src/js/widgets/change_password.js b/addons/web/static/src/js/widgets/change_password.js index b71ae4aaf4b..c05fa30408b 100644 --- a/addons/web/static/src/js/widgets/change_password.js +++ b/addons/web/static/src/js/widgets/change_password.js @@ -6,14 +6,14 @@ odoo.define('web.ChangePassword', function (require) { * allows the user to change his password. */ +var AbstractAction = require('web.AbstractAction'); var core = require('web.core'); var Dialog = require('web.Dialog'); -var Widget = require('web.Widget'); var web_client = require('web.web_client'); var _t = core._t; -var ChangePassword = Widget.extend({ +var ChangePassword = AbstractAction.extend({ template: "ChangePassword", /** |
