diff options
Diffstat (limited to 'addons/web/static/src/js/views/abstract_controller.js')
| -rw-r--r-- | addons/web/static/src/js/views/abstract_controller.js | 164 |
1 files changed, 73 insertions, 91 deletions
diff --git a/addons/web/static/src/js/views/abstract_controller.js b/addons/web/static/src/js/views/abstract_controller.js index 8a48c201fa6..5128fa6d9a8 100644 --- a/addons/web/static/src/js/views/abstract_controller.js +++ b/addons/web/static/src/js/views/abstract_controller.js @@ -16,7 +16,6 @@ var ActionMixin = require('web.ActionMixin'); var ajax = require('web.ajax'); var concurrency = require('web.concurrency'); const { ComponentWrapper } = require('web.OwlCompatibility'); -const ControlPanel = require('web.ControlPanel'); var mvc = require('web.mvc'); var session = require('web.session'); @@ -25,7 +24,6 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { custom_events: _.extend({}, ActionMixin.custom_events, { navigation_move: '_onNavigationMove', open_record: '_onOpenRecord', - search_panel_domain_updated: '_onSearchPanelDomainUpdated', switch_view: '_onSwitchView', }), events: { @@ -37,14 +35,13 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { * @param {Object[]} params.actionViews * @param {string} params.activeActions * @param {string} params.bannerRoute - * @param {Array[]} params.controlPanelDomain - * @param {ControlPanelModel} [params.controlPanelModel] - * @param {Object} [params.controlPanelProps] + * @param {Object} [params.controlPanel] * @param {string} params.controllerID an id to ease the communication with * upstream components * @param {string} params.displayName * @param {Object} params.initialState * @param {string} params.modelName + * @param {ActionModel} [params.searchModel] * @param {string} [params.searchPanel] * @param {string} params.viewType * @param {boolean} [params.withControlPanel] @@ -64,18 +61,20 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { this.dp = new concurrency.DropPrevious(); this.withControlPanel = params.withControlPanel; + this.withSearchPanel = params.withSearchPanel; + if (params.searchModel) { + this.searchModel = params.searchModel; + } if (this.withControlPanel) { - this.controlPanelProps = params.controlPanelProps; - this._controlPanelModel = params.controlPanelModel; + const { Component, props } = params.controlPanel; + this.ControlPanel = Component; + this.controlPanelProps = props; } - - this.withSearchPanel = params.withSearchPanel && params.searchPanel; - // the following attributes are used when there is a searchPanel if (this.withSearchPanel) { - this._searchPanel = params.searchPanel; + const { Component, props } = params.searchPanel; + this.SearchPanel = Component; + this.searchPanelProps = props; } - this.controlPanelDomain = params.controlPanelDomain || []; - this.searchPanelDomain = this._searchPanel ? this._searchPanel.getDomain() : []; }, /** @@ -84,23 +83,23 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { * @returns {Promise} */ start: async function () { - if (this.withSearchPanel) { - this.$('.o_content') - .addClass('o_controller_with_searchpanel') - .prepend(this._searchPanel.$el); - } this.$el.addClass('o_view_controller'); - this.renderButtons(); const promises = [this._super(...arguments)]; if (this.withControlPanel) { this._updateControlPanelProps(this.initialState); - this._controlPanelWrapper = new ComponentWrapper(this, ControlPanel, this.controlPanelProps); + this._controlPanelWrapper = new ComponentWrapper(this, this.ControlPanel, this.controlPanelProps); this._controlPanelWrapper.env.bus.on('focus-view', this, () => this._giveFocus()); promises.push(this._controlPanelWrapper.mount(this.el, { position: 'first-child' })); } + if (this.withSearchPanel) { + this._searchPanelWrapper = new ComponentWrapper(this, this.SearchPanel, this.searchPanelProps); + const content = this.el.querySelector(':scope .o_content'); + content.classList.add('o_controller_with_searchpanel'); + promises.push(this._searchPanelWrapper.mount(content, { position: 'first-child' })); + } await Promise.all(promises); - await this._update(this.initialState, { shouldUpdateControlPanel: false }); + await this._update(this.initialState, { shouldUpdateSearchComponents: false }); this.updateButtons(); }, /** @@ -118,12 +117,9 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { */ on_attach_callback: function () { ActionMixin.on_attach_callback.call(this); - if (this.withSearchPanel) { - this._searchPanel.on_attach_callback(); - } + this.searchModel.on('search', this, this._onSearch); if (this.withControlPanel) { - this._controlPanelModel.on('search', this, this._onSearch); - this._controlPanelModel.on('get-controller-query-params', this, this._onGetOwnedQueryParams); + this.searchModel.on('get-controller-query-params', this, this._onGetOwnedQueryParams); } if (!(this.renderer instanceof owl.Component)) { this.renderer.on_attach_callback(); @@ -134,9 +130,9 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { */ on_detach_callback: function () { ActionMixin.on_detach_callback.call(this); + this.searchModel.off('search', this); if (this.withControlPanel) { - this._controlPanelModel.off('search', this); - this._controlPanelModel.off('get-controller-query-params', this); + this.searchModel.off('get-controller-query-params', this); } if (!(this.renderer instanceof owl.Component)) { this.renderer.on_detach_callback(); @@ -177,20 +173,32 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { }, /** * Export the state of the controller containing information that is shared - * between different controllers of a same action (like the current - * searchQuery of the controlPanel). + * between different controllers of a same action (like the current search + * model state or the states of some components). * * @returns {Object} */ - exportState: function () { - var state = {}; - if (this.withControlPanel) { - state.cpState = this._controlPanelModel.exportState(); + exportState() { + const exported = { + searchModel: this.searchModel.exportState(), + }; + if (this.withSearchPanel) { + const searchPanel = this._searchPanelWrapper.componentRef.comp; + exported.searchPanel = searchPanel.exportState(); } + return exported; + }, + /** + * Parses and imports a previously exported state. + * + * @param {Object} state + */ + importState(state) { + this.searchModel.importState(state.searchModel); if (this.withSearchPanel) { - state.spState = this._searchPanel.exportState(); + const searchPanel = this._searchPanelWrapper.componentRef.comp; + searchPanel.importState(state.searchPanel); } - return state; }, /** * The use of this method is discouraged. It is still snakecased, because @@ -207,40 +215,17 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { /** * Short helper method to reload the view * - * @param {Object} [params={}] This object will simply be given to the update + * @param {Object} [params={}] + * @param {Object} [params.controllerState={}] * @returns {Promise} */ reload: async function (params = {}) { - const controllerState = params.controllerState || {}; - const cpState = controllerState.cpState; - if (this.withControlPanel && cpState) { - this._controlPanelModel.importState(cpState); - const searchQuery = this._controlPanelModel.getQuery(); - params = Object.assign({}, params, searchQuery); - } - let postponeRendering = false; - if (this.withSearchPanel) { - if (params.domain) { - this.controlPanelDomain = params.domain; - } - if (controllerState.spState) { - this._searchPanel.importState(controllerState.spState); - } else { - const viewDomain = await this._getViewDomain(); - await this._searchPanel.update({ - searchDomain: this.controlPanelDomain, - viewDomain, - }); - postponeRendering = !params.noRender; - params.noRender = true; // wait for searchpanel to be ready to render - } - this.searchPanelDomain = this._searchPanel.getDomain(); - params.domain = this.controlPanelDomain.concat(this.searchPanelDomain); - } - await this.update(params, {}); - if (postponeRendering) { - return this._updateRendererState(false); + if (params.controllerState) { + this.importState(params.controllerState); + await this.searchModel.load(); + Object.assign(params, this.searchModel.get('query')); } + return this.update(params, {}); }, /** * This is the main entry point for the controller. Changes from the search @@ -288,15 +273,6 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { return null; }, /** - * Get the domain defined by the view. It is meant to be overridden. - * - * @private - * @returns {Promise<Array[]>} - */ - _getViewDomain: async function () { - return []; - }, - /** * Meant to be overriden to return a proper object. * @private * @param {Object} [state] @@ -409,7 +385,8 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { * @private * @param {Object} state the state given by the model * @param {Object} [params={}] - * @param {Object} [params.shouldUpdateControlPanel] + * @param {Array} [params.breadcrumbs] + * @param {Object} [params.shouldUpdateSearchComponents] * @returns {Promise} */ async _update(state, params) { @@ -418,12 +395,17 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { this.renderButtons(); } const promises = [this._renderBanner()]; - if (this.withControlPanel && params.shouldUpdateControlPanel !== false) { - this._updateControlPanelProps(state); - if (params.breadcrumbs) { - this.controlPanelProps.breadcrumbs = params.breadcrumbs; + if (params.shouldUpdateSearchComponents !== false) { + if (this.withControlPanel) { + this._updateControlPanelProps(state); + if (params.breadcrumbs) { + this.controlPanelProps.breadcrumbs = params.breadcrumbs; + } + promises.push(this.updateControlPanel()); + } + if (this.withSearchPanel) { + this._updateSearchPanel(); } - promises.push(this.updateControlPanel()); } this._pushState(); await Promise.all(promises); @@ -476,6 +458,15 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { } return this.renderer.updateState(state, params); }, + /** + * @private + * @param {Object} [newProps={}] + * @return {Promise} + */ + async _updateSearchPanel(newProps) { + Object.assign(this.searchPanelProps, newProps); + await this._searchPanelWrapper.update(this.searchPanelProps); + }, //-------------------------------------------------------------------------- // Handlers @@ -551,7 +542,7 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { switch (ev.data.direction) { case 'up': ev.stopPropagation(); - this._controlPanelModel.trigger('focus-control-panel'); + this.searchModel.trigger('focus-control-panel'); break; case 'down': ev.stopPropagation(); @@ -594,15 +585,6 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { this.reload(_.extend({ offset: 0, groupsOffset: 0 }, searchQuery)); }, /** - * @private - * @param {OdooEvent} ev - * @param {Array[]} ev.data.domain the current domain of the searchPanel - */ - _onSearchPanelDomainUpdated: function (ev) { - this.searchPanelDomain = ev.data.domain; - this.reload({offset: 0}); - }, - /** * Intercepts the 'switch_view' event to add the controllerID into the data, * and lets the event bubble up. * |
