diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/js/chrome/abstract_action.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/web/static/src/js/chrome/abstract_action.js')
| -rw-r--r-- | addons/web/static/src/js/chrome/abstract_action.js | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/addons/web/static/src/js/chrome/abstract_action.js b/addons/web/static/src/js/chrome/abstract_action.js new file mode 100644 index 00000000..fc5c1fd4 --- /dev/null +++ b/addons/web/static/src/js/chrome/abstract_action.js @@ -0,0 +1,192 @@ +odoo.define('web.AbstractAction', function (require) { +"use strict"; + +/** + * We define here the AbstractAction widget, which implements the ActionMixin. + * All client actions must extend this widget. + * + * @module web.AbstractAction + */ + +var ActionMixin = require('web.ActionMixin'); +const ActionModel = require('web/static/src/js/views/action_model.js'); +var ControlPanel = require('web.ControlPanel'); +var Widget = require('web.Widget'); +const { ComponentWrapper } = require('web.OwlCompatibility'); + +var AbstractAction = Widget.extend(ActionMixin, { + config: { + ControlPanel: ControlPanel, + }, + + /** + * If this flag is set to true, the client action will create a control + * panel whenever it is created. + * + * @type boolean + */ + hasControlPanel: false, + + /** + * If true, this flag indicates that the client action should automatically + * fetch the <arch> of a search view (or control panel view). Note that + * to do that, it also needs a specific modelName. + * + * For example, the Discuss application adds the following line in its + * constructor:: + * + * this.searchModelConfig.modelName = 'mail.message'; + * + * @type boolean + */ + loadControlPanel: false, + + /** + * A client action might want to use a search bar in its control panel, or + * it could choose not to use it. + * + * Note that it only makes sense if hasControlPanel is set to true. + * + * @type boolean + */ + withSearchBar: false, + + /** + * This parameter can be set to customize the available sub menus in the + * controlpanel (Filters/Group By/Favorites). This is basically a list of + * the sub menus that we want to use. + * + * Note that it only makes sense if hasControlPanel is set to true. + * + * For example, set ['filter', 'favorite'] to enable the Filters and + * Favorites menus. + * + * @type string[] + */ + searchMenuTypes: [], + + /** + * @override + * + * @param {Widget} parent + * @param {Object} action + * @param {Object} [options] + */ + init: function (parent, action, options) { + this._super(parent); + this._title = action.display_name || action.name; + + this.searchModelConfig = { + context: Object.assign({}, action.context), + domain: action.domain || [], + env: owl.Component.env, + searchMenuTypes: this.searchMenuTypes, + }; + this.extensions = {}; + if (this.hasControlPanel) { + this.extensions.ControlPanel = { + actionId: action.id, + withSearchBar: this.withSearchBar, + }; + + this.viewId = action.search_view_id && action.search_view_id[0]; + + this.controlPanelProps = { + action, + breadcrumbs: options && options.breadcrumbs, + withSearchBar: this.withSearchBar, + searchMenuTypes: this.searchMenuTypes, + }; + } + }, + /** + * The willStart method is actually quite complicated if the client action + * has a controlPanel, because it needs to prepare it. + * + * @override + */ + willStart: async function () { + const superPromise = this._super(...arguments); + if (this.hasControlPanel) { + if (this.loadControlPanel) { + const { context, modelName } = this.searchModelConfig; + const options = { load_filters: this.searchMenuTypes.includes('favorite') }; + const { arch, fields, favoriteFilters } = await this.loadFieldView( + modelName, + context || {}, + this.viewId, + 'search', + options + ); + const archs = { search: arch }; + const { ControlPanel: controlPanelInfo } = ActionModel.extractArchInfo(archs); + Object.assign(this.extensions.ControlPanel, { + archNodes: controlPanelInfo.children, + favoriteFilters, + fields, + }); + this.controlPanelProps.fields = fields; + } + } + this.searchModel = new ActionModel(this.extensions, this.searchModelConfig); + if (this.hasControlPanel) { + this.controlPanelProps.searchModel = this.searchModel; + } + return Promise.all([ + superPromise, + this.searchModel.load(), + ]); + }, + /** + * @override + */ + start: async function () { + await this._super(...arguments); + if (this.hasControlPanel) { + if ('title' in this.controlPanelProps) { + this._setTitle(this.controlPanelProps.title); + } + this.controlPanelProps.title = this.getTitle(); + this._controlPanelWrapper = new ComponentWrapper(this, this.config.ControlPanel, this.controlPanelProps); + await this._controlPanelWrapper.mount(this.el, { position: 'first-child' }); + + } + }, + /** + * @override + */ + destroy: function() { + this._super.apply(this, arguments); + ActionMixin.destroy.call(this); + }, + /** + * @override + */ + on_attach_callback: function () { + ActionMixin.on_attach_callback.call(this); + this.searchModel.on('search', this, this._onSearch); + if (this.hasControlPanel) { + this.searchModel.on('get-controller-query-params', this, this._onGetOwnedQueryParams); + } + }, + /** + * @override + */ + on_detach_callback: function () { + ActionMixin.on_detach_callback.call(this); + this.searchModel.off('search', this); + if (this.hasControlPanel) { + this.searchModel.off('get-controller-query-params', this); + } + }, + + /** + * @private + * @param {Object} [searchQuery] + */ + _onSearch: function () {}, +}); + +return AbstractAction; + +}); |
