diff options
| author | Julien Mougenot <jum@odoo.com> | 2020-03-11 09:38:29 +0000 |
|---|---|---|
| committer | Julien Mougenot <jum@odoo.com> | 2020-03-13 14:08:33 +0000 |
| commit | e68d3bb09d1f844387ceb20aa76022ace48507d9 (patch) | |
| tree | d238fa35dcb11e5628112377a9daf569405ca74b /addons/board/static | |
| parent | 18e5416636b19b0953b1e6e26bfaeab1ebecce4c (diff) | |
[REF] *: Adapt all modules to new control panel
Adaptation of the code throughout all modules to properly instantiate the newly
refactored control panel and update it accordingly.
Part of task 2196029
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Diffstat (limited to 'addons/board/static')
| -rw-r--r-- | addons/board/static/src/js/action_manager_board_action.js | 2 | ||||
| -rw-r--r-- | addons/board/static/src/js/add_to_board_menu.js | 313 | ||||
| -rw-r--r-- | addons/board/static/src/js/board_view.js | 40 | ||||
| -rw-r--r-- | addons/board/static/src/scss/dashboard.scss | 3 | ||||
| -rw-r--r-- | addons/board/static/src/xml/board.xml | 30 |
5 files changed, 175 insertions, 213 deletions
diff --git a/addons/board/static/src/js/action_manager_board_action.js b/addons/board/static/src/js/action_manager_board_action.js index 3036ac0f328..05414572311 100644 --- a/addons/board/static/src/js/action_manager_board_action.js +++ b/addons/board/static/src/js/action_manager_board_action.js @@ -21,8 +21,8 @@ ActionManager.include({ if (action.res_model === 'board.board' && action.view_mode === 'form') { action.target = 'inline'; _.extend(action.flags, { + hasActionMenus: false, hasSearchView: false, - hasSidebar: false, headless: true, }); } diff --git a/addons/board/static/src/js/add_to_board_menu.js b/addons/board/static/src/js/add_to_board_menu.js index 57e98ca87d7..dd5158c6d50 100644 --- a/addons/board/static/src/js/add_to_board_menu.js +++ b/addons/board/static/src/js/add_to_board_menu.js @@ -1,211 +1,154 @@ 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); - }, + "use strict"; - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- + const Context = require('web.Context'); + const Domain = require('web.Domain'); + const DropdownMenuItem = require('web.DropdownMenuItem'); + const FavoriteMenu = require('web.FavoriteMenu'); + const pyUtils = require('web.py_utils'); + const { sprintf } = require('web.utils'); + const { useAutofocus } = require('web.custom_hooks'); - /** - * Closes the menu and render it. - * - */ - closeMenu: function () { - this.isOpen = false; - this._render(); - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- + const { useState } = owl.hooks; /** - * 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. + * 'Add to board' menu * - * @private - * @returns {Promise} + * Component consisiting of a toggle button, a text input and an 'Add' button. + * The first button is simply used to toggle the component and will determine + * whether the other elements should be rendered. + * The input will be given the name (or title) of the view that will be added. + * Finally, the last button will send the name as well as some of the action + * properties to the server to add the current view (and its context) to the + * user's dashboard. + * This component is only available in actions of type 'ir.actions.act_window'. + * @extends DropdownMenuItem */ - _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: searchQuery.groupBy, - orderedBy: searchQuery.orderedBy, - }); - - this.trigger_up('get_controller_query_params', { - callback: function (controllerQueryParams) { - var queryContext = controllerQueryParams.context; - var allContext = _.extend( - _.omit(controllerQueryParams, ['context']), - queryContext - ); - context.add(allContext); - } - }); - - var domain = new Domain(this.action.domain || []); - domain = Domain.prototype.normalizeArray(domain.toArray().concat(searchQuery.domain)); + class AddToBoardMenu extends DropdownMenuItem { + constructor() { + super(...arguments); + + this.interactive = true; + this.state = useState({ + name: this.env.action.name || "", + open: false, + }); - var evalutatedContext = pyUtils.eval('context', context); - for (var key in evalutatedContext) { - if (evalutatedContext.hasOwnProperty(key) && /^search_default_/.test(key)) { - delete evalutatedContext[key]; - } + useAutofocus(); } - evalutatedContext.dashboard_merge_domains_contexts = false; - var name = this.$input.val(); + //--------------------------------------------------------------------- + // 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 + */ + async _addToBoard() { + const searchQuery = this.env.controlPanelModel.getQuery(); + const context = new Context(this.env.action.context); + context.add(searchQuery.context); + context.add({ + group_by: searchQuery.groupBy, + orderedBy: searchQuery.orderedBy, + }); + if (searchQuery.timeRanges && searchQuery.timeRanges.hasOwnProperty('fieldName')) { + const { fieldName: field, range, comparisonRange } = searchQuery.timeRanges; + context.add({ + time_ranges : { field, range, comparisonRange }, + }); + } + let controllerQueryParams; + this.env.controlPanelModel.trigger('get-controller-query-params', params => { + controllerQueryParams = params || {}; + }); + controllerQueryParams.context = controllerQueryParams.context || {}; + const queryContext = controllerQueryParams.context; + delete controllerQueryParams.context; + context.add(Object.assign(controllerQueryParams, queryContext)); + + const domainArray = new Domain(this.env.action.domain || []); + const domain = Domain.prototype.normalizeArray(domainArray.toArray().concat(searchQuery.domain)); + + const evalutatedContext = context.eval(); + for (const key in evalutatedContext) { + if (evalutatedContext.hasOwnProperty(key) && /^search_default_/.test(key)) { + delete evalutatedContext[key]; + } + } + evalutatedContext.dashboard_merge_domains_contexts = false; - this.closeMenu(); + Object.assign(this.state, { + name: this.env.action.name || "", + open: false, + }); - return self._rpc({ + const result = await this.rpc({ route: '/board/add_to_dashboard', params: { - action_id: self.action.id || false, + action_id: this.env.action.id || false, context_to_save: evalutatedContext, domain: domain, - view_mode: controller.viewType, - name: name, + view_mode: this.env.view.type, + name: this.state.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(); + if (result) { + this.env.services.notification.notify({ + title: sprintf(this.env._t("'%s' added to dashboard"), this.state.name), + message: this.env._t("Please refresh your browser for the changes to take effect."), + type: 'warning', + }); + } else { + this.env.services.notification.notify({ + message: this.env._t("Could not add filter to dashboard"), + type: 'danger', + }); + } } - }, - /** - * 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(); + //--------------------------------------------------------------------- + // Handlers + //--------------------------------------------------------------------- + + /** + * @private + * @param {KeyboardEvent} ev + */ + _onInputKeydown(ev) { + switch (ev.key) { + case 'Enter': + ev.preventDefault(); + this._addToBoard(); + break; + case 'Escape': + // Gives the focus back to the component. + ev.preventDefault(); + ev.target.blur(); + break; + } } - }, - /** - * @private - * @param {jQueryEvent} event - */ - _onMenuHeaderClick: function (event) { - event.preventDefault(); - event.stopPropagation(); - this._toggleMenu(); - }, -}); + //--------------------------------------------------------------------- + // Static + //--------------------------------------------------------------------- + + /** + * @param {Object} env + * @returns {boolean} + */ + static shouldBeDisplayed(env) { + return env.action.type === 'ir.actions.act_window'; + } + } -favorites_submenus_registry.add('add_to_board_menu', AddToBoardMenu, 10); + AddToBoardMenu.props = {}; + AddToBoardMenu.template = 'AddToBoardMenu'; -return AddToBoardMenu; + FavoriteMenu.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 ffdcfbeb7ed..fab64783073 100644 --- a/addons/board/static/src/js/board_view.js +++ b/addons/board/static/src/js/board_view.js @@ -42,10 +42,7 @@ var BoardController = FormController.extend({ * @override */ getTitle: function () { - if (this.inDashboard) { - return _t("My Dashboard"); - } - return this._super.apply(this, arguments); + return _t("My Dashboard"); }, //-------------------------------------------------------------------------- @@ -94,12 +91,6 @@ var BoardController = FormController.extend({ dialog.open(); }, /** - * @private - */ - _onEnableDashboard: function () { - this.inDashboard = true; - }, - /** * We need to intercept switch_view event coming from sub views, because we * don't actually want to switch view in dashboard, we want to do a * do_action (which will open the record in a different breadcrumb). @@ -255,6 +246,7 @@ 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]; @@ -265,17 +257,32 @@ var BoardRenderer = FormRenderer.extend({ .then(function (viewsInfo) { var viewInfo = viewsInfo[viewType]; var View = viewRegistry.get(viewType); + + const searchQuery = { + context: context, + domain: domain, + groupBy: typeof context.group_by === 'string' && context.group_by ? + [context.group_by] : + context.group_by || [], + orderedBy: context.orderedBy || [], + }; + + if (['pivot', 'dashboard', 'graph', 'cohort'].includes(viewType)) { + if (context.time_ranges) { + const { field: fieldName, range, comparisonRange } = context.time_ranges; + searchQuery.timeRanges = { fieldName, range, comparisonRange }; + } else { + searchQuery.timeRanges = {}; + } + } + var view = new View(viewInfo, { action: action, hasSelectors: false, modelName: action.res_model, - searchQuery: { - context: context, - domain: domain, - groupBy: typeof context.group_by === 'string' && context.group_by ? [context.group_by] : context.group_by || [], - orderedBy: context.orderedBy || [], - }, + searchQuery, withControlPanel: false, + withSearchPanel: false, }); return view.getController(self).then(function (controller) { self._boardFormViewIDs[controller.handle] = _.first( @@ -300,7 +307,6 @@ var BoardRenderer = FormRenderer.extend({ // this function has a side effect. This is ok because we assume that // once we have a '<board>' tag, we are in a special dashboard mode. this.$el.addClass('o_dashboard'); - this.trigger_up('enable_dashboard'); var hasAction = _.detect(node.children, function (column) { return _.detect(column.children,function (element){ diff --git a/addons/board/static/src/scss/dashboard.scss b/addons/board/static/src/scss/dashboard.scss index 518849cde0a..69d1511761b 100644 --- a/addons/board/static/src/scss/dashboard.scss +++ b/addons/board/static/src/scss/dashboard.scss @@ -151,7 +151,8 @@ // Favorites menu in control panel .o_add_to_dashboard { display: none; // hidden by default - @include o-search-options-dropdown-custom-item; + max-width: 250px; + width: auto; } @include media-breakpoint-down(sm) { diff --git a/addons/board/static/src/xml/board.xml b/addons/board/static/src/xml/board.xml index bd2ec9fe605..c81892aca07 100644 --- a/addons/board/static/src/xml/board.xml +++ b/addons/board/static/src/xml/board.xml @@ -80,15 +80,27 @@ <iframe width="100%" frameborder="0" t-att-src="url"/> </t> -<div t-name="AddToBoardMenu"> - <button type="button" class="dropdown-item o_add_to_board o_menu_header">Add to my Dashboard</button> - <div t-if="widget.isOpen" class="dropdown-item-text o_add_to_board"> - <input class="o_input o_add_to_board_input" type="text"/> - </div> - <div t-if="widget.isOpen" class="dropdown-item-text o_add_to_board"> - <button type="button" class="btn btn-primary o_add_to_board_confirm_button">Add</button> - </div> -</div> +<t t-name="AddToBoardMenu" owl="1"> + <li class="o_menu_item o_add_to_board" role="menuitem"> + <button type="button" class="dropdown-item" + t-ref="fallback-focus" + t-on-click="state.open = !state.open" + > + <t>Add to my Dashboard</t> + </button> + <t t-if="state.open"> + <div class="dropdown-item-text"> + <input type="text" class="o_input" autofocus="" + t-model.trim="state.name" + t-on-keydown="_onInputKeydown" + /> + </div> + <div class="dropdown-item-text"> + <button type="button" class="btn btn-primary" t-on-click="_addToBoard">Add</button> + </div> + </t> + </li> +</t> <t t-name="SearchView.addtodashboard"> <a href="#" class="dropdown-item o_add_to_dashboard_link o_closed_menu">Add to my Dashboard</a> |
