Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[REF] web: move ControlPanel inside controllers/actions
This branch introduces a large-scale reorganization of the component tree generated by the web client. The short version is that now, the control panel is a child of the view controller and no longer a sibling. Graphically (and simplified), we go from this: webClient / | \ ... ... actionManager / \ controlPanel viewController / \ to this: webClient / | \ ... ... actionManager | viewController / | \ ControlPanelController / \ CPRenderer CPModel The motivation is that this work moves the code where it should be. Before this commit, it was kind of weird to have code in the controllers to render buttons outside of their root node (in renderButtons). Also, the action manager had to take care of coordinating search view states between view transitions. So, this work simplifies the code. It also makes it easier to extend. We see day after day that Odoo needs to take care of more complex UI needs, and in many cases, these needs were quite difficult to implement (we prefer spaghettis in our plates, not in our code). The changes in this branch should open the way to implement these features. For example, - it will now be easy to add the possibility of views (for example, the search view or a new ControlPanel view) to add custom buttons (of type action or object) in the control panel. - Another need will be to serialize/ restore the state of the search view across action boundaries (needed by the dashboard). - Another example is the possibility for views to customize easily the presence/absence of sub menus (filters/groupbys/favorites/ time range/...) - Another need is an easier way for views/client action to customize their control panel. This commit also contains a large rewrite of the search view (so it is more inline with our architecture and easier to maintain). Part of task 1893568 Co-authored-by: Aaron Bohy <aab@odoo.com> Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com> Co-authored-by: Martin Geubelle <mge@odoo.com> -- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr closes #29106
- Loading branch information
Showing
147 changed files
with
7,917 additions
and
6,863 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
|
||
}); |
Oops, something went wrong.