From 38dc5c18b4d407982351bb37b1c0a06d6dc20b5f Mon Sep 17 00:00:00 2001 From: Mathieu Duckerts-Antoine Date: Thu, 6 Dec 2018 12:39:43 +0000 Subject: [PATCH] [REF] board: adapt code to search refactoring This rev. adapts the code of the 'Add to Dashboard' entry of the Favotires menu, according to the large SearchView refactoring. It also does some tweaks for the dashboard app due to the move of the ControlPanel from the ActionManager to the controllers. Part of task 1893568 --- .../board/static/src/js/add_to_board_menu.js | 205 ++++++++++++++++++ addons/board/static/src/js/board_view.js | 37 +--- addons/board/static/src/js/favorite_menu.js | 136 ------------ addons/board/static/src/scss/dashboard.scss | 2 +- addons/board/static/src/xml/board.xml | 10 + addons/board/static/tests/dashboard_tests.js | 142 +++++------- addons/board/views/board_templates.xml | 2 +- 7 files changed, 283 insertions(+), 251 deletions(-) create mode 100644 addons/board/static/src/js/add_to_board_menu.js delete mode 100644 addons/board/static/src/js/favorite_menu.js diff --git a/addons/board/static/src/js/add_to_board_menu.js b/addons/board/static/src/js/add_to_board_menu.js new file mode 100644 index 00000000000..fb6b469d5ab --- /dev/null +++ b/addons/board/static/src/js/add_to_board_menu.js @@ -0,0 +1,205 @@ +odoo.define('board.AddToBoardMenu', function (require) { +"use strict"; + +var ActionManager = require('web.ActionManager'); +var Context = require('web.Context'); +var core = require('web.core'); +var Domain = require('web.Domain'); +var favorites_submenus_registry = require('web.favorites_submenus_registry'); +var pyUtils = require('web.py_utils'); +var Widget = require('web.Widget'); + +var _t = core._t; +var QWeb = core.qweb; + +var AddToBoardMenu = Widget.extend({ + events: _.extend({}, Widget.prototype.events, { + 'click .o_add_to_board.o_menu_header': '_onMenuHeaderClick', + 'click .o_add_to_board_confirm_button': '_onAddToBoardConfirmButtonClick', + 'click .o_add_to_board_input': '_onAddToBoardInputClick', + 'keyup .o_add_to_board_input': '_onKeyUp', + }), + /** + * @override + * @param {Object} params + * @param {Object} params.action an ir.actions description + */ + init: function (parent, params) { + this._super(parent); + this.action = params.action; + this.isOpen = false; + }, + /** + * @override + */ + start: function () { + if (this.action.id && this.action.type === 'ir.actions.act_window') { + this._render(); + } + return this._super.apply(this, arguments); + }, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * Closes the menu and render it. + * + */ + closeMenu: function () { + this.isOpen = false; + this._render(); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * This is the main function for actually saving the dashboard. This method + * is supposed to call the route /board/add_to_dashboard with proper + * information. + * + * @private + * @returns {Deferred} + */ + _addToBoard: function () { + var self = this; + var searchQuery; + // TO DO: for now the domains in query are evaluated. + // This should be changed I think. + this.trigger_up('get_search_query', { + callback: function (query) { + searchQuery = query; + } + }); + // TO DO: replace direct reference to action manager, controller, and currentAction in code below + + // AAB: trigger_up an event that will be intercepted by the controller, + // as soon as the controller is the parent of the control panel + var actionManager = this.findAncestor(function (ancestor) { + return ancestor instanceof ActionManager; + }); + var controller = actionManager.getCurrentController(); + + var context = new Context(this.action.context); + context.add(searchQuery.context); + context.add({ + group_by: pyUtils.eval('groupbys', searchQuery.groupBys || []) + }); + + this.trigger_up('get_controller_query_params', { + callback: function (controllerContext) { + context.add(controllerContext); + } + }); + + var domain = new Domain(this.action.domain || []); + domain = Domain.prototype.normalizeArray(domain.toArray().concat(searchQuery.domain)); + + var evalutatedContext = pyUtils.eval('context', context); + for (var key in evalutatedContext) { + if (evalutatedContext.hasOwnProperty(key) && /^search_default_/.test(key)) { + delete evalutatedContext[key]; + } + } + evalutatedContext.dashboard_merge_domains_contexts = false; + + var name = this.$input.val(); + + this.closeMenu(); + + return self._rpc({ + route: '/board/add_to_dashboard', + params: { + action_id: self.action.id || false, + context_to_save: evalutatedContext, + domain: domain, + view_mode: controller.viewType, + name: name, + }, + }) + .then(function (r) { + if (r) { + self.do_notify( + _.str.sprintf(_t("'%s' added to dashboard"), name), + _t('Please refresh your browser for the changes to take effect.') + ); + } else { + self.do_warn(_t("Could not add filter to dashboard")); + } + }); + }, + /** + * Renders and focuses the unique input if it is visible. + * + * @private + */ + _render: function () { + var $el = QWeb.render('AddToBoardMenu', {widget: this}); + this._replaceElement($el); + if (this.isOpen) { + this.$input = this.$('.o_add_to_board_input'); + this.$input.val(this.action.name); + this.$input.focus(); + } + }, + /** + * Hides and displays the submenu which allows adding custom filters. + * + * @private + */ + _toggleMenu: function () { + this.isOpen = !this.isOpen; + this._render(); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {jQueryEvent} event + */ + _onAddToBoardInputClick: function (event) { + event.preventDefault(); + event.stopPropagation(); + this.$input.focus(); + }, + /** + * @private + * @param {jQueryEvent} event + */ + _onAddToBoardConfirmButtonClick: function (event) { + event.preventDefault(); + event.stopPropagation(); + this._addToBoard(); + }, + /** + * @private + * @param {jQueryEvent} event + */ + _onKeyUp: function (event) { + if (event.which === $.ui.keyCode.ENTER) { + this._addToBoard(); + } + }, + /** + * @private + * @param {jQueryEvent} event + */ + _onMenuHeaderClick: function (event) { + event.preventDefault(); + event.stopPropagation(); + this._toggleMenu(); + }, + +}); + +favorites_submenus_registry.add('add_to_board_menu', AddToBoardMenu, 10); + +return AddToBoardMenu; + +}); diff --git a/addons/board/static/src/js/board_view.js b/addons/board/static/src/js/board_view.js index 3f9647de510..da8384f940f 100644 --- a/addons/board/static/src/js/board_view.js +++ b/addons/board/static/src/js/board_view.js @@ -120,7 +120,6 @@ var BoardController = FormController.extend({ var BoardRenderer = FormRenderer.extend({ custom_events: _.extend({}, FormRenderer.prototype.custom_events, { do_action: '_onDoAction', - env_updated: '_onEnvUpdated', update_filters: '_onUpdateFilters', switch_view: '_onSwitchView', }), @@ -256,6 +255,8 @@ var BoardRenderer = FormRenderer.extend({ var rawContext = new Context(action.context, evalContext, {lang: session.user_context.lang}); var context = pyUtils.eval('context', rawContext, evalContext); var domain = params.domain || pyUtils.eval('domain', action.domain || '[]', action.context); + action.context = context; + action.domain = domain; var viewType = params.viewType || action.views[0][1]; var view = _.find(action.views, function (descr) { return descr[1] === viewType; @@ -266,11 +267,14 @@ var BoardRenderer = FormRenderer.extend({ var View = viewRegistry.get(viewType); var view = new View(viewInfo, { action: action, - context: context, - domain: domain, - groupBy: context.group_by || [], - modelName: action.res_model, hasSelectors: false, + modelName: action.res_model, + searchQuery: { + context: context, + domain: domain, + groupBy: context.group_by || [], + }, + withControlPanel: false, }); return view.getController(self).then(function (controller) { self._boardFormViewIDs[controller.handle] = _.first( @@ -377,29 +381,6 @@ var BoardRenderer = FormRenderer.extend({ }, }); }, - /** - * Intercepts (without stopping) 'do_action' events to force the - * 'keepSearchView' option to false, as the dashboard action has no search - * view, and thus there is no search view that could be re-used for the - * action to execute (a new one will be created instead). - * - * @private - * @param {OdooEvent} event - */ - _onDoAction: function (event) { - if (event.data.options) { - event.data.options.keepSearchView = false; - } - }, - /** - * Stops the propagation of 'env_updated' events triggered by the controllers - * instantiated by the dashboard. - * - * @private - */ - _onEnvUpdated: function (event) { - event.stopPropagation(); - }, /** * @private * @param {MouseEvent} event diff --git a/addons/board/static/src/js/favorite_menu.js b/addons/board/static/src/js/favorite_menu.js deleted file mode 100644 index a3040af44f0..00000000000 --- a/addons/board/static/src/js/favorite_menu.js +++ /dev/null @@ -1,136 +0,0 @@ -odoo.define('board.favorite_menu', function (require) { -"use strict"; - -var ActionManager = require('web.ActionManager'); -var Context = require('web.Context'); -var core = require('web.core'); -var Domain = require('web.Domain'); -var FavoriteMenu = require('web.FavoriteMenu'); -var pyUtils = require('web.py_utils'); - -var _t = core._t; -var QWeb = core.qweb; - -FavoriteMenu.include({ - /** - * We manually add the 'add to dashboard' feature in the searchview. - * - * @override - */ - start: function () { - var self = this; - if(this.action_id === undefined) { - return this._super(); - } - if (this.action.type === 'ir.actions.act_window') { - this.add_to_dashboard_available = true; - this.$('.o_favorites_menu').append(QWeb.render('SearchView.addtodashboard')); - this.$add_to_dashboard = this.$('.o_add_to_dashboard'); - this.$add_dashboard_btn = this.$add_to_dashboard.eq(1).find('button'); - this.$add_dashboard_input = this.$add_to_dashboard.eq(0).find('input'); - this.$add_dashboard_link = this.$('.o_add_to_dashboard_link'); - var title = this.searchview.get_title(); - this.$add_dashboard_input.val(title); - this.$add_dashboard_link.click(function (e) { - e.preventDefault(); - self._toggleDashboardMenu(); - }); - this.$add_dashboard_btn.click(this.proxy('_addDashboard')); - } - return this._super(); - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * This is the main function for actually saving the dashboard. This method - * is supposed to call the route /board/add_to_dashboard with proper - * information. - * - * @private - * @returns {Deferred} - */ - _addDashboard: function () { - var self = this; - var search_data = this.searchview.build_search_data(); - var context = new Context(this.searchview.dataset.get_context() || []); - var domain = []; - - _.each(search_data.contexts, context.add, context); - _.each(search_data.domains, function (d) { - domain.push.apply(domain, Domain.prototype.stringToArray(d)); - }); - - context.add({ - group_by: pyUtils.eval('groupbys', search_data.groupbys || []) - }); - // AAB: trigger_up an event that will be intercepted by the controller, - // as soon as the controller is the parent of the control panel - var am = this.findAncestor(function (a) { - return a instanceof ActionManager; - }); - // with options 'keepSearchView', it may happen that the action_id of - // the searchview (received in init) is not the one of the current - // action, which corresponds to the one we want to add to dashboard - var currentAction = am.getCurrentAction(); - var controller = am.getCurrentController(); - context.add(controller.widget.getContext()); - var c = pyUtils.eval('context', context); - for (var k in c) { - if (c.hasOwnProperty(k) && /^search_default_/.test(k)) { - delete c[k]; - } - } - this._toggleDashboardMenu(false); - c.dashboard_merge_domains_contexts = false; - var name = self.$add_dashboard_input.val(); - - return self._rpc({ - route: '/board/add_to_dashboard', - params: { - action_id: currentAction.id || false, - context_to_save: c, - domain: domain, - view_mode: controller.viewType, - name: name, - }, - }) - .then(function (r) { - if (r) { - self.do_notify( - _.str.sprintf(_t("'%s' added to dashboard"), name), - _t('Please refresh your browser for the changes to take effect.') - ); - } else { - self.do_warn(_t("Could not add filter to dashboard")); - } - }); - }, - /** - * @override - * @private - */ - _closeMenus: function () { - if (this.add_to_dashboard_available) { - this._toggleDashboardMenu(false); - } - this._super(); - }, - /** - * @private - * @param {undefined|false} isOpen - */ - _toggleDashboardMenu: function (isOpen) { - this.$add_dashboard_link - .toggleClass('o_closed_menu', !(_.isUndefined(isOpen)) ? !isOpen : undefined) - .toggleClass('o_open_menu', isOpen); - this.$add_to_dashboard.toggle(isOpen); - if (this.$add_dashboard_link.hasClass('o_open_menu')) { - this.$add_dashboard_input.focus(); - } - }, -}); - -}); diff --git a/addons/board/static/src/scss/dashboard.scss b/addons/board/static/src/scss/dashboard.scss index 08cd66a09c1..ad718403495 100644 --- a/addons/board/static/src/scss/dashboard.scss +++ b/addons/board/static/src/scss/dashboard.scss @@ -123,7 +123,7 @@ } // Override height of graph. min-height doesn't do the trick - .o_graph { + .o_graph_controller { height: 500px; } } diff --git a/addons/board/static/src/xml/board.xml b/addons/board/static/src/xml/board.xml index cb907290fd1..4e6f65a7803 100644 --- a/addons/board/static/src/xml/board.xml +++ b/addons/board/static/src/xml/board.xml @@ -74,6 +74,16 @@