diff options
| author | Julien Mougenot <jum@odoo.com> | 2020-03-11 09:38:28 +0000 |
|---|---|---|
| committer | Julien Mougenot <jum@odoo.com> | 2020-03-13 14:08:33 +0000 |
| commit | 18e5416636b19b0953b1e6e26bfaeab1ebecce4c (patch) | |
| tree | 5be75af26f1707a5b8b2184545719f3628d2980f /addons/web/static/src/js/views/form | |
| parent | fbf347498f1cc7b74ef373179b7bcae201715c24 (diff) | |
[REF] web: Adapt views/actions to new control panel
Some web actions/controllers/viewsl have been adapted to properly instantiate the
newly refactored control panel and update it accordingly. We needed to adapt the
starting mechanism of actions and controllers to ensure that the control panel
instantiation did not delay the loading of any widget.
Part of task 2196029
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Diffstat (limited to 'addons/web/static/src/js/views/form')
| -rw-r--r-- | addons/web/static/src/js/views/form/form_controller.js | 320 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form/form_renderer.js | 3 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form/form_view.js | 12 |
3 files changed, 126 insertions, 209 deletions
diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js index 9d361693595..5c54afb7e41 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -5,7 +5,6 @@ var BasicController = require('web.BasicController'); var core = require('web.core'); var Dialog = require('web.Dialog'); var dialogs = require('web.view_dialogs'); -var Sidebar = require('web.Sidebar'); var _t = core._t; var qweb = core.qweb; @@ -24,7 +23,7 @@ var FormController = BasicController.extend({ /** * @override * - * @param {boolean} params.hasSidebar + * @param {boolean} params.hasActionMenus * @param {Object} params.toolbarActions */ init: function (parent, model, renderer, params) { @@ -34,7 +33,7 @@ var FormController = BasicController.extend({ this.disableAutofocus = params.disableAutofocus; this.footerToButtons = params.footerToButtons; this.defaultButtons = params.defaultButtons; - this.hasSidebar = params.hasSidebar; + this.hasActionMenus = params.hasActionMenus; this.toolbarActions = params.toolbarActions || {}; }, /** @@ -88,10 +87,9 @@ var FormController = BasicController.extend({ * for the new record. * @returns {Promise} */ - createRecord: function (parentID) { - var self = this; - var record = this.model.get(this.handle, {raw: true}); - return this.model.load({ + createRecord: async function (parentID) { + const record = this.model.get(this.handle, { raw: true }); + const handle = await this.model.load({ context: record.getContext(), fields: record.fields, fieldsInfo: record.fieldsInfo, @@ -100,15 +98,14 @@ var FormController = BasicController.extend({ res_ids: record.res_ids, type: 'record', viewType: 'form', - }).then(function (handle) { - self.handle = handle; - self._updateEnv(); - return self._setMode('edit'); }); + this.handle = handle; + this._updateControlPanel(); + return this._setMode('edit'); }, /** * Returns the current res_id, wrapped in a list. This is only used by the - * sidebar (and the debugmanager) + * action menus (and the debugmanager) * * @override * @@ -142,35 +139,34 @@ var FormController = BasicController.extend({ * have to use them instead of the standard buttons. * * @override method from AbstractController - * @param {jQueryElement} $node + * @param {jQuery} [$node] */ renderButtons: function ($node) { - var $footer = this.footerToButtons ? this.renderer.$('footer') : null; + var $footer = this.footerToButtons ? this.renderer.$el && this.renderer.$('footer') : null; var mustRenderFooterButtons = $footer && $footer.length; - if (!this.defaultButtons && !mustRenderFooterButtons) { - return; + if ((this.defaultButtons && !this.$buttons) || mustRenderFooterButtons) { + this.$buttons = $('<div/>'); + if (mustRenderFooterButtons) { + this.$buttons.append($footer); + } else { + this.$buttons.append(qweb.render("FormView.buttons", {widget: this})); + this.$buttons.on('click', '.o_form_button_edit', this._onEdit.bind(this)); + this.$buttons.on('click', '.o_form_button_create', this._onCreate.bind(this)); + this.$buttons.on('click', '.o_form_button_save', this._onSave.bind(this)); + this.$buttons.on('click', '.o_form_button_cancel', this._onDiscard.bind(this)); + this._assignSaveCancelKeyboardBehavior(this.$buttons.find('.o_form_buttons_edit')); + this.$buttons.find('.o_form_buttons_edit').tooltip({ + delay: {show: 200, hide:0}, + title: function(){ + return qweb.render('SaveCancelButton.tooltip'); + }, + trigger: 'manual', + }); + } } - this.$buttons = $('<div/>'); - if (mustRenderFooterButtons) { - this.$buttons.append($footer); - - } else { - this.$buttons.append(qweb.render("FormView.buttons", {widget: this})); - this.$buttons.on('click', '.o_form_button_edit', this._onEdit.bind(this)); - this.$buttons.on('click', '.o_form_button_create', this._onCreate.bind(this)); - this.$buttons.on('click', '.o_form_button_save', this._onSave.bind(this)); - this.$buttons.on('click', '.o_form_button_cancel', this._onDiscard.bind(this)); - this._assignSaveCancelKeyboardBehavior(this.$buttons.find('.o_form_buttons_edit')); - this.$buttons.find('.o_form_buttons_edit').tooltip({ - delay: {show: 200, hide:0}, - title: function(){ - return qweb.render('SaveCancelButton.tooltip'); - }, - trigger: 'manual', - }); - this._updateButtons(); + if (this.$buttons && $node) { + this.$buttons.appendTo($node); } - this.$buttons.appendTo($node); }, /** * The form view has to prevent a click on the pager if the form is dirty @@ -180,71 +176,58 @@ var FormController = BasicController.extend({ * @param {Object} options * @returns {Promise} */ - renderPager: function ($node, options) { - options = _.extend({}, options, { + _getPagingInfo: function () { + // Only display the pager if we are not on a new record. + if (this.model.isNew(this.handle)) { + return null; + } + return Object.assign(this._super(...arguments), { validate: this.canBeDiscarded.bind(this), }); - return this._super($node, options); }, /** - * Instantiate and render the sidebar if a sidebar is requested - * Sets this.sidebar - * @param {jQuery} [$node] a jQuery node where the sidebar should be - * inserted - * @return {Promise} + * @override + * @private **/ - renderSidebar: function ($node) { - var self = this; - if (this.hasSidebar) { - var otherItems = []; - const activeField = this.model.getActiveField(this.initialState); - const activeFieldValue = this.initialState.data[activeField]; - if (this.archiveEnabled && activeField) { - var classname = "o_sidebar_item_archive" + (activeFieldValue ? "" : " o_hidden") - otherItems.push({ - label: _t("Archive"), - callback: function () { - Dialog.confirm(self, _t("Are you sure that you want to archive this record?"), { - confirm_callback: self._toggleArchiveState.bind(self, true), + _getActionMenuItems: function () { + if (!this.hasActionMenus || this.mode === 'edit') { + return null; + } + const props = this._super(...arguments); + const activeField = this.model.getActiveField(this.initialState); + const otherActionItems = []; + if (this.archiveEnabled && activeField) { + if (this.initialState.data[activeField]) { + otherActionItems.push({ + description: _t("Archive"), + callback: () => { + Dialog.confirm(this, _t("Are you sure that you want to archive this record?"), { + confirm_callback: () => this._toggleArchiveState(true), }); }, - classname: classname, - }); - classname = "o_sidebar_item_unarchive" + (activeFieldValue ? " o_hidden" : "") - otherItems.push({ - label: _t("Unarchive"), - callback: this._toggleArchiveState.bind(this, false), - classname: classname, - }); - } - if (this.is_action_enabled('delete')) { - otherItems.push({ - label: _t('Delete'), - callback: this._onDeleteRecord.bind(this), }); - } - if (this.is_action_enabled('create') && this.is_action_enabled('duplicate')) { - otherItems.push({ - label: _t('Duplicate'), - callback: this._onDuplicateRecord.bind(this), + } else { + otherActionItems.push({ + description: _t("Unarchive"), + callback: () => this._toggleArchiveState(false), }); } - this.sidebar = new Sidebar(this, { - editable: this.is_action_enabled('edit'), - viewType: 'form', - env: { - context: this.model.get(this.handle).getContext(), - activeIds: this.getSelectedIds(), - model: this.modelName, - }, - actions: _.extend(this.toolbarActions, {other: otherItems}), + } + if (this.activeActions.create && this.activeActions.duplicate) { + otherActionItems.push({ + description: _t("Duplicate"), + callback: () => this._onDuplicateRecord(this), }); - return this.sidebar.appendTo($node).then(function() { - // Show or hide the sidebar according to the view mode - self._updateSidebar(); + } + if (this.activeActions.delete) { + otherActionItems.push({ + description: _t("Delete"), + callback: () => this._onDeleteRecord(this), }); } - return Promise.resolve(); + return Object.assign(props, { + items: Object.assign(this.toolbarActions, { other: otherActionItems }), + }); }, /** * Show a warning message if the user modified a translated field. For each @@ -252,32 +235,29 @@ var FormController = BasicController.extend({ * * @override */ - saveRecord: function () { - var self = this; - return this._super.apply(this, arguments).then(function (changedFields) { - // the title could have been changed - self._setTitle(self.getTitle()); - self._updateEnv(); + saveRecord: async function () { + const changedFields = await this._super(...arguments); + // the title could have been changed + this._updateControlPanel(); - if (_t.database.multi_lang && changedFields.length) { - // need to make sure changed fields that should be translated - // are displayed with an alert - var fields = self.renderer.state.fields; - var data = self.renderer.state.data; - var alertFields = {}; - for (var k = 0; k < changedFields.length; k++) { - var field = fields[changedFields[k]]; - var fieldData = data[changedFields[k]]; - if (field.translate && fieldData) { - alertFields[changedFields[k]] = field; - } - } - if (!_.isEmpty(alertFields)) { - self.renderer.updateAlertFields(alertFields); + if (_t.database.multi_lang && changedFields.length) { + // need to make sure changed fields that should be translated + // are displayed with an alert + var fields = this.renderer.state.fields; + var data = this.renderer.state.data; + var alertFields = {}; + for (var k = 0; k < changedFields.length; k++) { + var field = fields[changedFields[k]]; + var fieldData = data[changedFields[k]]; + if (field.translate && fieldData) { + alertFields[changedFields[k]] = field; } } - return changedFields; - }); + if (!_.isEmpty(alertFields)) { + this.renderer.updateAlertFields(alertFields); + } + } + return changedFields; }, /** * Overrides to force the viewType to 'form', so that we ensure that the @@ -285,12 +265,32 @@ var FormController = BasicController.extend({ * * @override */ - update: function (params, options) { + update: async function (params, options) { if ('currentId' in params && !params.currentId) { this.mode = 'edit'; // if there is no record, we are in 'edit' mode } params = _.extend({viewType: 'form', mode: this.mode}, params); - return this._super(params, options); + await this._super(params, options); + this.autofocus(); + }, + /** + * @override + */ + updateButtons: function () { + if (!this.$buttons) { + return; + } + if (this.footerToButtons) { + var $footer = this.renderer.$el && this.renderer.$('footer'); + if ($footer && $footer.length) { + this.$buttons.empty().append($footer); + } + } + var edit_mode = (this.mode === 'edit'); + this.$buttons.find('.o_form_buttons_edit') + .toggleClass('o_hidden', !edit_mode); + this.$buttons.find('.o_form_buttons_view') + .toggleClass('o_hidden', edit_mode); }, //-------------------------------------------------------------------------- @@ -413,15 +413,6 @@ var FormController = BasicController.extend({ this.renderer.enableButtons(); }, /** - * Only display the pager if we are not on a new record. - * - * @override - * @private - */ - _isPagerVisible: function () { - return !this.model.isNew(this.handle); - }, - /** * Hook method, called when record(s) has been deleted. * * @override @@ -464,74 +455,6 @@ var FormController = BasicController.extend({ } return this._super.apply(this, arguments); }, - /** - * Updates the controller's title according to the new state - * - * @override - * @private - * @param {Object} state - * @returns {Promise} - */ - _update: function () { - var self = this; - - return this._super.apply(this, arguments).then(function() { - var title = self.getTitle(); - self._setTitle(title); - self._updateButtons(); - self._updateSidebar(); - self.autofocus(); - }); - }, - /** - * @private - */ - _updateButtons: function () { - if (this.$buttons) { - if (this.footerToButtons) { - var $footer = this.renderer.$('footer'); - if ($footer.length) { - this.$buttons.empty().append($footer); - } - } - var edit_mode = (this.mode === 'edit'); - this.$buttons.find('.o_form_buttons_edit') - .toggleClass('o_hidden', !edit_mode); - this.$buttons.find('.o_form_buttons_view') - .toggleClass('o_hidden', edit_mode); - } - }, - /** - * Show or hide the sidebar according to the actual_mode - * @private - */ - _updateSidebar: function () { - if (this.sidebar) { - this.sidebar.do_toggle(this.mode === 'readonly'); - // Hide/Show Archive/Unarchive dropdown items - // We could have toggled the o_hidden class on the - // item theirselves, but the items are redrawed - // at each update, based on the initial definition - var archive_item = _.find(this.sidebar.items.other, function(item) { - return item.classname && item.classname.includes('o_sidebar_item_archive') - }) - var unarchive_item = _.find(this.sidebar.items.other, function(item) { - return item.classname && item.classname.includes('o_sidebar_item_unarchive') - }) - const state = this.model.get(this.handle, {raw: true}); - const activeField = this.model.getActiveField(state); - const activeFieldValue = this.renderer.state.data[activeField]; - if (archive_item && unarchive_item) { - if (activeFieldValue) { - archive_item.classname = 'o_sidebar_item_archive'; - unarchive_item.classname = 'o_sidebar_item_unarchive o_hidden'; - } else { - archive_item.classname = 'o_sidebar_item_archive o_hidden'; - unarchive_item.classname = 'o_sidebar_item_unarchive'; - } - } - } - }, //-------------------------------------------------------------------------- // Handlers @@ -623,18 +546,15 @@ var FormController = BasicController.extend({ this._discardChanges(); }, /** - * Called when the user clicks on 'Duplicate Record' in the sidebar + * Called when the user clicks on 'Duplicate Record' in the action menus * * @private */ - _onDuplicateRecord: function () { - var self = this; - this.model.duplicateRecord(this.handle) - .then(function (handle) { - self.handle = handle; - self._updateEnv(); - self._setMode('edit'); - }); + _onDuplicateRecord: async function () { + const handle = await this.model.duplicateRecord(this.handle); + this.handle = handle; + this._updateControlPanel(); + this._setMode('edit'); }, /** * Called when the user wants to edit the current record -> @see _setMode @@ -777,7 +697,7 @@ var FormController = BasicController.extend({ }); }, /** - * Called when clicking on 'Archive' or 'Unarchive' in the sidebar. + * Called when clicking on 'Archive' or 'Unarchive' in the action menus. * * @private * @param {boolean} archive diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index f3c663891b0..1af48aabf73 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -49,9 +49,6 @@ var FormRenderer = BasicRenderer.extend({ */ on_attach_callback: function () { this._isInDom = true; - _.forEach(this.allFieldWidgets, function (widgets){ - _.invoke(widgets, 'on_attach_callback'); - }); this._super.apply(this, arguments); }, /** diff --git a/addons/web/static/src/js/views/form/form_view.js b/addons/web/static/src/js/views/form/form_view.js index 13d73cf37c2..9d13fd36b16 100644 --- a/addons/web/static/src/js/views/form/form_view.js +++ b/addons/web/static/src/js/views/form/form_view.js @@ -25,19 +25,19 @@ var FormView = BasicView.extend({ * @override */ init: function (viewInfo, params) { - var hasSidebar = params.hasSidebar; + var hasActionMenus = params.hasActionMenus; this._super.apply(this, arguments); var mode = params.mode || (params.currentId ? 'readonly' : 'edit'); this.loadParams.type = 'record'; // this is kind of strange, but the param object is modified by - // AbstractView, so we only need to use its hasSidebar value if it was + // AbstractView, so we only need to use its hasActionMenus value if it was // not already present in the beginning of this method - if (hasSidebar === undefined) { - hasSidebar = params.hasSidebar; + if (hasActionMenus === undefined) { + hasActionMenus = params.hasActionMenus; } - this.controllerParams.hasSidebar = hasSidebar; + this.controllerParams.hasActionMenus = hasActionMenus; this.controllerParams.disableAutofocus = params.disable_autofocus; this.controllerParams.toolbarActions = viewInfo.toolbar; this.controllerParams.footerToButtons = params.footerToButtons; @@ -75,7 +75,7 @@ var FormView = BasicView.extend({ params.withControlPanel = !(inDialog || inline); params.footerToButtons = inDialog; params.hasSearchView = inDialog ? false : params.hasSearchView; - params.hasSidebar = !inDialog && !inline; + params.hasActionMenus = !inDialog && !inline; params.searchMenuTypes = inDialog ? [] : params.searchMenuTypes; if (inDialog || inline || fullscreen) { params.mode = 'edit'; |
