diff options
| author | Aaron Bohy <aab@odoo.com> | 2015-01-21 16:36:23 +0100 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2015-03-20 16:17:06 +0100 |
| commit | 53a9f6c081d0d91c99d8f035fd09d813a16172e8 (patch) | |
| tree | a4da311c1bda804c4800b4b272a316320ef9c25b /addons/web/static | |
| parent | db592efca282d12f6fcef38a13dc2cbff31522b8 (diff) | |
[IMP] Web et al.: ControlPanel extracted from ViewManager
The ControlPanel is still instantiated by the ViewManager.
Changes details:
* web: views.js:
Code related to views header is extracted from the ViewManager
to a new Widget named ControlPanel.
Also uses the headless flag to tell the inner view not to put
its buttons (use case: kanban) or pager (use case: list) in the
header as it is hidden.
* web: view_form.js, base.xml:
Uses the headless flag at initialization of the One2ManyViewManager
widget instead of extending the ViewManager template (which doesn't
handle the header anymore).
* web: view_list.js:
Test on this.options.$pager instead of this.options.$buttons
when dealing with pager.
Note: the behavior for list view is unchanged and has a bug.
If there are more then 80 records to display, only the 80th
first are display, and as there is no pager, there is no way
to see the remaining ones. A fix for this would be to use a
light ControlPanel in One2Many views as well. With this,
there won't be duplicated .oe-'view'-buttons/sidebar/pager
anymore.
* web: view_graph.js, view_pivot.js:
Only render buttons in non-headless mode
* web_dashboard: dashboard.js:
Fix some references that were broken with ControlPanel extraction
* web_view_editor: web_view_editor.js:
Extend ControlPanel instead of ViewManager
* Changes in selector of ControlPanel elements in several addons:
* base_import
* mail
* web
Diffstat (limited to 'addons/web/static')
| -rw-r--r-- | addons/web/static/src/css/base.css | 85 | ||||
| -rw-r--r-- | addons/web/static/src/css/base.sass | 30 | ||||
| -rw-r--r-- | addons/web/static/src/js/action_manager.js | 3 | ||||
| -rw-r--r-- | addons/web/static/src/js/control_panel.js | 375 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_manager.js | 358 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form_relational_widgets.js | 5 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/graph_view.js | 15 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/list_view.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/pivot_view.js | 17 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 44 |
10 files changed, 517 insertions, 417 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index c71c340dd04..5626ccec148 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -967,7 +967,7 @@ .openerp .oe-view-manager .oe-view-manager-debug { margin-right: 5px; } -.openerp .oe-view-manager-header { +.openerp .oe-control-panel { background-color: #f0eeee; border-bottom: 1px solid #afafb6; -webkit-flex-shrink: 0; @@ -977,141 +977,140 @@ -moz-user-select: none; user-select: none; } -.openerp .oe-view-manager-header .oe-button-column { +.openerp .oe-control-panel .oe-button-column { height: 30px; } -.openerp .oe-view-manager-header .dropdown-menu li { +.openerp .oe-control-panel .dropdown-menu li { position: relative; } -.openerp .oe-view-manager-header .dropdown-menu li a { +.openerp .oe-control-panel .dropdown-menu li a { padding: 3px 25px; } -.openerp .oe-view-manager-header .dropdown-menu .oe_searchview_custom_public a:after, .openerp .oe-view-manager-header .dropdown-menu .oe-share-filter:after { +.openerp .oe-control-panel .dropdown-menu .oe_searchview_custom_public a:after, .openerp .oe-control-panel .dropdown-menu .oe-share-filter:after { font-family: FontAwesome; content: ""; color: #666; margin-left: 3px; } -.openerp .oe-view-manager-header .selected { +.openerp .oe-control-panel .selected { display: block; } -.openerp .oe-view-manager-header .selected a { +.openerp .oe-control-panel .selected a { font-weight: bold; } -.openerp .oe-view-manager-header .selected a:before { +.openerp .oe-control-panel .selected a:before { font-family: FontAwesome; position: absolute; left: 6px; top: 3px; content: ""; } -.openerp .oe-view-manager-header .oe-right-toolbar { +.openerp .oe-control-panel .oe-right-toolbar { float: right; } -.openerp .oe-view-manager-header .oe-right-toolbar > div { +.openerp .oe-control-panel .oe-right-toolbar > div { display: inline-block; } -.openerp .oe-view-manager-header .row:first-child { +.openerp .oe-control-panel .row:first-child { padding-top: 3px; padding-bottom: 3px; } -.openerp .oe-view-manager-header .row:last-child { +.openerp .oe-control-panel .row:last-child { padding-bottom: 10px; } -.openerp .oe-view-manager-header .oe_tag { +.openerp .oe-control-panel .oe_tag { -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; } -.openerp .oe-view-manager-header .oe-view-title { +.openerp .oe-control-panel .oe-view-title { font-size: 18px; padding-left: 0; margin: 0; background-color: #f0eeee; } -.openerp .oe-view-manager-header .oe-view-title li { +.openerp .oe-control-panel .oe-view-title li { -moz-user-select: initial; -webkit-user-select: initial; user-select: initial; } -.openerp .oe-view-manager-header .oe-view-manager-search-view { +.openerp .oe-control-panel .oe-cp-search-view { padding-top: 5px; } -.openerp .oe-view-manager-header .oe-view-manager-switch button { +.openerp .oe-control-panel .oe-cp-switch-buttons button { width: 34px; } -.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-kanban:before { +.openerp .oe-control-panel .oe-cp-switch-buttons .oe-cp-switch-kanban:before { content: ""; } -.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-list:before { +.openerp .oe-control-panel .oe-cp-switch-buttons .oe-cp-switch-list:before { content: ""; } -.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-form:before { +.openerp .oe-control-panel .oe-cp-switch-buttons .oe-cp-switch-form:before { content: ""; } -.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-graph:before { +.openerp .oe-control-panel .oe-cp-switch-buttons .oe-cp-switch-graph:before { content: ""; } -.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-calendar:before { +.openerp .oe-control-panel .oe-cp-switch-buttons .oe-cp-switch-calendar:before { content: ""; } -.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-gantt:before { +.openerp .oe-control-panel .oe-cp-switch-buttons .oe-cp-switch-gantt:before { content: ""; } -.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-pivot:before { +.openerp .oe-control-panel .oe-cp-switch-buttons .oe-cp-switch-pivot:before { content: ""; } -.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-tree:before { +.openerp .oe-control-panel .oe-cp-switch-buttons .oe-cp-switch-tree:before { content: ""; } -.openerp .oe-view-manager-header .oe-view-manager-buttons { +.openerp .oe-control-panel .oe-cp-buttons { display: inline-block; } -.openerp .oe-view-manager-header .oe-view-manager-buttons > div { +.openerp .oe-control-panel .oe-cp-buttons > div { display: none; } -.openerp .oe-view-manager-header .oe-view-manager-sidebar { +.openerp .oe-control-panel .oe-cp-sidebar { display: inline-block; float: right; } -.openerp .oe-view-manager-header .oe-view-manager-sidebar .oe_form_binary_form { +.openerp .oe-control-panel .oe-cp-sidebar .oe_form_binary_form { cursor: pointer; } -.openerp .oe-view-manager-header .oe-view-manager-sidebar .oe_form_binary_form span { +.openerp .oe-control-panel .oe-cp-sidebar .oe_form_binary_form span { padding: 3px 20px; } -.openerp .oe-view-manager-header .oe-view-manager-sidebar .oe_form_binary_form input.oe_form_binary_file { +.openerp .oe-control-panel .oe-cp-sidebar .oe_form_binary_form input.oe_form_binary_file { width: 100%; } -.openerp .oe-view-manager-header .oe-view-manager-sidebar .oe_form_binary_form:hover { +.openerp .oe-control-panel .oe-cp-sidebar .oe_form_binary_form:hover { background-color: #f5f5f5; } -.openerp .oe-view-manager-header .oe-view-manager-sidebar .oe_file_attachment { +.openerp .oe-control-panel .oe-cp-sidebar .oe_file_attachment { padding: 3px 20px; display: inline-block; } -.openerp .oe-view-manager-header .oe-view-manager-sidebar .oe_sidebar_delete_item { +.openerp .oe-control-panel .oe-cp-sidebar .oe_sidebar_delete_item { padding: 0; - position: absolute; - right: 10px; + display: inline-block; } -.openerp .oe-view-manager-header .oe-view-manager-sidebar .dropdown-menu li a { +.openerp .oe-control-panel .oe-cp-sidebar .dropdown-menu li a { width: 100%; } -.openerp .oe-view-manager-header .oe_form_buttons { +.openerp .oe-control-panel .oe_form_buttons { padding: 0; } -.openerp .oe-view-manager-header .oe_form_buttons_view > button { +.openerp .oe-control-panel .oe_form_buttons_view > button { float: left; } -.openerp .oe-view-manager-header .oe_form_buttons_view > button:last-child { +.openerp .oe-control-panel .oe_form_buttons_view > button:last-child { float: right; margin-left: 4px; } -.openerp .oe-view-manager-header .oe-pager-buttons { +.openerp .oe-control-panel .oe-pager-buttons { min-height: 30px; } -.openerp .oe_view_manager_inline > .oe-view-manager-header, .openerp .oe_view_manager_inlineview > .oe-view-manager-header { +.openerp .oe_view_manager_inline > .oe-control-panel-content, .openerp .oe_view_manager_inlineview > .oe-control-panel-content { display: none; } .openerp .o-modal-header > div { @@ -3094,7 +3093,7 @@ body.oe_single_form .oe_single_form_container { .openerp .oe_application .oe_form_sheet .oe_list, .openerp .oe_application .oe_form_sheetbg .oe_list { overflow-x: visible; } - .openerp .oe_view_manager_current > .oe_view_manager_header { + .openerp .oe-control-panel { border: 0px !important; box-shadow: 0px 0px 0px; } diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 1432352aa7e..63ef0cd5bdb 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -840,7 +840,7 @@ $sheet-padding: 16px display: block .oe-view-manager-debug margin-right: 5px - .oe-view-manager-header + .oe-control-panel background-color: rgb(240, 238, 238) border-bottom: 1px solid #afafb6 -webkit-flex-shrink: 0 @@ -891,32 +891,32 @@ $sheet-padding: 16px -moz-user-select: initial -webkit-user-select: initial user-select: initial - .oe-view-manager-search-view + .oe-cp-search-view padding-top: 5px - .oe-view-manager-switch + .oe-cp-switch-buttons button width: 34px - .oe-vm-switch-kanban:before + .oe-cp-switch-kanban:before content: "\f009" - .oe-vm-switch-list:before + .oe-cp-switch-list:before content: "" - .oe-vm-switch-form:before + .oe-cp-switch-form:before content: "\f044" - .oe-vm-switch-graph:before + .oe-cp-switch-graph:before content: "\f080" - .oe-vm-switch-calendar:before + .oe-cp-switch-calendar:before content: "\f073" - .oe-vm-switch-gantt:before + .oe-cp-switch-gantt:before content: "\f0ae" - .oe-vm-switch-pivot:before + .oe-cp-switch-pivot:before content: "\f0ce" - .oe-vm-switch-tree:before + .oe-cp-switch-tree:before content: "\f036" - .oe-view-manager-buttons + .oe-cp-buttons display: inline-block > div display: none - .oe-view-manager-sidebar + .oe-cp-sidebar display: inline-block float: right .oe_form_binary_form @@ -951,7 +951,7 @@ $sheet-padding: 16px .oe-pager-buttons min-height: 30px .oe_view_manager_inline, .oe_view_manager_inlineview - > .oe-view-manager-header + > .oe-control-panel-content display: none // }}} @@ -2549,7 +2549,7 @@ body.oe_single_form box-shadow: 0px 0px 0px .oe_list overflow-x: visible - .oe_view_manager_current > .oe_view_manager_header + .oe-control-panel border: 0px !important box-shadow: 0px 0px 0px text-shadow: none diff --git a/addons/web/static/src/js/action_manager.js b/addons/web/static/src/js/action_manager.js index efc617c4af2..61686dc4e7e 100644 --- a/addons/web/static/src/js/action_manager.js +++ b/addons/web/static/src/js/action_manager.js @@ -142,9 +142,6 @@ var ActionManager = Widget.extend({ w.destroy(); }); self.inner_widget = _.last(self.widgets); - if (self.inner_widget.display_breadcrumbs) { - self.inner_widget.display_breadcrumbs(); - } if (self.inner_widget.do_show) { self.inner_widget.do_show(); } diff --git a/addons/web/static/src/js/control_panel.js b/addons/web/static/src/js/control_panel.js new file mode 100644 index 00000000000..d5c016522f5 --- /dev/null +++ b/addons/web/static/src/js/control_panel.js @@ -0,0 +1,375 @@ +odoo.define('web.ControlPanel', function (require) { +"use strict"; + +var core = require('web.core'); +var Dialog = require('web.Dialog'); +var formats = require('web.formats'); +var framework = require('web.framework'); +var Model = require('web.Model'); +var pyeval = require('web.pyeval'); +var SearchView = require('web.SearchView'); +var utils = require('web.utils'); +var Widget = require('web.Widget'); + +var ControlPanel = Widget.extend({ + template: 'ControlPanel', + events: { + "click .oe_debug_view": "on_debug_changed", + "click .oe-cp-switch-buttons button": "on_switch_buttons_click", + }, + /** + * @param {String} [template] the QWeb template to render the ControlPanel. + * By default, the template 'ControlPanel' will be used + */ + init: function(parent, template) { + this._super(parent); + if (template) { + this.template = template; + } + + this.view_manager = parent; + this.action_manager = this.view_manager.action_manager; + this.action = this.view_manager.action; + this.dataset = this.view_manager.dataset; + this.active_view = this.view_manager.active_view; + this.views = this.view_manager.views; + this.flags = this.view_manager.flags; + this.title = this.view_manager.title; // needed for Favorites of searchview + this.view_order = this.view_manager.view_order; + this.multiple_views = (this.view_order.length > 1); + }, + start: function() { + var self = this; + + // Retrieve control panel elements + this.$control_panel = this.$('.oe-control-panel-content'); + this.$breadcrumbs = this.$('.oe-view-title'); + this.$switch_buttons = this.$('.oe-cp-switch-buttons button'); + this.$title_col = this.$control_panel.find('.oe-cp-title'); + this.$search_col = this.$control_panel.find('.oe-cp-search-view'); + // AAB: Use sidebar and pager of the ControlPanel only if it is displayed, otherwise set them + // to undefined to that the view uses its own elements to sidebar and pager, as follows: + // this.$sidebar = !this.flags.headless && this.flags.sidebar ? this.$('.oe-cp-sidebar') : undefined, + // this.$pager = !this.flags.headless ? this.$('.oe-cp-pager') : undefined; + // But rather use the following definition to keep behavior as it is for now (i.e. it does not + // display the pager in one2many list views) + this.$sidebar = this.flags.sidebar ? this.$('.oe-cp-sidebar') : undefined; + this.$pager = this.$('.oe-cp-pager'); + + // Hide the ControlPanel in headless mode + if (this.flags.headless) { + this.$control_panel.hide(); + } + + _.each(this.views, function (view) { + // Expose control panel elements to the views so that they can insert stuff in them + view.options = _.extend(view.options, { + $buttons : !self.flags.headless ? self.$('.oe-' + view.type + '-buttons') : undefined, + $sidebar : self.$sidebar, + $pager : self.$pager, + }, self.flags, self.flags[view.type], view.options); + // Show $buttons as views will put their own buttons inside it and show/hide them + if (view.options.$buttons) view.options.$buttons.show(); + self.$('.oe-cp-switch-' + view.type).tooltip(); + }); + + // Create the searchview + this.search_view_loaded = this.setup_search_view(); + + return this._super(); + }, + /** + * Triggers an event when switch-buttons are clicked on + */ + on_switch_buttons_click: function(event) { + var view_type = $(event.target).data('view-type'); + this.trigger('switch_view', view_type); + }, + /** + * Updates its status according to the active_view + */ + update: function(active_view) { + this.active_view = active_view; + + this.update_search_view(); + this.update_breadcrumbs(); + this.render_debug_view(); + + // Update switch-buttons + this.$switch_buttons.removeClass('active'); + this.$('.oe-cp-switch-' + this.active_view.type).addClass('active'); + }, + update_breadcrumbs: function () { + var self = this; + if (!this.action_manager) return; + var breadcrumbs = this.action_manager.get_breadcrumbs(); + if (!breadcrumbs.length) return; + + var $breadcrumbs = breadcrumbs.map(function (bc, index) { + return make_breadcrumb(bc, index === breadcrumbs.length - 1); + }); + + this.$breadcrumbs + .empty() + .append($breadcrumbs); + + function make_breadcrumb (bc, is_last) { + var $bc = $('<li>') + .append(is_last ? bc.title : $('<a>').text(bc.title)) + .toggleClass('active', is_last); + if (!is_last) { + $bc.click(function () { + self.action_manager.select_widget(bc.widget, bc.index); + }); + } + return $bc; + } + }, + /** + * Sets up the search view. + * + * @returns {jQuery.Deferred} search view startup deferred + */ + setup_search_view: function() { + if (this.searchview) { + this.searchview.destroy(); + } + + var view_id = (this.action && this.action.search_view_id && this.action.search_view_id[0]) || false; + + var search_defaults = {}; + + var context = this.action ? this.action.context : []; + _.each(context, function (value, key) { + var match = /^search_default_(.*)$/.exec(key); + if (match) { + search_defaults[match[1]] = value; + } + }); + + var options = { + hidden: this.flags.search_view === false, + disable_custom_filters: this.flags.search_disable_custom_filters, + $buttons: this.$('.oe-search-options'), + action: this.action, + }; + this.searchview = new SearchView(this, this.dataset, view_id, search_defaults, options); + + this.searchview.on('search_data', this, this.search.bind(this)); + return this.searchview.appendTo(this.$(".oe-cp-search-view:first")); + }, + update_search_view: function() { + if (this.searchview) { + var is_hidden = this.active_view.controller.searchable === false; + this.searchview.toggle_visibility(!is_hidden); + this.$title_col.toggleClass('col-md-6', !is_hidden).toggleClass('col-md-12', is_hidden); + this.$search_col.toggle(!is_hidden); + } + }, + search: function(domains, contexts, groupbys) { + var self = this, + controller = this.active_view.controller, + action_context = this.action.context || {}, + view_context = controller.get_context(); + pyeval.eval_domains_and_contexts({ + domains: [this.action.domain || []].concat(domains || []), + contexts: [action_context, view_context].concat(contexts || []), + group_by_seq: groupbys || [] + }).done(function (results) { + if (results.error) { + self.active_search.resolve(); + throw new Error( + _.str.sprintf(_t("Failed to evaluate search criterions")+": \n%s", + JSON.stringify(results.error))); + } + self.dataset._model = new Model( + self.dataset.model, results.context, results.domain); + var groupby = results.group_by.length ? + results.group_by : + action_context.group_by; + if (_.isString(groupby)) { + groupby = [groupby]; + } + if (!controller.grouped && !_.isEmpty(groupby)){ + self.dataset.set_sort([]); + } + $.when(controller.do_search(results.domain, results.context, groupby || [])).then(function() { + self.active_search.resolve(); + }); + }); + }, + activate_search: function(view_created_def) { + this.active_search = $.Deferred(); + if (this.searchview && + this.flags.auto_search && + this.active_view.controller.searchable !== false) { + $.when(this.search_view_loaded,view_created_def).done(this.searchview.do_search); + } else { + this.active_search.resolve(); + } + return this.active_search; + }, + on_debug_changed: function (evt) { + var self = this, + params = $(evt.target).data(), + val = params.action, + current_view = this.active_view.controller; + switch (val) { + case 'fvg': + var dialog = new Dialog(this, { title: _t("Fields View Get") }).open(); + $('<pre>').text(utils.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$el); + break; + case 'tests': + this.do_action({ + name: _t("JS Tests"), + target: 'new', + type : 'ir.actions.act_url', + url: '/web/tests?mod=*' + }); + break; + case 'get_metadata': + var ids = current_view.get_selected_ids(); + if (ids.length === 1) { + this.dataset.call('get_metadata', [ids]).done(function(result) { + var dialog = new Dialog(this, { + title: _.str.sprintf(_t("Metadata (%s)"), self.dataset.model), + size: 'medium', + buttons: { + Ok: function() { this.parents('.modal').modal('hide');} + }, + }, QWeb.render('ViewManagerDebugViewLog', { + perm : result[0], + format : formats.format_value + })).open(); + }); + } + break; + case 'toggle_layout_outline': + current_view.rendering_engine.toggle_layout_debugging(); + break; + case 'set_defaults': + current_view.open_defaults_dialog(); + break; + case 'translate': + this.do_action({ + name: _t("Technical Translation"), + res_model : 'ir.translation', + domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']], + views: [[false, 'list'], [false, 'form']], + type : 'ir.actions.act_window', + view_type : "list", + view_mode : "list" + }); + break; + case 'fields': + this.dataset.call('fields_get', [false, {}]).done(function (fields) { + var $root = $('<dl>'); + _(fields).each(function (attributes, name) { + $root.append($('<dt>').append($('<h4>').text(name))); + var $attrs = $('<dl>').appendTo($('<dd>').appendTo($root)); + _(attributes).each(function (def, name) { + if (def instanceof Object) { + def = JSON.stringify(def); + } + $attrs + .append($('<dt>').text(name)) + .append($('<dd style="white-space: pre-wrap;">').text(def)); + }); + }); + new Dialog(self, { + title: _.str.sprintf(_t("Model %s fields"), + self.dataset.model), + buttons: { + Ok: function() { this.parents('.modal').modal('hide');} + }, + }, $root).open(); + }); + break; + case 'edit_workflow': + return this.do_action({ + res_model : 'workflow', + name: _t('Edit Workflow'), + domain : [['osv', '=', this.dataset.model]], + views: [[false, 'list'], [false, 'form'], [false, 'diagram']], + type : 'ir.actions.act_window', + view_type : 'list', + view_mode : 'list' + }); + case 'edit': + this.do_edit_resource(params.model, params.id, evt.target.text); + break; + case 'manage_filters': + this.do_action({ + res_model: 'ir.filters', + name: _t('Manage Filters'), + views: [[false, 'list'], [false, 'form']], + type: 'ir.actions.act_window', + context: { + search_default_my_filters: true, + search_default_model_id: this.dataset.model + } + }); + break; + case 'print_workflow': + if (current_view.get_selected_ids && current_view.get_selected_ids().length == 1) { + framework.blockUI(); + var action = { + context: { active_ids: current_view.get_selected_ids() }, + report_name: "workflow.instance.graph", + datas: { + model: this.dataset.model, + id: current_view.get_selected_ids()[0], + nested: true, + } + }; + this.session.get_file({ + url: '/web/report', + data: {action: JSON.stringify(action)}, + complete: framework.unblockUI + }); + } else { + self.do_warn("Warning", "No record selected."); + } + break; + case 'leave_debug': + window.location.search="?"; + break; + default: + if (val) { + console.warn("No debug handler for ", val); + } + } + }, + do_edit_resource: function(model, id, name) { + this.do_action({ + res_model : model, + res_id : id, + name: name, + type : 'ir.actions.act_window', + view_type : 'form', + view_mode : 'form', + views : [[false, 'form']], + target : 'new', + flags : { + action_buttons : true, + headless: true, + } + }); + }, + /** + * Renders the debug dropdown according to the active_view + */ + render_debug_view: function() { + var self = this; + if (self.session.debug) { + self.$('.oe_debug_view').html(QWeb.render('ViewManagerDebug', { + view: self.active_view.controller, + widget: self, + })); + } + }, +}); + +return ControlPanel; + +}); diff --git a/addons/web/static/src/js/view_manager.js b/addons/web/static/src/js/view_manager.js index 869ba4f1b0c..0474f0e127b 100644 --- a/addons/web/static/src/js/view_manager.js +++ b/addons/web/static/src/js/view_manager.js @@ -1,6 +1,7 @@ odoo.define('web.ViewManager', function (require) { "use strict"; +var ControlPanel = require('web.ControlPanel'); var core = require('web.core'); var data = require('web.data'); var Dialog = require('web.Dialog'); @@ -43,7 +44,6 @@ var ViewManager = Widget.extend({ } this.action = action; this.action_manager = parent; - this.debug = session.debug; dataset = new data.DataSetSearch(this, action.res_model, action.context, action.domain); if (action.res_id) { dataset.ids.push(action.res_id); @@ -57,12 +57,9 @@ var ViewManager = Widget.extend({ this.flags = flags || {}; this.dataset = dataset; this.view_order = []; - this.url_states = {}; this.views = {}; this.view_stack = []; // used for breadcrumbs this.active_view = null; - this.searchview = null; - this.active_search = null; this.registry = core.view_registry; this.title = this.action && this.action.name; @@ -77,68 +74,61 @@ var ViewManager = Widget.extend({ type: view_type, label: view_label, embedded_view: view.embedded_view, - title: self.action && self.action.name, + title: self.title, button_label: View ? _.str.sprintf(_t('%(view_type)s view'), {'view_type': (view_label || view_type)}) : (void 'nope'), }; self.view_order.push(view_descr); self.views[view_type] = view_descr; }); - this.multiple_views = (self.view_order.length > 1); + + // Instantiate ControlPanel + this.control_panel = new ControlPanel(self); + // Listen to event 'switch_view' trigerred when clicking on switch-buttons + this.control_panel.on('switch_view', this, function(view_type) { + if (view_type === 'form' && this.active_view && this.active_view.type === 'form') { + this._display_view(view_type); + } else { + this.switch_mode(view_type); + } + }); }, /** * @returns {jQuery.Deferred} initial view loading promise */ start: function() { var self = this; - var default_view = this.flags.default_view || this.view_order[0].type, + var default_view = this.get_default_view(), default_options = this.flags[default_view] && this.flags[default_view].options; - if (this.flags.headless) { - this.$('.oe-view-manager-header').hide(); - } this._super(); - var $sidebar = this.flags.sidebar ? this.$('.oe-view-manager-sidebar') : undefined, - $pager = this.$('.oe-view-manager-pager'); - this.$breadcrumbs = this.$('.oe-view-title'); - this.$switch_buttons = this.$('.oe-view-manager-switch button'); - this.$header = this.$('.oe-view-manager-header'); - this.$header_col = this.$header.find('.oe-header-title'); - this.$search_col = this.$header.find('.oe-view-manager-search-view'); - this.$switch_buttons.click(function (event) { - var view_type = $(this).data('view-type'); - if ((view_type === 'form') && (self.active_view.type === 'form')) { - self._display_view(view_type); - } else { - self.switch_mode(view_type); - } - }); var views_ids = {}; _.each(this.views, function (view) { views_ids[view.type] = view.view_id; view.options = _.extend({ - $buttons: self.$('.oe-' + view.type + '-buttons'), - $sidebar : $sidebar, - $pager : $pager, action : self.action, action_views_ids : views_ids, }, self.flags, self.flags[view.type], view.options); view.$container = self.$(".oe-view-manager-view-" + view.type); - - // show options.$buttons as views will put their $buttons inside it - // and call show/hide on them - view.options.$buttons.show(); - self.$('.oe-vm-switch-' + view.type).tooltip(); }); - this.$('.oe_debug_view').click(this.on_debug_changed); + this.$el.addClass("oe_view_manager_" + ((this.action && this.action.target) || 'current')); - this.search_view_loaded = this.setup_search_view(); + // Insert ControlPanel in the DOM + var cp_loaded = this.control_panel.prependTo(this.$el); var main_view_loaded = this.switch_mode(default_view, null, default_options); - return $.when(main_view_loaded, this.search_view_loaded); + return $.when(main_view_loaded, cp_loaded); + }, + /** + * Needed for dashboard.js to add Favorites to Dashboard + */ + get_searchview: function() { + return this.control_panel.searchview; + }, + get_default_view: function() { + return this.flags.default_view || this.view_order[0].type; }, - switch_mode: function(view_type, no_store, view_options) { var self = this, view = this.views[view_type]; @@ -148,7 +138,8 @@ var ViewManager = Widget.extend({ } if ((view_type !== 'form') && (view_type !== 'diagram')) { this.view_stack = []; - } + } + this.view_stack.push(view); // Hide active view (at first rendering, there is no view to hide) @@ -156,86 +147,35 @@ var ViewManager = Widget.extend({ if (this.active_view.controller) this.active_view.controller.do_hide(); if (this.active_view.$container) this.active_view.$container.hide(); } - this.active_view = view; + this.active_view = this.control_panel.active_view = view; if (!view.created) { view.created = this.create_view.bind(this)(view, view_options); } - this.active_search = $.Deferred(); - - if (this.searchview && - this.flags.auto_search && - view.controller.searchable !== false) { - $.when(this.search_view_loaded, view.created).done(this.searchview.do_search); - } else { - this.active_search.resolve(); - } + // Tell the ControlPanel to call do_search on its searchview + var active_search = this.control_panel.activate_search(view.created); - self.update_header(); - return $.when(view.created, this.active_search).done(function () { - self.active_view = view; + return $.when(view.created, active_search).done(function () { self._display_view(view_options); self.trigger('switch_mode', view_type, no_store, view_options); - if (self.debug) { - self.$('.oe_debug_view').html(QWeb.render('ViewManagerDebug', { - view: self.active_view.controller, - view_manager: self, - uid: session.uid, - })); - } }); }, - update_header: function () { - this.$switch_buttons.removeClass('active'); - this.$('.oe-vm-switch-' + this.active_view.type).addClass('active'); - }, _display_view: function (view_options) { var self = this; this.active_view.$container.show(); $.when(this.active_view.controller.do_show(view_options)).done(function () { - if (self.searchview) { - var is_hidden = self.active_view.controller.searchable === false; - self.searchview.toggle_visibility(!is_hidden); - self.$header_col.toggleClass('col-md-6', !is_hidden).toggleClass('col-md-12', is_hidden); - self.$search_col.toggle(!is_hidden); - } - self.display_breadcrumbs(); + // Tell the ControlPanel to update its elemnts + self.control_panel.update(self.active_view); }); }, - display_breadcrumbs: function () { - var self = this; - if (!this.action_manager) return; - var breadcrumbs = this.action_manager.get_breadcrumbs(); - if (!breadcrumbs.length) return; - - var $breadcrumbs = breadcrumbs.map(function (bc, index) { - return make_breadcrumb(bc, index === breadcrumbs.length - 1); - }); - - this.$breadcrumbs - .empty() - .append($breadcrumbs); - - function make_breadcrumb (bc, is_last) { - var $bc = $('<li>') - .append(is_last ? bc.title : $('<a>').text(bc.title)) - .toggleClass('active', is_last); - if (!is_last) { - $bc.click(function () { - self.action_manager.select_widget(bc.widget, bc.index); - }); - } - return $bc; - } - }, create_view: function(view, view_options) { var self = this, - View = this.registry.get(view.type), + View = this.registry.get_object(view.type), options = _.clone(view.options), view_loaded = $.Deferred(); - if (view.type === "form" && ((this.action && (this.action.target === 'new' || this.action.target === 'inline')) - || (view_options && view_options.mode === 'edit'))) { + if (view.type === "form" && ((this.action && (this.action.target === 'new' || this.action.target === 'inline')) || + (view_options && view_options.mode === 'edit'))) { options.initial_mode = 'edit'; } var controller = new View(this, this.dataset, view.view_id, options), @@ -253,14 +193,13 @@ var ViewManager = Widget.extend({ if (self.action_manager) self.action_manager.trigger('history_back'); }); controller.on("change:title", this, function() { - self.display_breadcrumbs(); + self.control_panel.update_breadcrumbs(); }); controller.on('view_loaded', this, function () { view_loaded.resolve(); }); - this.$('.oe-view-manager-pager > span').hide(); return $.when(controller.appendTo($container), view_loaded) - .done(function () { + .done(function () { self.trigger("controller_inited", view.type, controller); }); }, @@ -275,73 +214,6 @@ var ViewManager = Widget.extend({ get_view_id: function(view_type) { return this.views[view_type] && this.views[view_type].view_id || false; }, - /** - * Sets up the current viewmanager's search view. - * - * @param {Number|false} view_id the view to use or false for a default one - * @returns {jQuery.Deferred} search view startup deferred - */ - setup_search_view: function() { - if (this.searchview) { - this.searchview.destroy(); - } - - var view_id = (this.action && this.action.search_view_id && this.action.search_view_id[0]) || false; - - var search_defaults = {}; - - var context = this.action ? this.action.context : []; - _.each(context, function (value, key) { - var match = /^search_default_(.*)$/.exec(key); - if (match) { - search_defaults[match[1]] = value; - } - }); - - - var options = { - hidden: this.flags.search_view === false, - disable_custom_filters: this.flags.search_disable_custom_filters, - $buttons: this.$('.oe-search-options'), - action: this.action, - }; - this.searchview = new SearchView(this, this.dataset, view_id, search_defaults, options); - - this.searchview.on('search_data', this, this.search.bind(this)); - return this.searchview.appendTo(this.$(".oe-view-manager-search-view:first")); - }, - search: function(domains, contexts, groupbys) { - var self = this, - controller = this.active_view.controller, - action_context = this.action.context || {}, - view_context = controller.get_context(); - pyeval.eval_domains_and_contexts({ - domains: [this.action.domain || []].concat(domains || []), - contexts: [action_context, view_context].concat(contexts || []), - group_by_seq: groupbys || [] - }).done(function (results) { - if (results.error) { - self.active_search.resolve(); - throw new Error( - _.str.sprintf(_t("Failed to evaluate search criterions")+": \n%s", - JSON.stringify(results.error))); - } - self.dataset._model = new Model( - self.dataset.model, results.context, results.domain); - var groupby = results.group_by.length - ? results.group_by - : action_context.group_by; - if (_.isString(groupby)) { - groupby = [groupby]; - } - if (!controller.grouped && !_.isEmpty(groupby)){ - self.dataset.set_sort([]); - } - $.when(controller.do_search(results.domain, results.context, groupby || [])).then(function() { - self.active_search.resolve(); - }); - }); - }, do_push_state: function(state) { if (this.action_manager) { state.view_type = this.active_view.type; @@ -356,156 +228,8 @@ var ViewManager = Widget.extend({ // on the new view, after it was initialized, but before it is fully loaded and // in particular, before the do_show method is called. this.switch_mode(state.view_type, true); - } - this.active_view.controller.do_load_state(state, warm); - }, - on_debug_changed: function (evt) { - var self = this, - params = $(evt.target).data(), - val = params.action, - current_view = this.active_view.controller; - switch (val) { - case 'fvg': - var dialog = new Dialog(this, { title: _t("Fields View Get") }).open(); - $('<pre>').text(utils.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$el); - break; - case 'tests': - this.do_action({ - name: _t("JS Tests"), - target: 'new', - type : 'ir.actions.act_url', - url: '/web/tests?mod=*' - }); - break; - case 'get_metadata': - var ids = current_view.get_selected_ids(); - if (ids.length === 1) { - this.dataset.call('get_metadata', [ids]).done(function(result) { - var dialog = new Dialog(this, { - title: _.str.sprintf(_t("Metadata (%s)"), self.dataset.model), - size: 'medium', - buttons: { - Ok: function() { this.parents('.modal').modal('hide');} - }, - }, QWeb.render('ViewManagerDebugViewLog', { - perm : result[0], - format : formats.format_value - })); - dialog.open(); - }); - } - break; - case 'toggle_layout_outline': - current_view.rendering_engine.toggle_layout_debugging(); - break; - case 'set_defaults': - current_view.open_defaults_dialog(); - break; - case 'translate': - this.do_action({ - name: _t("Technical Translation"), - res_model : 'ir.translation', - domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']], - views: [[false, 'list'], [false, 'form']], - type : 'ir.actions.act_window', - view_type : "list", - view_mode : "list" - }); - break; - case 'fields': - this.dataset.call('fields_get', [false, {}]).done(function (fields) { - var $root = $('<dl>'); - _(fields).each(function (attributes, name) { - $root.append($('<dt>').append($('<h4>').text(name))); - var $attrs = $('<dl>').appendTo($('<dd>').appendTo($root)); - _(attributes).each(function (def, name) { - if (def instanceof Object) { - def = JSON.stringify(def); - } - $attrs - .append($('<dt>').text(name)) - .append($('<dd style="white-space: pre-wrap;">').text(def)); - }); - }); - new Dialog(self, { - title: _.str.sprintf(_t("Model %s fields"), - self.dataset.model), - buttons: { - Ok: function() { this.parents('.modal').modal('hide');} - }, - }, $root).open(); - }); - break; - case 'edit_workflow': - return this.do_action({ - res_model : 'workflow', - name: _t('Edit Workflow'), - domain : [['osv', '=', this.dataset.model]], - views: [[false, 'list'], [false, 'form'], [false, 'diagram']], - type : 'ir.actions.act_window', - view_type : 'list', - view_mode : 'list' - }); - case 'edit': - this.do_edit_resource(params.model, params.id, evt.target.text); - break; - case 'manage_filters': - this.do_action({ - res_model: 'ir.filters', - name: _t('Manage Filters'), - views: [[false, 'list'], [false, 'form']], - type: 'ir.actions.act_window', - context: { - search_default_my_filters: true, - search_default_model_id: this.dataset.model - } - }); - break; - case 'print_workflow': - if (current_view.get_selected_ids && current_view.get_selected_ids().length == 1) { - framework.blockUI(); - var action = { - context: { active_ids: current_view.get_selected_ids() }, - report_name: "workflow.instance.graph", - datas: { - model: this.dataset.model, - id: current_view.get_selected_ids()[0], - nested: true, - } - }; - this.session.get_file({ - url: '/web/report', - data: {action: JSON.stringify(action)}, - complete: framework.unblockUI - }); - } else { - self.do_warn("Warning", "No record selected."); - } - break; - case 'leave_debug': - window.location.search="?"; - break; - default: - if (val) { - console.warn("No debug handler for ", val); - } } - }, - do_edit_resource: function(model, id, name) { - this.do_action({ - res_model : model, - res_id : id, - name: name, - type : 'ir.actions.act_window', - view_type : 'form', - view_mode : 'form', - views : [[false, 'form']], - target : 'new', - flags : { - action_buttons : true, - headless: true, - } - }); + this.active_view.controller.do_load_state(state, warm); }, }); diff --git a/addons/web/static/src/js/views/form_relational_widgets.js b/addons/web/static/src/js/views/form_relational_widgets.js index 376a01f07f5..a33f1b84469 100644 --- a/addons/web/static/src/js/views/form_relational_widgets.js +++ b/addons/web/static/src/js/views/form_relational_widgets.js @@ -1078,9 +1078,10 @@ var One2ManyFormView = FormView.extend({ }); var One2ManyViewManager = ViewManager.extend({ - template: 'One2Many.viewmanager', init: function(parent, dataset, views, flags) { - this._super(parent, dataset, views, _.extend({}, flags, {$sidebar: false})); + // Only display the ControlPanel when there are several views to display + var flags = _.extend({}, flags, {$sidebar: false, headless: (views.length <= 1)}); + this._super(parent, dataset, views, flags); this.registry = core.view_registry.extend({ list: One2ManyListView, form: One2ManyFormView, diff --git a/addons/web/static/src/js/views/graph_view.js b/addons/web/static/src/js/views/graph_view.js index f8e89a27e86..2ab42516ba2 100644 --- a/addons/web/static/src/js/views/graph_view.js +++ b/addons/web/static/src/js/views/graph_view.js @@ -34,12 +34,15 @@ var GraphView = View.extend({ return $.when(this._super(), load_fields).then(this.render_buttons.bind(this)); }, render_buttons: function () { - var context = {measures: _.pairs(_.omit(this.measures, '__count__'))}; - this.$buttons.html(QWeb.render('GraphView.buttons', context)); - this.$measure_list = this.$buttons.find('.oe-measure-list'); - this.update_measure(); - this.$buttons.find('button').tooltip(); - this.$buttons.click(this.on_button_click.bind(this)); + // Render buttons only in non-headless mode as buttons are in the header + if (!this.options.headless) { + var context = {measures: _.pairs(_.omit(this.measures, '__count__'))}; + this.$buttons.html(QWeb.render('GraphView.buttons', context)); + this.$measure_list = this.$buttons.find('.oe-measure-list'); + this.update_measure(); + this.$buttons.find('button').tooltip(); + this.$buttons.click(this.on_button_click.bind(this)); + } }, update_measure: function () { var self = this; diff --git a/addons/web/static/src/js/views/list_view.js b/addons/web/static/src/js/views/list_view.js index 93bf5b5071f..9207f17b610 100644 --- a/addons/web/static/src/js/views/list_view.js +++ b/addons/web/static/src/js/views/list_view.js @@ -304,7 +304,7 @@ var ListView = View.extend( /** @lends instance.web.ListView# */ { // Pager if (!this.$pager) { this.$pager = $(QWeb.render("ListView.pager", {'widget':self})).hide(); - if (this.options.$buttons) { + if (this.options.$pager) { this.$pager.appendTo(this.options.$pager); } else { this.$el.find('.oe_list_pager').replaceWith(this.$pager); diff --git a/addons/web/static/src/js/views/pivot_view.js b/addons/web/static/src/js/views/pivot_view.js index cd401b3ea51..05f84477cec 100644 --- a/addons/web/static/src/js/views/pivot_view.js +++ b/addons/web/static/src/js/views/pivot_view.js @@ -85,20 +85,23 @@ var PivotView = View.extend({ }, render_buttons: function () { var self = this; - var context = {measures: _.pairs(_.omit(this.measures, '__count__'))}; - this.$buttons.html(QWeb.render('PivotView.buttons', context)); - this.$buttons.click(this.on_button_click.bind(this)); - this.active_measures.forEach(function (measure) { - self.$buttons.find('li[data-field="' + measure + '"]').addClass('selected'); - }); + // Render buttons only in non-headless mode as buttons are in the header + if (!this.options.headless) { + var context = {measures: _.pairs(_.omit(this.measures, '__count__'))}; + this.$buttons.html(QWeb.render('PivotView.buttons', context)); + this.$buttons.click(this.on_button_click.bind(this)); + this.active_measures.forEach(function (measure) { + self.$buttons.find('li[data-field="' + measure + '"]').addClass('selected'); + }); + this.$buttons.find('button').tooltip(); + } var another_ctx = {fields: _.chain(this.groupable_fields).pairs().sortBy(function(f){return f[1].string;}).value()}; this.$field_selection = this.$('.o-field-selection'); this.$field_selection.html(QWeb.render('PivotView.FieldSelection', another_ctx)); core.bus.on('click', self, function () { self.$field_selection.find('ul').first().hide(); }); - this.$buttons.find('button').tooltip(); }, view_loading: function (fvg) { var self = this; diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 2d514dc2830..3758aec3366 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -66,7 +66,7 @@ <div class="oe_form"> <form id="db_create" name="create_db_form" style="display: block;"> <div class="oe_view_manager oe_view_manager_current"> - <div class="oe_view_manager_header" style="padding: 8px;"> + <div class="oe-control-panel" style="padding: 8px;"> <div class="oe_header_row"> <h2 class="oe_view_title"> <span class="oe_view_title_text oe_breadcrumb_title">Create a New Database</span> @@ -134,7 +134,7 @@ </form> <form id="db_duplicate" name="duplicate_db_form" style="display: none;"> <div class="oe_view_manager oe_view_manager_current"> - <div class="oe_view_manager_header" style="padding: 8px;"> + <div class="oe-control-panel" style="padding: 8px;"> <div class="oe_header_row"> <h2 class="oe_view_title"> <span class="oe_view_title_text oe_breadcrumb_title">Duplicate Database</span> @@ -160,7 +160,7 @@ </form> <form id="db_drop" name="drop_db_form" style="display: none; "> <div class="oe_view_manager oe_view_manager_current"> - <div class="oe_view_manager_header" style="padding: 8px;"> + <div class="oe-control-panel" style="padding: 8px;"> <div class="oe_header_row"> <h2 class="oe_view_title"> <span class="oe_view_title_text oe_breadcrumb_title">Drop Database</span> @@ -191,7 +191,7 @@ </form> <form id="db_backup" name="backup_db_form" target="backup-target" action="/web/database/backup" style="display: none;"> <div class="oe_view_manager oe_view_manager_current"> - <div class="oe_view_manager_header" style="padding: 8px;"> + <div class="oe-control-panel" style="padding: 8px;"> <div class="oe_header_row"> <h2 class="oe_view_title"> <span class="oe_view_title_text oe_breadcrumb_title">Backup Database</span> @@ -232,7 +232,7 @@ </form> <form id="db_restore" name="restore_db_form" style="display: none; "> <div class="oe_view_manager oe_view_manager_current"> - <div class="oe_view_manager_header" style="padding: 8px;"> + <div class="oe-control-panel" style="padding: 8px;"> <div class="oe_header_row"> <h2 class="oe_view_title"> <span class="oe_view_title_text oe_breadcrumb_title">Restore Database</span> @@ -265,7 +265,7 @@ </form> <form id="db_change_password" name="change_pwd_form" style="display: none;"> <div class="oe_view_manager oe_view_manager_current"> - <div class="oe_view_manager_header" style="padding: 8px;"> + <div class="oe-control-panel" style="padding: 8px;"> <div class="oe_header_row"> <h2 class="oe_view_title"> <span class="oe_view_title_text oe_breadcrumb_title">Change Master Password</span> @@ -469,33 +469,33 @@ <div t-name="ActionManager" class="oe_application" /> -<div t-name="ViewManager" class="oe-view-manager"> - <div class="oe-view-manager-header container-fluid"> +<t t-name="ControlPanel"> + <div class="oe-control-panel container-fluid"> <div class="row"> - <div class="col-md-6 oe-header-title"> + <div class="col-md-6 oe-cp-title"> <div t-if="widget.debug" class="oe_debug_view btn-group btn-group-sm"/> <ol class="oe-view-title breadcrumb" t-if="widget.flags.display_title !== false"> </ol> </div> - <div class="oe-view-manager-search-view col-md-6" /> + <div class="oe-cp-search-view col-md-6" /> </div> <div class="row"> <div class="col-md-6 oe-button-column"> - <div class="oe-view-manager-buttons"> + <div class="oe-cp-buttons"> <t t-foreach="widget.views" t-as="view"> <div t-attf-class="oe-#{view}-buttons"/> </t> </div> - <div class="oe-view-manager-sidebar"></div> + <div class="oe-cp-sidebar"></div> </div> <div class="col-md-6"> <div class="oe-search-options btn-group"/> <div class="oe-right-toolbar"> - <div class="oe-view-manager-pager"></div> + <div class="oe-cp-pager"></div> <t t-if="widget.multiple_views"> - <div class="oe-view-manager-switch btn-group btn-group-sm"> + <div class="oe-cp-switch-buttons btn-group btn-group-sm"> <t t-foreach="widget.view_order" t-as="view"> - <button type="button" t-attf-class="btn btn-default fa oe-vm-switch-#{view.type}" t-att-data-view-type="view.type" t-att-title="view.label"> + <button type="button" t-attf-class="btn btn-default fa oe-cp-switch-#{view.type}" t-att-data-view-type="view.type" t-att-title="view.label"> </button> </t> </div> @@ -504,6 +504,9 @@ </div> </div> </div> +</t> + +<div t-name="ViewManager" class="oe-view-manager"> <div class="oe-view-manager-content"> <t t-foreach="widget.views" t-as="view"> <div t-attf-class="oe-view-manager-view-#{view} fade"/> @@ -514,7 +517,7 @@ <button type="button" class="btn btn-default dropdown-toggle fa fa-bug oe-view-manager-debug" data-toggle="dropdown"> <span class="caret"/> </button> <ul class="dropdown-menu" role="menu"> - <t t-if="view_manager.active_view.type === 'form'"> + <t t-if="widget.active_view.type === 'form'"> <li><a data-action="get_metadata">View Metadata</a></li> <li><a data-action="toggle_layout_outline">Toggle Form Layout Outline</a></li> <li><a data-action="set_defaults">Set Defaults</a></li> @@ -527,8 +530,8 @@ <li><a data-action="translate">Technical Translation</a></li> <li><a data-action="manage_views">Manage Views</a></li> <li><a data-action="edit" data-model="ir.ui.view" t-att-data-id="view.fields_view.view_id">Edit <t t-esc="_.str.capitalize(view.fields_view.type)"/> View</a></li> - <li t-if="view_manager.searchview"><a data-action="edit" data-model="ir.ui.view" t-att-data-id="view_manager.searchview.view_id">Edit SearchView</a></li> - <li t-if="view_manager.action"><a data-action="edit" t-att-data-model="view_manager.action.type" t-att-data-id="view_manager.action.id">Edit Action</a></li> + <li t-if="widget.searchview"><a data-action="edit" data-model="ir.ui.view" t-att-data-id="widget.searchview.view_id">Edit SearchView</a></li> + <li t-if="widget.action"><a data-action="edit" t-att-data-model="widget.action.type" t-att-data-id="widget.action.id">Edit Action</a></li> <li><a data-action="edit_workflow">Edit Workflow</a></li> <li><a data-action="print_workflow">Print Workflow</a></li> <li class="divider"/> @@ -1577,11 +1580,6 @@ </a> </t> -<t t-name="One2Many.viewmanager" t-extend="ViewManager"> - <t t-jquery=".oe-view-manager-header"> - this.attr('t-if', 'widget.view_order.length != 1'); - </t> -</t> <t t-name="One2Many.formview" t-extend="FormView"> <t t-jquery=".oe_form_buttons" t-operation="inner"> <button type="button" class="oe_button oe_form_button_create">Add</button> |
