diff options
| author | Priyanka Kakadiya <pka@odoo.com> | 2020-08-26 07:38:43 +0000 |
|---|---|---|
| committer | Julien Mougenot <jum@odoo.com> | 2020-10-06 11:12:20 +0000 |
| commit | 44055fd0f0de4f4a64635bd384c6004eb67c8374 (patch) | |
| tree | 7d4739adaa83d3e16515ff72ed81af766246f62a /addons/web/static/src/js | |
| parent | 6916a386db4cad398c6faa02d745103617a1e512 (diff) | |
[FIX] web: hide action button when no action
Before this commit: the action menu registry items were rendered
regardless of their inner state. The problem is that these item
components can choose not to render themselves, leading to a blank
dropdown menu if no other item was present.
To fix this, the "getProps" function of the registry has been altered to
act as validation: the item will not be rendered if the return value is
falsy. The function has also been made asynchronous to allow RPC calls.
This solution is still flawed and hides a bad design choice which is to
register components and not items or item getters; this API is too
complex for its use case(s) and adds pointless depth to the DOM. The
shape of the registry should be simplified in an improvement in master.
closes odoo/odoo#59254
Task: 2325587
X-original-commit: 45c7d881a5d130f6b3222749c8c87b6c6b45e910
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Co-authored-by: Julien Mougenot <jum@odoo.com>
Co-authored-by: Mohammed Shekha <msh@odoo.com>
Diffstat (limited to 'addons/web/static/src/js')
| -rw-r--r-- | addons/web/static/src/js/components/action_menus.js | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/addons/web/static/src/js/components/action_menus.js b/addons/web/static/src/js/components/action_menus.js index 4427ac5c948..ed95e6663fa 100644 --- a/addons/web/static/src/js/components/action_menus.js +++ b/addons/web/static/src/js/components/action_menus.js @@ -7,6 +7,8 @@ odoo.define('web.ActionMenus', function (require) { const { Component } = owl; + let registryActionId = 1; + /** * Action menus (or Action/Print bar, previously called 'Sidebar') * @@ -21,6 +23,16 @@ odoo.define('web.ActionMenus', function (require) { */ class ActionMenus extends Component { + async willStart() { + this.actionItems = await this._setActionItems(this.props); + this.printItems = await this._setPrintItems(this.props); + } + + async willUpdateProps(nextProps) { + this.actionItems = await this._setActionItems(nextProps); + this.printItems = await this._setPrintItems(nextProps); + } + mounted() { this._addTooltips(); } @@ -30,39 +42,59 @@ odoo.define('web.ActionMenus', function (require) { } //--------------------------------------------------------------------- - // Getters + // Private //--------------------------------------------------------------------- /** - * @returns {Object[]} + * Add the tooltips to the items + * @private */ - get actionItems() { + _addTooltips() { + $(this.el.querySelectorAll('[title]')).tooltip({ + delay: { show: 500, hide: 0 } + }); + } + + /** + * @private + * @param {Object} props + * @returns {Promise<Object[]>} + */ + async _setActionItems(props) { // Callback based actions - const callbackActions = (this.props.items.other || []).map( + const callbackActions = (props.items.other || []).map( action => Object.assign({ key: `action-${action.description}` }, action) ); // Action based actions - const actionActions = this.props.items.action || []; - const relateActions = this.props.items.relate || []; + const actionActions = props.items.action || []; + const relateActions = props.items.relate || []; const formattedActions = [...actionActions, ...relateActions].map( action => ({ action, description: action.name, key: action.id }) ); // ActionMenus action registry components - const registryActions = this.constructor.registry.values().map( - ({ Component, getProps }, index) => ({ - key: `registry-action-${index}`, - Component, - props: getProps(this.props), - }) - ); + const registryActions = []; + const rpc = this.rpc.bind(this); + for (const { Component, getProps } of this.constructor.registry.values()) { + const itemProps = await getProps(props, this.env, rpc); + if (itemProps) { + registryActions.push({ + Component, + key: `registry-action-${registryActionId++}`, + props: itemProps, + }); + } + } + return [...callbackActions, ...formattedActions, ...registryActions]; } /** - * @returns {Object[]} + * @private + * @param {Object} props + * @returns {Promise<Object[]>} */ - get printItems() { - const printActions = this.props.items.print || []; + async _setPrintItems(props) { + const printActions = props.items.print || []; const printItems = printActions.map( action => ({ action, description: action.name, key: action.id }) ); @@ -70,20 +102,6 @@ odoo.define('web.ActionMenus', function (require) { } //--------------------------------------------------------------------- - // Private - //--------------------------------------------------------------------- - - /** - * Add teh tooltips to the items - * @private - */ - _addTooltips() { - $(this.el.querySelectorAll('[title]')).tooltip({ - delay: { show: 500, hide: 0 } - }); - } - - //--------------------------------------------------------------------- // Handlers //--------------------------------------------------------------------- @@ -160,7 +178,7 @@ odoo.define('web.ActionMenus', function (require) { ActionMenus.components = { DropdownMenu }; ActionMenus.props = { - activeIds: { type: Array, element: [Number | String] }, // virtual IDs are strings. + activeIds: { type: Array, element: [Number, String] }, // virtual IDs are strings. context: Object, domain: { type: Array, optional: 1 }, isDomainSelected: { type: Boolean, optional: 1 }, |
