[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
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<t t-set="_id" t-value="_.uniqueId('export')"/>
|
||||
<form action="" method="post" enctype="multipart/form-data" class="oe_import">
|
||||
<div class="oe_view_manager oe_view_manager_current">
|
||||
<div class="oe_view_manager_header oe_padding">
|
||||
<div class="oe-control-panel oe_padding">
|
||||
<h2>
|
||||
Import a CSV File
|
||||
</h2>
|
||||
|
||||
@@ -369,10 +369,10 @@ FavoriteMenu.include({
|
||||
this.do_warn(_t("Can't find dashboard action"));
|
||||
return;
|
||||
}
|
||||
var searchview = view_manager.searchview,
|
||||
search_data = searchview.build_search_data(),
|
||||
context = new data.CompoundContext(searchview.dataset.get_context() || []),
|
||||
domain = new data.CompoundDomain(searchview.dataset.get_domain() || []);
|
||||
var searchview = view_manager.get_searchview();
|
||||
var search_data = searchview.build_search_data();
|
||||
var context = new data.CompoundContext(searchview.dataset.get_context() || []);
|
||||
var domain = new data.CompoundDomain(searchview.dataset.get_domain() || []);
|
||||
_.each(search_data.contexts, context.add, context);
|
||||
_.each(search_data.domains, domain.add, domain);
|
||||
|
||||
|
||||
@@ -1875,7 +1875,7 @@ var MailWall = Widget.extend({
|
||||
options = { $buttons: this.$('.oe-search-options') };
|
||||
this.searchview = new SearchView(this, ds_msg, false, defaults || {}, options);
|
||||
this.searchview.on('search_data', this, this.do_searchview_search);
|
||||
this.searchview.appendTo(this.$('.oe-view-manager-search-view')).then(function () {
|
||||
this.searchview.appendTo(this.$('.oe-cp-search-view')).then(function () {
|
||||
self.searchview.toggle_visibility(true);
|
||||
});
|
||||
if (this.searchview.has_defaults) {
|
||||
|
||||
@@ -171,14 +171,14 @@
|
||||
Template used to display the communication history in the wall.
|
||||
-->
|
||||
<div t-name="mail.wall" class="oe-view-manager oe_mail_wall oe_view_manager_current">
|
||||
<div class="oe-view-manager-header container-fluid">
|
||||
<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">
|
||||
<ol class="oe-view-title breadcrumb">
|
||||
<li class="active"><t t-esc="widget.action.name"/></li>
|
||||
</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-sm-6 col-sm-offset-6">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
});
|
||||
@@ -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();
|
||||
// Tell the ControlPanel to call do_search on its searchview
|
||||
var active_search = this.control_panel.activate_search(view.created);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
<script type="text/javascript" src="/web/static/src/js/framework/view.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/framework/pyeval.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/action_manager.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/control_panel.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/view_manager.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/web_client.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/framework/data.js"></script>
|
||||
|
||||
@@ -45,6 +45,6 @@
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.oe-view-manager-switch .oe-vm-switch-diagram:before {
|
||||
.oe-cp-switch-buttons .oe-cp-switch-diagram:before {
|
||||
content: "";
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ odoo.define('web_view_editor.view_editor', function (require) {
|
||||
"use strict";
|
||||
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var ControlPanel = require('web.ControlPanel');
|
||||
var core = require('web.core');
|
||||
var data = require('web.data');
|
||||
var Dialog = require('web.Dialog');
|
||||
@@ -9,13 +10,12 @@ var formats = require('web.formats');
|
||||
var Registry = require('web.Registry');
|
||||
var session = require('web.session');
|
||||
var utils = require('web.utils');
|
||||
var ViewManager = require('web.ViewManager');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
var _t = core._t;
|
||||
|
||||
ViewManager.include({
|
||||
ControlPanel.include({
|
||||
on_debug_changed:function(evt){
|
||||
var val = $(evt.target).data('action'),
|
||||
current_view = this.active_view.controller;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@charset "utf-8";
|
||||
@charset "UTF-8";
|
||||
/* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY
|
||||
*
|
||||
* css for editor buttons, openerp widget included in the website and other
|
||||
|
||||
Reference in New Issue
Block a user