odoo.define('web.Sidebar', function (require) { "use strict"; var Context = require('web.Context'); var core = require('web.core'); var pyUtils = require('web.py_utils'); var Widget = require('web.Widget'); var QWeb = core.qweb; var _t = core._t; var Sidebar = Widget.extend({ events: { "click a.dropdown-item": "_onDropdownClicked" }, /** * @override * * @param {Object} options * @param {Object} options.items * @param {Object} options.sections * @param {Object} options.env * @param {Object} options.actions * */ init: function (parent, options) { this._super.apply(this, arguments); this.options = _.defaults(options || {}, { 'editable': true }); this.env = options.env; this.sections = options.sections || [ {name: 'print', label: _t('Print')}, {name: 'other', label: _t('Action')}, ]; this.items = options.items || { print: [], other: [], }; if (options.actions) { this._addToolbarActions(options.actions); } }, /** * @override */ start: function () { this._super.apply(this, arguments); this.$el.addClass('btn-group'); this._redraw(); }, //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- /** * Update the env for the sidebar then rerender it. * * @param {Object} env */ updateEnv: function (env) { this.env = env; this._redraw(); }, //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- /** * For each item added to the section: * * ``label`` * will be used as the item's name in the sidebar, can be html * * ``action`` * descriptor for the action which will be executed, ``action`` and * ``callback`` should be exclusive * * ``callback`` * function to call when the item is clicked in the sidebar, called * with the item descriptor as its first argument (so information * can be stored as additional keys on the object passed to * ``_addItems``) * * ``classname`` (optional) * ``@class`` set on the sidebar serialization of the item * * ``title`` (optional) * will be set as the item's ``@title`` (tooltip) * * @private * @param {String} sectionCode * @param {Array<{label, action | callback[, classname][, title]}>} items */ _addItems: function (sectionCode, items) { if (items) { this.items[sectionCode].unshift.apply(this.items[sectionCode], items); } }, /** * Method that will add the custom actions to the toolbar * * @private * @param {Object} toolbarActions */ _addToolbarActions: function (toolbarActions) { var self = this; _.each(['print','action','relate'], function (type) { if (type in toolbarActions) { var actions = toolbarActions[type]; if (actions && actions.length) { var items = _.map(actions, function (action) { return { label: action.name, action: action, }; }); self._addItems(type === 'print' ? 'print' : 'other', items); } } }); if ('other' in toolbarActions) { this._addItems('other', toolbarActions.other); } }, /** * Performs the action for the item clicked after getting the data * necessary with a trigger up * * @private * @param {Object} item */ _onItemActionClicked: function (item) { var self = this; this.trigger_up('sidebar_data_asked', { callback: function (env) { self.env = env; var activeIdsContext = { active_id: env.activeIds[0], active_ids: env.activeIds, active_model: env.model, }; if (env.domain) { activeIdsContext.active_domain = env.domain; } var context = pyUtils.eval('context', new Context(env.context, activeIdsContext)); self._rpc({ route: '/web/action/load', params: { action_id: item.action.id, context: context, }, }).done(function (result) { result.context = new Context( result.context || {}, activeIdsContext) .set_eval_context(context); result.flags = result.flags || {}; result.flags.new_window = true; self.do_action(result, { on_close: function () { self.trigger_up('reload'); }, }); }); } }); }, /** * Method that renders the sidebar when there is a data update * * @private */ _redraw: function () { this.$el.html(QWeb.render('Sidebar', {widget: this})); // Hides Sidebar sections when item list is empty _.each(this.$('.o_dropdown'), function (el) { var $dropdown = $(el); if (!$dropdown.find('.dropdown-item').length) { $dropdown.hide(); } }); this.$("[title]").tooltip({ delay: { show: 500, hide: 0} }); }, //-------------------------------------------------------------------------- // Handlers //-------------------------------------------------------------------------- /** * Method triggered when the user clicks on a toolbar dropdown * * @private * @param {MouseEvent} event */ _onDropdownClicked: function (event) { var section = $(event.currentTarget).data('section'); var index = $(event.currentTarget).data('index'); var item = this.items[section][index]; if (item.callback) { item.callback.apply(this, [item]); } else if (item.action) { this._onItemActionClicked(item); } else if (item.url) { return true; } event.preventDefault(); }, }); return Sidebar; });