[MERGE] Improved search view UI
This branch is the result of a UI rethink of the search views. In order to do that, many other parts had to be moved/reworked. Main changes affect action manager, view manager and search view (they have been almost completely rewritten) Some highlights: * search view has 3 submenus (filters, groupbys, favorites) and all inputs are included in these submenus * view manager header is now responsive, and bootstrapized * icons are now using fontawesome * transitions between views should have much less flicker (because of work in action and view managers) * debug mode has a pretty icon (because why not) * we can now add custom groupbys (every groupable fields from the model are exposed (make sure you have good descriptive strings))
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
@charset "UTF-8";
|
||||
.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_0 {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -82,7 +83,7 @@
|
||||
color: #b3b3b3;
|
||||
}
|
||||
.openerp .oe_dashboard .oe_action .oe_header .oe_icon:hover {
|
||||
color: #666666;
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
}
|
||||
.openerp .oe_dashboard .oe_action .oe_header .oe_close:after {
|
||||
@@ -116,8 +117,14 @@
|
||||
.openerp .oe_dashboard .oe_action .oe_content {
|
||||
padding: 0 12px 12px 12px;
|
||||
}
|
||||
.openerp .oe_dashboard .oe_action .oe_content .oe_view_manager_header {
|
||||
display: none;
|
||||
.openerp .oe_dashboard .oe_action .oe_content .oe-view-manager-views {
|
||||
position: relative;
|
||||
}
|
||||
.openerp .oe_dashboard .oe_action .oe_content .oe-view-manager {
|
||||
display: block;
|
||||
}
|
||||
.openerp .oe_dashboard .oe_action .oe_content .oe-view-manager-content {
|
||||
display: block;
|
||||
}
|
||||
.openerp .oe_dashboard .oe_action .oe_content .oe_list_content > thead {
|
||||
border-bottom: 1px;
|
||||
@@ -125,3 +132,12 @@
|
||||
.openerp .oe_dashboard .oe_action .oe_content .oe_list_content > tbody tr:nth-child(odd) {
|
||||
background: transparent;
|
||||
}
|
||||
.openerp .oe-search-options .add-to-dashboard button {
|
||||
margin: 3px 25px;
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe-search-options .add-to-dashboard input {
|
||||
width: calc(100% - 50px);
|
||||
margin: 3px 25px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -98,25 +98,14 @@
|
||||
margin-left: 4px
|
||||
padding: 0 4px 0 4px
|
||||
height: 16px !important
|
||||
//.oe_rename
|
||||
//float: left
|
||||
//padding-right: 4px
|
||||
//position: relative
|
||||
//top: 1px
|
||||
//.oe_input
|
||||
//height: 16px;
|
||||
//position: relative;
|
||||
//top: 2px;
|
||||
//.ui-sortable-placeholder
|
||||
//border: 1px dotted black;
|
||||
//visibility: visible !important;
|
||||
//height: 50px !important;
|
||||
//*
|
||||
//visibility: hidden;
|
||||
.oe_content
|
||||
padding: 0 12px 12px 12px
|
||||
.oe_view_manager_header
|
||||
display: none
|
||||
.oe-view-manager-views
|
||||
position: relative
|
||||
.oe-view-manager
|
||||
display: block
|
||||
.oe-view-manager-content
|
||||
display: block
|
||||
.oe_list_content
|
||||
> thead
|
||||
border-bottom: 1px
|
||||
@@ -124,3 +113,13 @@
|
||||
tr:nth-child(odd)
|
||||
background: transparent
|
||||
|
||||
|
||||
.oe-search-options
|
||||
.add-to-dashboard
|
||||
button
|
||||
margin: 3px 25px
|
||||
display: none
|
||||
input
|
||||
width: calc(100% - 50px)
|
||||
margin: 3px 25px
|
||||
display: none
|
||||
|
||||
@@ -8,6 +8,16 @@ if (!instance.board) {
|
||||
}
|
||||
|
||||
instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
||||
events: {
|
||||
'click .oe_dashboard_link_reset': 'on_reset',
|
||||
'click .oe_dashboard_link_change_layout': 'on_change_layout',
|
||||
'click h2.oe_header span.oe_header_txt': function (ev) {
|
||||
if(ev.target === ev.currentTarget)
|
||||
self.on_header_string($(ev.target).parent());
|
||||
},
|
||||
'click .oe_dashboard_column .oe_fold': 'on_fold_action',
|
||||
'click .oe_dashboard_column .oe_close': 'on_close_action',
|
||||
},
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.form_template = 'DashBoard';
|
||||
@@ -18,7 +28,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.$el.find('.oe_dashboard_column').sortable({
|
||||
this.$('.oe_dashboard_column').sortable({
|
||||
connectWith: '.oe_dashboard_column',
|
||||
handle: '.oe_header',
|
||||
scroll: false
|
||||
@@ -27,16 +37,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
||||
var old_title = this.__parentedParent.get('title');
|
||||
this.__parentedParent.on('load_record', self, function(){
|
||||
self.__parentedParent.set({ 'title': old_title});
|
||||
})
|
||||
// Events
|
||||
this.$el.find('.oe_dashboard_link_reset').click(this.on_reset);
|
||||
this.$el.find('.oe_dashboard_link_change_layout').click(this.on_change_layout);
|
||||
this.$el.find('h2.oe_header span.oe_header_txt').click(function(ev){
|
||||
if(ev.target === ev.currentTarget)
|
||||
self.on_header_string($(ev.target).parent());
|
||||
});
|
||||
this.$el.delegate('.oe_dashboard_column .oe_fold', 'click', this.on_fold_action);
|
||||
this.$el.delegate('.oe_dashboard_column .oe_close', 'click', this.on_close_action);
|
||||
|
||||
// Init actions
|
||||
_.each(this.node.children, function(column, column_index) {
|
||||
@@ -208,6 +209,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
||||
views_switcher : false,
|
||||
action_buttons : false,
|
||||
pager: false,
|
||||
headless: true,
|
||||
low_profile: true,
|
||||
display_title: false,
|
||||
list: {
|
||||
@@ -244,7 +246,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
||||
};
|
||||
var list = am.inner_widget.views.list;
|
||||
if (list) {
|
||||
list.deferred.done(function() {
|
||||
list.created.done(function() {
|
||||
$(list.controller.groups).off('row_link').on('row_link', function(e, id) {
|
||||
new_form_action(id);
|
||||
});
|
||||
@@ -252,7 +254,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
||||
}
|
||||
var kanban = am.inner_widget.views.kanban;
|
||||
if (kanban) {
|
||||
kanban.deferred.done(function() {
|
||||
kanban.created.done(function() {
|
||||
kanban.controller.open_record = function(id, editable) {
|
||||
new_form_action(id, editable);
|
||||
};
|
||||
@@ -326,113 +328,85 @@ instance.web.form.tags.add('vpaned', 'instance.web.form.DashBoardLegacy');
|
||||
instance.web.form.tags.add('board', 'instance.web.form.DashBoard');
|
||||
|
||||
|
||||
instance.board.AddToDashboard = instance.web.search.Input.extend({
|
||||
template: 'SearchView.addtodashboard',
|
||||
_in_drawer: true,
|
||||
init: function (parent) {
|
||||
this._super(parent);
|
||||
this.is_loaded = null;
|
||||
},
|
||||
start: function () {
|
||||
instance.web.search.FavoriteMenu.include({
|
||||
prepare_dropdown_menu: function (filters) {
|
||||
var self = this;
|
||||
this.$el
|
||||
.on('click', 'h4', this.proxy('load_and_show_option'))
|
||||
.on('submit', 'form', function (e) {
|
||||
e.preventDefault();
|
||||
self.add_dashboard();
|
||||
});
|
||||
return $.when();
|
||||
},
|
||||
load_data:function(){
|
||||
var board = new instance.web.Model('board.board');
|
||||
return board.call('list', [board.context()]);
|
||||
},
|
||||
_x:function() {
|
||||
if (!instance.webclient) { return $.Deferred().reject(); }
|
||||
var dashboard_menu = instance.webclient.menu.data.data.children;
|
||||
return new instance.web.Model('ir.model.data')
|
||||
.query(['res_id'])
|
||||
.filter([['name','=','menu_reporting_dashboard']])
|
||||
.first().then(function (result) {
|
||||
var menu = _(dashboard_menu).chain()
|
||||
.pluck('children')
|
||||
.flatten(true)
|
||||
.find(function (child) { return child.id === result.res_id; })
|
||||
.value();
|
||||
return menu ? menu.children : [];
|
||||
this._super(filters);
|
||||
this.$('.favorites-menu').append(QWeb.render('SearchView.addtodashboard'));
|
||||
var $add_to_dashboard = this.$('.add-to-dashboard');
|
||||
this.$add_dashboard_btn = $add_to_dashboard.eq(2).find('button');
|
||||
this.$add_dashboard_input = $add_to_dashboard.eq(1).find('input');
|
||||
this.$add_dashboard_link = $add_to_dashboard.first().find('a');
|
||||
var title = this.searchview.getParent().title;
|
||||
this.$add_dashboard_input.val(title);
|
||||
this.$add_dashboard_link.click(function () {
|
||||
self.toggle_dashboard_menu();
|
||||
});
|
||||
this.$add_dashboard_btn.click(this.proxy('add_dashboard'));
|
||||
},
|
||||
render_data: function(dashboard_choices){
|
||||
var selection = instance.web.qweb.render(
|
||||
"SearchView.addtodashboard.selection", {
|
||||
selections: dashboard_choices});
|
||||
this.$("input").before(selection)
|
||||
toggle_dashboard_menu: function (is_open) {
|
||||
this.$add_dashboard_link
|
||||
.toggleClass('closed-menu', !is_open)
|
||||
.toggleClass('open-menu', is_open);
|
||||
this.$add_dashboard_btn.toggle(is_open);
|
||||
this.$add_dashboard_input.toggle(is_open);
|
||||
if (this.$add_dashboard_link.hasClass('open-menu')) {
|
||||
this.$add_dashboard_input.focus();
|
||||
}
|
||||
},
|
||||
add_dashboard: function(){
|
||||
var self = this;
|
||||
if (! this.view.view_manager.action || ! this.$el.find("select").val()) {
|
||||
close_menus: function () {
|
||||
this.toggle_dashboard_menu(false);
|
||||
this._super();
|
||||
},
|
||||
add_dashboard: function () {
|
||||
var self = this,
|
||||
view_manager = this.findAncestor(function (a) {
|
||||
return a instanceof instance.web.ViewManager
|
||||
});
|
||||
if (!view_manager.action) {
|
||||
this.do_warn(_t("Can't find dashboard action"));
|
||||
return;
|
||||
}
|
||||
var data = this.view.build_search_data();
|
||||
var context = new instance.web.CompoundContext(this.view.dataset.get_context() || []);
|
||||
var domain = new instance.web.CompoundDomain(this.view.dataset.get_domain() || []);
|
||||
var searchview = view_manager.searchview,
|
||||
data = searchview.build_search_data(),
|
||||
context = new instance.web.CompoundContext(searchview.dataset.get_context() || []),
|
||||
domain = new instance.web.CompoundDomain(searchview.dataset.get_domain() || []);
|
||||
_.each(data.contexts, context.add, context);
|
||||
_.each(data.domains, domain.add, domain);
|
||||
|
||||
context.add({
|
||||
group_by: instance.web.pyeval.eval('groupbys', data.groupbys || [])
|
||||
});
|
||||
|
||||
var c = instance.web.pyeval.eval('context', context);
|
||||
for(var k in c) {
|
||||
if (c.hasOwnProperty(k) && /^search_default_/.test(k)) {
|
||||
delete c[k];
|
||||
}
|
||||
}
|
||||
// TODO: replace this 6.1 workaround by attribute on <action/>
|
||||
this.toggle_dashboard_menu(false);
|
||||
c.dashboard_merge_domains_contexts = false;
|
||||
var d = instance.web.pyeval.eval('domain', domain);
|
||||
|
||||
this.rpc('/board/add_to_dashboard', {
|
||||
menu_id: this.$el.find("select").val(),
|
||||
action_id: this.view.view_manager.action.id,
|
||||
context_to_save: c,
|
||||
domain: d,
|
||||
view_mode: this.view.view_manager.active_view,
|
||||
name: this.$el.find("input").val()
|
||||
}).done(function(r) {
|
||||
if (r === false) {
|
||||
self.do_warn(_t("Could not add filter to dashboard"));
|
||||
} else {
|
||||
self.$el.toggleClass('oe_opened');
|
||||
self.do_notify(_t("Filter added to dashboard"), '');
|
||||
}
|
||||
});
|
||||
var d = instance.web.pyeval.eval('domain', domain),
|
||||
board = new instance.web.Model('board.board'),
|
||||
name = self.$add_dashboard_input.val();
|
||||
|
||||
board.call('list', [board.context()])
|
||||
.then(function (board_list) {
|
||||
return self.rpc('/board/add_to_dashboard', {
|
||||
menu_id: board_list[0].id,
|
||||
action_id: view_manager.action.id,
|
||||
context_to_save: c,
|
||||
domain: d,
|
||||
view_mode: view_manager.active_view.type,
|
||||
name: name,
|
||||
});
|
||||
}).then(function (r) {
|
||||
if (r) {
|
||||
self.do_notify(_.str.sprintf(_t("'%s' added to dashboard"), name), '');
|
||||
} else {
|
||||
self.do_warn(_t("Could not add filter to dashboard"));
|
||||
}
|
||||
});
|
||||
},
|
||||
load_and_show_option: function(){
|
||||
if (!this.is_loaded) {
|
||||
this.is_loaded = this.load_data().done(this.proxy("render_data"));
|
||||
}
|
||||
this.is_loaded.done(this.proxy('show_option'));
|
||||
},
|
||||
show_option: function () {
|
||||
this.$el.toggleClass('oe_opened');
|
||||
if (! this.$el.hasClass('oe_opened'))
|
||||
return;
|
||||
this.$("input").val(this.view.fields_view.name || "" );
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
instance.web.SearchViewDrawer.include({
|
||||
add_common_inputs: function() {
|
||||
this._super();
|
||||
var vm = this.getParent().getParent();
|
||||
if (vm.inner_action && vm.inner_action.id && vm.inner_action.views) {
|
||||
(new instance.board.AddToDashboard(this));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -63,19 +63,9 @@
|
||||
<iframe width="100%" frameborder="0" t-att-src="url"/>
|
||||
</t>
|
||||
|
||||
<div t-name="SearchView.addtodashboard" class="oe_searchview_dashboard">
|
||||
<h4>Add to Dashboard</h4>
|
||||
<form>
|
||||
<p><input placeholder="Title of new dashboard item"/></p>
|
||||
<button class="oe_apply" type="submit">Add</button>
|
||||
</form>
|
||||
</div>
|
||||
<t t-name="SearchView.addtodashboard.selection">
|
||||
<select>
|
||||
<option t-foreach="selections" t-as="element"
|
||||
t-att-value="element.id ">
|
||||
<t t-esc="element.name"/></option>
|
||||
</select>
|
||||
<t t-name="SearchView.addtodashboard">
|
||||
<li class="add-to-dashboard closed-menu"><a>Add to my Dashboard</a></li>
|
||||
<li class="add-to-dashboard"><input class="form-control" type="text"/></li>
|
||||
<li class="add-to-dashboard"><button class="btn btn-default">Add</button></li>
|
||||
</t>
|
||||
|
||||
</template>
|
||||
|
||||
@@ -12,20 +12,6 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="res_partner_opt_out_search">
|
||||
<field name="name">res.partner.opt_out.search</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_res_partner_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<filter string="Suppliers" position="after">
|
||||
<separator />
|
||||
<filter string="Available for mass mailing"
|
||||
name='not_opt_out' domain="[('opt_out', '=', False)]"
|
||||
help="Partners that did not ask not to be included in mass mailing campaigns" />
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--Definition of an email template with an empty body that will be used in partner mailing. Used to give a
|
||||
basis for email recipients, name and to ease the definition of a further elaborated template. -->
|
||||
<record id="email_template_partner" model="email.template">
|
||||
|
||||
@@ -1,54 +1,50 @@
|
||||
openerp.google_spreadsheet = function(instance) {
|
||||
var _t = instance.web._t;
|
||||
var _t = instance.web._t,
|
||||
QWeb = instance.web.qweb;
|
||||
|
||||
instance.web.FormView.include({
|
||||
on_processed_onchange: function(result, processed) {
|
||||
var self = this;
|
||||
|
||||
var fields = self.fields;
|
||||
_(result.selection).each(function (selection, fieldname) {
|
||||
var field = fields[fieldname];
|
||||
if (!field) { return; }
|
||||
field.field.selection = selection;
|
||||
field.values = selection;
|
||||
field.renderElement();
|
||||
});
|
||||
return this._super(result, processed);
|
||||
},
|
||||
on_processed_onchange: function(result, processed) {
|
||||
var self = this;
|
||||
var fields = self.fields;
|
||||
_(result.selection).each(function (selection, fieldname) {
|
||||
var field = fields[fieldname];
|
||||
if (!field) { return; }
|
||||
field.field.selection = selection;
|
||||
field.values = selection;
|
||||
field.renderElement();
|
||||
});
|
||||
return this._super(result, processed);
|
||||
},
|
||||
});
|
||||
instance.web.search.FavoriteMenu.include({
|
||||
prepare_dropdown_menu: function (filters) {
|
||||
this._super(filters);
|
||||
this.$('.favorites-menu').append(QWeb.render('SearchView.addtogooglespreadsheet'));
|
||||
this.$('.add-to-spreadsheet').click(this.add_to_spreadsheet.bind(this));
|
||||
},
|
||||
add_to_spreadsheet: function () {
|
||||
var data = this.searchview.build_search_data(),
|
||||
model = this.searchview.dataset.model,
|
||||
view_manager = this.searchview.getParent(),
|
||||
list_view = view_manager.views.list,
|
||||
list_view_id = list_view ? list_view.view_id : false,
|
||||
context = this.searchview.dataset.get_context() || [],
|
||||
domain = this.searchview.dataset.get_domain() || [],
|
||||
compound_context = new instance.web.CompoundContext(context),
|
||||
compound_domain = new instance.web.CompoundDomain(context),
|
||||
groupbys = instance.web.pyeval.eval('groupbys', data.groupbys).join(" "),
|
||||
ds = new instance.web.DataSet(this, 'google.drive.config');
|
||||
|
||||
_.each(data.contexts, compound_context.add, compound_context);
|
||||
_.each(data.domains, compound_domain.add, compound_domain);
|
||||
|
||||
compound_domain = JSON.stringify(compound_domain.eval());
|
||||
ds.call('set_spreadsheet', [model, compound_domain, groupbys, list_view_id])
|
||||
.done(function (res) {
|
||||
if (res['url']){
|
||||
window.open(res['url'], '_blank');
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
instance.board.AddToGoogleSpreadsheet = instance.web.search.Input.extend({
|
||||
template: 'SearchView.addtogooglespreadsheet',
|
||||
_in_drawer: true,
|
||||
start: function () {
|
||||
var self = this;
|
||||
this.$el.on('click', 'h4', function(){
|
||||
var view = self.view;
|
||||
var data = view.build_search_data();
|
||||
var model = view.model;
|
||||
var list_view = self.view.getParent().views['list'];
|
||||
var view_id = list_view ? list_view.view_id : false;
|
||||
var context = new instance.web.CompoundContext(view.dataset.get_context() || []);
|
||||
var domain = new instance.web.CompoundDomain(view.dataset.get_domain() || []);
|
||||
_.each(data.contexts, context.add, context);
|
||||
_.each(data.domains, domain.add, domain);
|
||||
domain = JSON.stringify(domain.eval());
|
||||
var groupbys = instance.web.pyeval.eval('groupbys', data.groupbys).join(" ");
|
||||
var view_id = view_id;
|
||||
var ds = new instance.web.DataSet(self, 'google.drive.config');
|
||||
ds.call('set_spreadsheet', [model, domain, groupbys, view_id]).done(function (res) {
|
||||
if (res['url']){
|
||||
window.open(res['url'], '_blank');
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
instance.web.SearchViewDrawer.include({
|
||||
add_common_inputs: function() {
|
||||
this._super();
|
||||
var vm = this.getParent().getParent();
|
||||
if (vm.inner_action && vm.inner_action.views) {
|
||||
(new instance.board.AddToGoogleSpreadsheet(this));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div t-name="SearchView.addtogooglespreadsheet" class="oe_searchview_dashboard">
|
||||
<h4>Add to Google Spreadsheet</h4>
|
||||
</div>
|
||||
<t t-name="SearchView.addtogooglespreadsheet">
|
||||
<li><a class="add-to-spreadsheet">Add to Google Spreadsheet</a></li>
|
||||
</t>
|
||||
</template>
|
||||
@@ -740,3 +740,6 @@
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.oe_mail_wall .oe-groupby-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1278,6 +1278,7 @@ openerp.mail = function (session) {
|
||||
start: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.bind_events();
|
||||
return $.when();
|
||||
},
|
||||
|
||||
/* instantiate the compose message object and insert this on the DOM.
|
||||
@@ -1967,11 +1968,14 @@ openerp.mail = function (session) {
|
||||
* @param {Object} defaults ??
|
||||
*/
|
||||
load_searchview: function (defaults) {
|
||||
var ds_msg = new session.web.DataSetSearch(this, 'mail.message');
|
||||
this.searchview = new session.web.SearchView(this, ds_msg, false, defaults || {}, false);
|
||||
var self = this,
|
||||
ds_msg = new session.web.DataSetSearch(this, 'mail.message'),
|
||||
options = { $buttons: this.$('.oe-search-options') };
|
||||
this.searchview = new session.web.SearchView(this, ds_msg, false, defaults || {}, options);
|
||||
this.searchview.on('search_data', this, this.do_searchview_search);
|
||||
this.searchview.appendTo(this.$('.oe_view_manager_view_search'),
|
||||
this.$('.oe_searchview_drawer_container'));
|
||||
this.searchview.appendTo(this.$('.oe-view-manager-search-view')).then(function () {
|
||||
self.searchview.toggle_visibility(true);
|
||||
});
|
||||
if (this.searchview.has_defaults) {
|
||||
this.searchview.ready.then(this.searchview.do_search);
|
||||
}
|
||||
|
||||
@@ -166,36 +166,25 @@
|
||||
wall main template
|
||||
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">
|
||||
<table class="oe_view_manager_header">
|
||||
<colgroup>
|
||||
<col width="33%"/>
|
||||
<col width="33%"/>
|
||||
<col width="34%"/>
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr class="oe_header_row oe_header_row_top">
|
||||
<td colspan="2">
|
||||
<h2 class="oe_view_title">
|
||||
<span class="oe_view_title_text">
|
||||
<t t-esc="widget.action.name"/>
|
||||
</span>
|
||||
</h2>
|
||||
<t t-if="widget.action.params.header_description">
|
||||
<br/>
|
||||
<span class="oe_view_subtitle_text">
|
||||
<t t-raw="widget.action.params.header_description"/>
|
||||
</span>
|
||||
</t>
|
||||
</td>
|
||||
<td><div class="oe_view_manager_view_search"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="oe_view_manager_wrapper">
|
||||
<div>
|
||||
<div class="oe_view_manager_body">
|
||||
<div class="oe_searchview_drawer_container"/>
|
||||
<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="row">
|
||||
<div class="col-md-6 oe-header-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>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-sm-offset-6">
|
||||
<div class="oe-search-options btn-group"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe-view-manager-content">
|
||||
<div class="oe-view-manager-body">
|
||||
<div>
|
||||
<div class="oe_mail-placeholder"></div>
|
||||
<aside class="oe_mail_wall_aside"></aside>
|
||||
</div>
|
||||
|
||||
@@ -65,7 +65,7 @@ class crm_case_section(osv.osv):
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Sales Team', size=64, required=True, translate=True),
|
||||
'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True),
|
||||
'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True, string="Full Name"),
|
||||
'code': fields.char('Code', size=8),
|
||||
'active': fields.boolean('Active', help="If the active field is set to "\
|
||||
"true, it will allow you to hide the sales team without removing it."),
|
||||
|
||||
@@ -94,7 +94,7 @@ openerp.share = function(session) {
|
||||
}
|
||||
});
|
||||
|
||||
session.web.ViewManagerAction.include({
|
||||
session.web.ViewManager.include({
|
||||
start: function() {
|
||||
var self = this;
|
||||
this.check_if_action_is_defined();
|
||||
|
||||
+362
-656
File diff suppressed because it is too large
Load Diff
+256
-471
@@ -267,7 +267,7 @@ $sheet-padding: 16px
|
||||
font-size: inherit
|
||||
// }}}
|
||||
// Button style {{{
|
||||
a.button:link, a.button:visited, button, .oe_button, input[type='submit']
|
||||
a.button:link, a.button:visited, .oe_button, input[type='submit']
|
||||
display: inline-block
|
||||
border: 1px solid rgba(0,0,0,0.4)
|
||||
color: #4c4c4c
|
||||
@@ -282,22 +282,22 @@ $sheet-padding: 16px
|
||||
-webkit-font-smoothing: antialiased
|
||||
outline: none
|
||||
|
||||
a.button:hover, button:hover,.oe_button:hover, input[type='submit']:hover
|
||||
a.button:hover,.oe_button:hover, input[type='submit']:hover
|
||||
@include vertical-gradient(#f6f6f6, #e3e3e3)
|
||||
cursor: pointer
|
||||
background-position: 0
|
||||
|
||||
a.button:focus, button:focus, .oe_button:focus, input[type='submit']:focus
|
||||
a.button:focus, .oe_button:focus, input[type='submit']:focus
|
||||
border: 1px solid #80bfff
|
||||
background-position: 0
|
||||
@include vertical-gradient(#f6f6f6, #e3e3e3)
|
||||
@include box-shadow((0 0 3px #80bfff, 0 1px 1px rgba(255, 255, 255, .8) inset))
|
||||
|
||||
a.button:active, a.button.active, button:active, .oe_button:active, .oe_button.active, input[type='submit']:active, input[type='submit'].active
|
||||
a.button:active, a.button.active, .oe_button:active, .oe_button.active, input[type='submit']:active, input[type='submit'].active
|
||||
@include vertical-gradient(#e3e3e3, #f6f6f6)
|
||||
@include box-shadow(none)
|
||||
|
||||
a.button.disabled, button:disabled, .oe_button:disabled, input[type='submit']:disabled
|
||||
a.button.disabled, .oe_button:disabled, input[type='submit']:disabled
|
||||
background: #efefef !important
|
||||
border: 1px solid #d1d1d1 !important
|
||||
@include box-shadow(none !important)
|
||||
@@ -653,44 +653,6 @@ $sheet-padding: 16px
|
||||
border-right: 4px solid transparent
|
||||
border-top: 4px solid#404040
|
||||
@include opacity(0.5)
|
||||
.oe_sidebar
|
||||
white-space: nowrap
|
||||
.oe_dropdown_menu
|
||||
.oe_sidebar_add_attachment
|
||||
height: 20px
|
||||
cursor: pointer
|
||||
padding-left: 6px
|
||||
margin-top: 6px
|
||||
span
|
||||
font-weight: bold
|
||||
.oe_hidden_input_file
|
||||
width: 200px
|
||||
&:hover
|
||||
@include vertical-gradient(#f0f0fa, #eeeef6)
|
||||
@include box-shadow(none)
|
||||
li
|
||||
.oe_sidebar_delete_item
|
||||
position: absolute
|
||||
top: 4px
|
||||
right: 4px
|
||||
display: none
|
||||
width: 12px
|
||||
height: 12px
|
||||
padding: 1px
|
||||
color: #8786b7
|
||||
line-height: 8px
|
||||
text-align: center
|
||||
font-weight: bold
|
||||
text-shadow: 0 1px 1px white
|
||||
&:hover
|
||||
text-decoration: none
|
||||
color: white
|
||||
background: #8786b7
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4)
|
||||
@include radius(2px)
|
||||
&:hover
|
||||
.oe_sidebar_delete_item
|
||||
display: inline-block
|
||||
// }}}
|
||||
// Loading {{{
|
||||
.oe_loading
|
||||
@@ -899,202 +861,148 @@ $sheet-padding: 16px
|
||||
.oe_application
|
||||
width: 100%
|
||||
height: 100%
|
||||
a
|
||||
color: $link-color
|
||||
overflow: hidden
|
||||
> div
|
||||
position: relative
|
||||
height: 100%
|
||||
> .oe_view_manager
|
||||
> .oe_view_manager_wrapper
|
||||
display: table-row
|
||||
height: 100%
|
||||
> div
|
||||
position: relative
|
||||
height: 100%
|
||||
> .oe_view_manager_body
|
||||
position: absolute
|
||||
position: static\9
|
||||
top: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
right: 0
|
||||
overflow: auto
|
||||
.oe-view-manager
|
||||
.oe-view-manager-debug
|
||||
margin-right: 5px
|
||||
.oe-view-manager-content
|
||||
display: table-row
|
||||
height: 100%
|
||||
|
||||
.oe-view-manager-body
|
||||
position: relative
|
||||
height: 100%
|
||||
a
|
||||
color: $link-color
|
||||
.oe-view-manager-view-kanban:not(:empty)
|
||||
height: 100%
|
||||
> div
|
||||
position: absolute
|
||||
top: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
right: 0
|
||||
overflow: auto
|
||||
.oe_form_field_one2many
|
||||
.oe-view-manager-views
|
||||
position: initial
|
||||
|
||||
.oe_breadcrumb_item:not(:last-child)
|
||||
max-width: 7em
|
||||
white-space: nowrap
|
||||
text-overflow: ellipsis
|
||||
.oe_breadcrumb_title > *
|
||||
display: inline-block
|
||||
overflow: hidden
|
||||
font-weight: bold
|
||||
// }}}
|
||||
// ViewManager common {{{
|
||||
.oe_view_manager
|
||||
.oe-view-manager
|
||||
display: table
|
||||
height: inherit
|
||||
width: 100%
|
||||
.oe_view_manager_view_kanban:not(:empty)
|
||||
height: 100%
|
||||
&[data-view-type=kanban]
|
||||
.oe_view_manager_body
|
||||
display: table-row
|
||||
|
||||
table.oe_view_manager_header
|
||||
border-collapse: separate
|
||||
width: 100%
|
||||
table-layout: fixed
|
||||
.oe_header_row
|
||||
//min-height: 26px
|
||||
//line-height: 26px
|
||||
clear: both
|
||||
text-shadow: 0 1px 1px white
|
||||
.oe_header_row:last-child
|
||||
td
|
||||
padding-top: 0
|
||||
.oe_header_row:first-child
|
||||
td
|
||||
padding-top: 8px
|
||||
.oe_view_manager_sidebar
|
||||
margin: 0px auto
|
||||
text-align: center
|
||||
.oe_dropdown_arrow:after
|
||||
opacity: 0.9
|
||||
td
|
||||
line-height: 26px
|
||||
h2
|
||||
font-size: 18px
|
||||
margin: 0
|
||||
float: left
|
||||
line-height: 30px
|
||||
a
|
||||
color: $link-color
|
||||
.oe_dropdown_menu
|
||||
line-height: normal
|
||||
.oe_button_group
|
||||
display: inline-block
|
||||
border: 1px solid #ababab
|
||||
@include radius(5px)
|
||||
li
|
||||
float: left
|
||||
border-right: 1px solid #ababab
|
||||
&:last-child
|
||||
border: none
|
||||
a
|
||||
color: #4c4c4c
|
||||
&:hover
|
||||
text-decoration: none
|
||||
.active
|
||||
background: #999
|
||||
@include box-shadow(0 1px 4px rgba(0,0,0,0.3) inset)
|
||||
a
|
||||
color: #fff
|
||||
text-shadow: 0 1px 2px rgba(0,0,0,0.4)
|
||||
.oe_view_manager_buttons
|
||||
white-space: nowrap
|
||||
// }}}
|
||||
// ViewManager.switches {{{
|
||||
.oe_view_manager_switch
|
||||
padding: 0
|
||||
margin: 0 0 0 8px
|
||||
height: 100%
|
||||
.oe-view-manager-header
|
||||
display: table-row
|
||||
background-color: rgb(240, 238, 238)
|
||||
border-bottom: 1px solid #afafb6
|
||||
-webkit-user-select: none
|
||||
-moz-user-select: none
|
||||
user-select: none
|
||||
.dropdown-menu
|
||||
li
|
||||
margin: 0
|
||||
width: 24px
|
||||
height: 24px
|
||||
line-height: 16px
|
||||
padding: 0
|
||||
text-align: center
|
||||
list-style-type: none
|
||||
position: relative
|
||||
a
|
||||
position: relative
|
||||
.oe_vm_switch_list:after, .oe_vm_switch_tree:after
|
||||
padding: 2px
|
||||
content: "i"
|
||||
.oe_vm_switch_form:after
|
||||
content: "m"
|
||||
.oe_vm_switch_graph:after
|
||||
font-family: "mnmliconsRegular" !important
|
||||
font-size: 21px
|
||||
font-weight: 300 !important
|
||||
content: "}"
|
||||
top: -2px
|
||||
position: relative
|
||||
.oe_vm_switch_gantt:after
|
||||
font-family: "mnmliconsRegular" !important
|
||||
font-size: 21px
|
||||
font-weight: 300 !important
|
||||
content: "y"
|
||||
top: -2px
|
||||
position: relative
|
||||
.oe_vm_switch_calendar:after
|
||||
content: "P"
|
||||
.oe_vm_switch_kanban:after
|
||||
content: "k"
|
||||
.oe_vm_switch_diagram:after
|
||||
content: "f"
|
||||
// }}}
|
||||
// List pager {{{
|
||||
.oe_list_pager
|
||||
line-height: 26px
|
||||
.oe_pager_value
|
||||
float: left
|
||||
margin-right: 8px
|
||||
ul.oe_pager_group
|
||||
padding: 0
|
||||
margin: 0
|
||||
.oe_pager_group
|
||||
float: left
|
||||
height: 24px
|
||||
line-height: 24px
|
||||
display: inline-block
|
||||
border: 1px solid #ababab
|
||||
cursor: pointer
|
||||
@include radius(5px)
|
||||
li
|
||||
height: 24px
|
||||
line-height: 24px
|
||||
padding: 0
|
||||
padding: 3px 25px
|
||||
.oe-right-toolbar
|
||||
float: right
|
||||
> div
|
||||
display: inline-block
|
||||
.row
|
||||
margin: 0
|
||||
list-style-type: none
|
||||
float: left
|
||||
border-right: 1px solid #ababab
|
||||
&:last-child
|
||||
border: none
|
||||
a
|
||||
color: #4c4c4c
|
||||
padding: 0 8px
|
||||
&:hover
|
||||
text-decoration: none
|
||||
.active
|
||||
background: #999
|
||||
@include box-shadow(0 1px 4px rgba(0,0,0,0.3) inset)
|
||||
a
|
||||
color: #fff
|
||||
text-shadow: 0 1px 2px rgba(0,0,0,0.4)
|
||||
.oe_list_pager.oe_list_pager_single_page .oe_pager_group
|
||||
display: none
|
||||
// }}}
|
||||
// ViewManager application {{{
|
||||
.oe_view_manager_current
|
||||
height: 100%
|
||||
> .oe_view_manager_header
|
||||
border-bottom: 1px solid #cacaca
|
||||
@include vertical-gradient(#fcfcfc, #dedede)
|
||||
@include box-shadow((0 1px 0 rgba(255,255,255,0.4), 0 0 9px rgba(0,0,0,0.1)))
|
||||
.oe_header_row
|
||||
td
|
||||
padding: 8px
|
||||
.oe_header_row:first-child
|
||||
td
|
||||
padding-top: 8px
|
||||
// }}}
|
||||
// ViewManager inline {{{
|
||||
.row:first-child
|
||||
padding-top: 3px
|
||||
padding-bottom: 3px
|
||||
.row:last-child
|
||||
padding-bottom: 10px
|
||||
.oe_tag
|
||||
@include radius(0px)
|
||||
.oe-view-title
|
||||
font-size: 18px
|
||||
padding-left: 0
|
||||
margin: 0
|
||||
background-color: rgb(240, 238, 238)
|
||||
li
|
||||
-moz-user-select: initial
|
||||
-webkit-user-select: initial
|
||||
user-select: initial
|
||||
.oe-view-manager-search-view
|
||||
padding-top: 5px
|
||||
.oe-view-manager-switch
|
||||
.oe-vm-switch-kanban:before
|
||||
content: "\f009"
|
||||
.oe-vm-switch-list:before
|
||||
content: ""
|
||||
.oe-vm-switch-form:before
|
||||
content: "\f044"
|
||||
.oe-vm-switch-graph:before
|
||||
content: "\f080"
|
||||
.oe-vm-switch-calendar:before
|
||||
content: "\f073"
|
||||
.oe-vm-switch-gantt:before
|
||||
content: "\f0ae"
|
||||
.oe-vm-switch-pivot:before
|
||||
content: "\f0ce"
|
||||
.oe-view-manager-buttons
|
||||
display: inline-block
|
||||
> div
|
||||
display: none
|
||||
.oe-view-manager-sidebar
|
||||
display: inline-block
|
||||
float: right
|
||||
.oe_form_binary_form
|
||||
cursor: pointer
|
||||
span
|
||||
padding: 3px 20px
|
||||
input.oe_form_binary_file
|
||||
width: 100%
|
||||
|
||||
.oe_form_binary_form:hover
|
||||
background-color: #f5f5f5
|
||||
.oe_file_attachment
|
||||
padding: 3px 20px
|
||||
display: inline-block
|
||||
.oe_sidebar_delete_item
|
||||
padding: 0
|
||||
display: inline-block
|
||||
.dropdown-menu
|
||||
li
|
||||
a
|
||||
width: 100%
|
||||
.oe_form_buttons
|
||||
padding: 0
|
||||
.oe-pager-buttons
|
||||
min-height: 30px
|
||||
.oe_view_manager_inline, .oe_view_manager_inlineview
|
||||
height: 100%
|
||||
> .oe_view_manager_header
|
||||
> .oe-view-manager-header
|
||||
display: none
|
||||
// }}}
|
||||
.oe-search-options
|
||||
.selected
|
||||
display: block
|
||||
a
|
||||
font-weight: bold
|
||||
a:before
|
||||
font-family: FontAwesome
|
||||
position: absolute
|
||||
left: 6px
|
||||
top: 3px
|
||||
content: "\f00c"
|
||||
|
||||
.oe_application
|
||||
> div
|
||||
> div
|
||||
> .oe-view-manager-body
|
||||
position: absolute
|
||||
top: 90px
|
||||
bottom: 0
|
||||
left: 0
|
||||
right: 0
|
||||
overflow: auto
|
||||
// }}}
|
||||
// FormPopup {{{
|
||||
.oe_popup_form
|
||||
display: table
|
||||
@@ -1106,98 +1014,53 @@ $sheet-padding: 16px
|
||||
// End of customize
|
||||
.oe_popup_list_pager
|
||||
float: right
|
||||
.oe_popup_search
|
||||
width: 50%
|
||||
float: right
|
||||
// }}}
|
||||
// SearchView {{{
|
||||
.oe_searchview
|
||||
cursor: text
|
||||
position: relative
|
||||
float: right
|
||||
padding: 1px 0
|
||||
line-height: 18px
|
||||
min-width: 400px
|
||||
border: 1px solid #ababab
|
||||
background: white
|
||||
@include radius(13px)
|
||||
@include box-shadow(0 1px 2px rgba(0,0,0,0.2) inset)
|
||||
input, textarea
|
||||
padding: 3px
|
||||
height: 14px
|
||||
font-size: 12px
|
||||
line-height: 18px
|
||||
//Customize searchview input, select
|
||||
input:not([type]), input[type="text"], input[type="number"]
|
||||
width: 156px
|
||||
height: 22px
|
||||
input[type="checkbox"]
|
||||
margin: 3px 3px 3px 4px
|
||||
select
|
||||
margin: 2px 4px 2px 0
|
||||
//End of customize
|
||||
&.oe_focused
|
||||
border-color: $tag-border-selected
|
||||
@include box-shadow(0 1px 2px $tag-border-selected inset)
|
||||
.oe_searchview_clear
|
||||
cursor: pointer
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 18px
|
||||
width: 15px
|
||||
height: 24px
|
||||
background: url(../img/search_reset.gif) center center no-repeat
|
||||
display: none
|
||||
height: auto
|
||||
padding-top: 1px
|
||||
padding-bottom: 1px
|
||||
.oe_searchview_unfold_drawer
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
height: 24px
|
||||
padding: 0 7px 0 4px
|
||||
color: #ccc
|
||||
top: 8px
|
||||
right: 5px
|
||||
cursor: pointer
|
||||
&:hover
|
||||
color: #999
|
||||
&:before
|
||||
position: absolute
|
||||
top: 10px
|
||||
right: 7px
|
||||
width: 0
|
||||
height: 0
|
||||
display: inline-block
|
||||
content: ""
|
||||
vertical-align: top
|
||||
border-top: 5px solid #4C4C4C
|
||||
border-left: 5px solid transparent
|
||||
border-right: 5px solid transparent
|
||||
@include opacity()
|
||||
|
||||
.oe_searchview_search
|
||||
@include text-to-icon("r", #a3a3a3)
|
||||
@include box-shadow(none)
|
||||
@include radius(0)
|
||||
cursor: pointer
|
||||
position: absolute
|
||||
left: 3px
|
||||
top: 1px
|
||||
padding: 0
|
||||
border: none
|
||||
background: transparent
|
||||
|
||||
top: 8px
|
||||
left: 5px
|
||||
.oe_searchview_facets
|
||||
min-height: 22px
|
||||
margin: 0 35px 0 15px
|
||||
margin: 2px 20px 0 0
|
||||
*
|
||||
vertical-align: top
|
||||
display: inline-block
|
||||
line-height: 17px
|
||||
font-size: 100%
|
||||
.oe_searchview_facet
|
||||
margin: 1px 0
|
||||
font-size: 11px
|
||||
&:focus
|
||||
outline: none
|
||||
.label
|
||||
@include radius(0px)
|
||||
.oe_searchview_input
|
||||
padding: 0 0 0 6px
|
||||
padding: 2px 0 0 6px
|
||||
font-size: 12px
|
||||
height: 16px
|
||||
margin-top: 3px
|
||||
-webkit-user-select: initial
|
||||
-moz-user-select: initial
|
||||
user-select: initial
|
||||
&:focus
|
||||
outline: none
|
||||
.oe_searchview_input:first-child
|
||||
margin-left: 10px
|
||||
.oe_searchview_facet
|
||||
position: relative
|
||||
cursor: pointer
|
||||
@@ -1209,7 +1072,6 @@ $sheet-padding: 16px
|
||||
@include box-shadow(0 0 3px 1px $tag-border-selected)
|
||||
.oe_facet_values
|
||||
background: $tag-bg-light
|
||||
@include radius(0 3px 3px 0)
|
||||
.oe_facet_category, .oe_facet_value
|
||||
padding: 0 4px
|
||||
.oe_facet_category
|
||||
@@ -1218,11 +1080,12 @@ $sheet-padding: 16px
|
||||
.oe_facet_category.oe_i
|
||||
font-size: 16px
|
||||
.oe_facet_value
|
||||
border-left: 1px solid $tag-border
|
||||
text-shadow: 0 1px 1px white
|
||||
border-left: 1px solid #afafb6
|
||||
color: #4C4C4C
|
||||
&:last-child
|
||||
padding-right: 16px
|
||||
&:first-child
|
||||
border-left: none
|
||||
.oe_facet_remove
|
||||
position: absolute
|
||||
top: 3px
|
||||
@@ -1245,14 +1108,13 @@ $sheet-padding: 16px
|
||||
.oe-autocomplete
|
||||
display: none
|
||||
position: absolute
|
||||
width: 300px
|
||||
background-color: white
|
||||
width: 400px
|
||||
border: 1px solid #afafb6
|
||||
z-index: 666
|
||||
margin-top: 2px
|
||||
cursor: default
|
||||
@include radius(3px)
|
||||
@include box-shadow(0 1px 4px rgba(0, 0, 0, 0.3))
|
||||
ul
|
||||
list-style-type: none
|
||||
padding-left: 0
|
||||
@@ -1276,180 +1138,102 @@ $sheet-padding: 16px
|
||||
li.oe-separator:last-child
|
||||
display: none
|
||||
|
||||
|
||||
.oe_searchview_drawer_container
|
||||
overflow: auto
|
||||
.oe_searchview_drawer
|
||||
display: none
|
||||
width: 100%
|
||||
cursor: default
|
||||
display: none
|
||||
overflow: hidden
|
||||
border-bottom: 1px solid $tag-border
|
||||
text-align: left
|
||||
padding: 8px 0
|
||||
.badge
|
||||
font-size: 12px
|
||||
line-height: 12px
|
||||
> div:first-child
|
||||
border: none
|
||||
padding-left: 0
|
||||
li:hover:not(.badge)
|
||||
background-color: $hover-background
|
||||
.col-md-5
|
||||
padding-left: 0
|
||||
dl
|
||||
margin-bottom: 0
|
||||
dt
|
||||
color: $section-title-color
|
||||
font-size: 13px
|
||||
line-height: 24px
|
||||
dd
|
||||
line-height: 24px
|
||||
font-size: 13px
|
||||
padding-top: 3px
|
||||
h4, h4 *
|
||||
margin: 0 0 0 2px
|
||||
padding-left: 20px
|
||||
cursor: pointer
|
||||
font-weight: normal
|
||||
display: inline-block
|
||||
&:hover
|
||||
background-color: $hover-background
|
||||
h4:before
|
||||
content: "▸ "
|
||||
color: #a3a3a3
|
||||
button
|
||||
margin: 4px 0
|
||||
.button
|
||||
border: none
|
||||
background: transparent
|
||||
padding: 0 2px
|
||||
@include box-shadow(none)
|
||||
@include radius(0)
|
||||
.oe_searchview_section
|
||||
ul
|
||||
margin: 0 8px
|
||||
padding: 0
|
||||
list-style: none
|
||||
display: inline
|
||||
li
|
||||
display: inline-block
|
||||
cursor: pointer
|
||||
position: relative
|
||||
margin-right: 8px
|
||||
> span
|
||||
display: inline-block
|
||||
max-width: 250px
|
||||
text-overflow: ellipsis
|
||||
vertical-align: bottom
|
||||
overflow: hidden
|
||||
form
|
||||
margin-left: 12px
|
||||
p
|
||||
margin: 4px 0
|
||||
line-height: 18px
|
||||
button
|
||||
margin: 0 0 8px -3px // Managed margin-left according bootstrap3
|
||||
.oe_searchview_savefilter
|
||||
form
|
||||
display: none
|
||||
.oe_searchview_custom
|
||||
.oe-search-options
|
||||
a
|
||||
padding-left: 25px
|
||||
padding-right: 25px
|
||||
width: 100%
|
||||
-webkit-user-select: none
|
||||
-moz-user-select: none
|
||||
user-select: none
|
||||
.oe-apply-filter
|
||||
margin-left: 25px
|
||||
.oe-add-filter-menu
|
||||
display: none
|
||||
li
|
||||
cursor: pointer
|
||||
position: relative
|
||||
line-height: 14px
|
||||
margin-right: 0
|
||||
button
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 5px
|
||||
a
|
||||
margin-left: 10px
|
||||
position: inherit
|
||||
visibility: hidden
|
||||
display: inline-block
|
||||
span:hover:not(.badge)
|
||||
background-color: $hover-background
|
||||
li:hover a
|
||||
visibility: visible
|
||||
//Customize for searchview label
|
||||
label
|
||||
font-weight: normal
|
||||
//End of Customize
|
||||
.oe_searchview_dashboard
|
||||
form
|
||||
display: none
|
||||
margin-top: 2px
|
||||
.oe-add-condition
|
||||
width: auto
|
||||
margin-left: 10px
|
||||
padding-left: 0
|
||||
padding-right: 10px
|
||||
.oe-group-selector
|
||||
margin: 3px 25px
|
||||
min-width: calc(100% - 40px)
|
||||
max-width: 250px
|
||||
width: auto
|
||||
.divider
|
||||
display: none
|
||||
.filters-menu
|
||||
.divider
|
||||
display: list-item
|
||||
.closed-menu
|
||||
a:before
|
||||
font-family: FontAwesome
|
||||
position: absolute
|
||||
left: 12px
|
||||
top: 3px
|
||||
content: "\f0da"
|
||||
.open-menu
|
||||
a:before
|
||||
font-family: FontAwesome
|
||||
position: absolute
|
||||
left: 9px
|
||||
top: 3px
|
||||
content: "\f0d7"
|
||||
|
||||
.oe_searchview_advanced
|
||||
overflow: auto
|
||||
form
|
||||
display: none
|
||||
margin-top: 8px
|
||||
button.oe_add_condition:before
|
||||
content: "Z"
|
||||
font-family: "entypoRegular" !important
|
||||
font-size: 24px
|
||||
font-weight: 300 !important
|
||||
margin-right: 4px
|
||||
ul
|
||||
list-style: none
|
||||
padding: 0
|
||||
li
|
||||
position: relative
|
||||
list-style: none
|
||||
margin: 0
|
||||
.oe-select-group
|
||||
margin: 3px 25px
|
||||
.oe-add-group
|
||||
display: none
|
||||
.oe-save-name
|
||||
display: none
|
||||
margin: 3px 25px
|
||||
span
|
||||
white-space: nowrap
|
||||
&:first-child .searchview_extended_prop_or
|
||||
visibility: hidden
|
||||
margin-left: -14px
|
||||
.searchview_extended_prop_or
|
||||
opacity: 0.5
|
||||
margin-left: -14px //Customize 'or' in searchview
|
||||
.oe_opened
|
||||
h4:before
|
||||
content: "▾ "
|
||||
position: relative
|
||||
top: -1px
|
||||
form
|
||||
display: block
|
||||
|
||||
// delete buttons
|
||||
.oe_searchview_custom_delete, .searchview_extended_delete_prop
|
||||
display: inline-block
|
||||
width: 12px
|
||||
height: 12px
|
||||
line-height: 12px
|
||||
padding: 1px
|
||||
color: #8786b7
|
||||
line-height: 8px
|
||||
text-align: center
|
||||
font-weight: bold
|
||||
text-shadow: 0 1px 1px white
|
||||
&:hover
|
||||
text-decoration: none
|
||||
color: white
|
||||
background: #8786b7
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4)
|
||||
@include radius(2px)
|
||||
.oe_searchview_custom_delete
|
||||
display: none
|
||||
input
|
||||
margin-left: 0
|
||||
.searchview_extended_prop_field
|
||||
display: inline
|
||||
width: calc(100% - 20px)
|
||||
|
||||
.searchview_extended_prop_op
|
||||
margin: 3px 0
|
||||
width: calc(100% - 20px)
|
||||
.searchview_extended_delete_prop
|
||||
float: right
|
||||
display: inline
|
||||
.searchview_extended_prop_value
|
||||
width: calc(100% - 20px)
|
||||
> select, > input
|
||||
width: calc(100% - 20px)
|
||||
.oe_datepicker_main
|
||||
width: calc(100% - 20px)
|
||||
.oe_datepicker_master
|
||||
width: 100%
|
||||
.fa-calendar
|
||||
margin-left: -21px
|
||||
cursor: pointer
|
||||
span.fa-trash-o
|
||||
position: absolute
|
||||
bottom: 1px
|
||||
right: 4px
|
||||
.oe_searchview_custom_private, .oe_searchview_custom_public
|
||||
&:hover
|
||||
.oe_searchview_custom_delete
|
||||
display: inline-block
|
||||
.oe_searchview_custom_public:after
|
||||
content: ","
|
||||
font-family: "entypoRegular" !important
|
||||
font-size: 22px
|
||||
font-weight: 300 !important
|
||||
margin: 0 0 0 4px
|
||||
padding: 0
|
||||
top: 6px
|
||||
right: 10px
|
||||
cursor: pointer
|
||||
.dropdown-menu
|
||||
> li
|
||||
position: relative
|
||||
white-space: nowrap
|
||||
li.oe-filter-condition
|
||||
white-space: normal
|
||||
padding-left: 25px
|
||||
padding-right: 10px
|
||||
margin-bottom: 5px
|
||||
a
|
||||
display: inline-block
|
||||
|
||||
input.oe-save-name
|
||||
width: auto
|
||||
.oe_pager_value
|
||||
display: inline-block
|
||||
|
||||
// }}}
|
||||
// Views Common {{{
|
||||
.oe_view_nocontent
|
||||
@@ -1784,6 +1568,9 @@ $sheet-padding: 16px
|
||||
width: auto
|
||||
.oe_datepicker_root
|
||||
display: inline-block
|
||||
.datepickerbutton
|
||||
margin-left: 5px
|
||||
cursor: pointer
|
||||
.oe_form_required
|
||||
input:not([disabled]):not([readonly]), select:not([disabled]):not([readonly]), textarea:not([disabled]):not([readonly])
|
||||
background-color: #D2D2FF !important
|
||||
@@ -2360,6 +2147,8 @@ $sheet-padding: 16px
|
||||
content: "[newline]"
|
||||
.oe_debug_view
|
||||
float: left
|
||||
margin-top: 5px
|
||||
width: auto
|
||||
.oe_debug_view_log
|
||||
font-size: 95%
|
||||
line-height: 1.2em
|
||||
@@ -2410,8 +2199,6 @@ $sheet-padding: 16px
|
||||
background-color: #7c7bad
|
||||
|
||||
// Customize for global tags
|
||||
button, body
|
||||
line-height: normal
|
||||
h1,h2
|
||||
font-weight: bold
|
||||
h3
|
||||
@@ -2447,8 +2234,6 @@ $sheet-padding: 16px
|
||||
|
||||
@-moz-document url-prefix()
|
||||
.openerp
|
||||
.oe_searchview .oe_searchview_search
|
||||
top: -1px
|
||||
.oe_form_field_many2one .oe_m2o_cm_button
|
||||
line-height: 18px
|
||||
.oe_webclient
|
||||
|
||||
@@ -287,7 +287,17 @@ openerp.ParentedMixin = {
|
||||
});
|
||||
this.setParent(undefined);
|
||||
this.__parentedDestroyed = true;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Find the closest ancestor matching predicate
|
||||
*/
|
||||
findAncestor: function (predicate) {
|
||||
var ancestor = this;
|
||||
while (!(predicate(ancestor)) && ancestor && ancestor.getParent) {
|
||||
ancestor = ancestor.getParent();
|
||||
}
|
||||
return ancestor;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+585
-818
File diff suppressed because it is too large
Load Diff
@@ -85,8 +85,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
|
||||
* @param {instance.web.Session} session the current openerp session
|
||||
* @param {instance.web.DataSet} dataset the dataset this view will work with
|
||||
* @param {String} view_id the identifier of the OpenERP view object
|
||||
* @param {Object} options
|
||||
* - resize_textareas : [true|false|max_height]
|
||||
*
|
||||
* @property {instance.web.Registry} registry=instance.web.form.widgets widgets registry for this form view instance
|
||||
*/
|
||||
@@ -257,7 +255,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
|
||||
this.dataset.ids.push(state.id);
|
||||
}
|
||||
this.dataset.select_id(state.id);
|
||||
this.do_show({ reload: warm });
|
||||
this.do_show();
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -425,7 +423,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
|
||||
$el.removeAttr("disabled");
|
||||
});
|
||||
});
|
||||
this.do_update_pager();
|
||||
},
|
||||
do_update_pager: function(hide_index) {
|
||||
this.$pager.toggle(this.dataset.ids.length > 1);
|
||||
@@ -3973,7 +3970,6 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
|
||||
disable_utility_classes: true,
|
||||
init: function(field_manager, node) {
|
||||
this._super(field_manager, node);
|
||||
lazy_build_o2m_kanban_view();
|
||||
this.is_loaded = $.Deferred();
|
||||
this.initial_is_loaded = this.is_loaded;
|
||||
this.form_last_update = $.Deferred();
|
||||
@@ -4143,14 +4139,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
|
||||
/**
|
||||
* Returns the current active view if any.
|
||||
*/
|
||||
if (this.viewmanager && this.viewmanager.views && this.viewmanager.active_view &&
|
||||
this.viewmanager.views[this.viewmanager.active_view] &&
|
||||
this.viewmanager.views[this.viewmanager.active_view].controller) {
|
||||
return {
|
||||
type: this.viewmanager.active_view,
|
||||
controller: this.viewmanager.views[this.viewmanager.active_view].controller
|
||||
};
|
||||
}
|
||||
return (this.viewmanager && this.viewmanager.active_view);
|
||||
},
|
||||
set_value: function(value_) {
|
||||
value_ = value_ || [];
|
||||
@@ -4242,12 +4231,12 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
|
||||
save_any_view: function() {
|
||||
var view = this.get_active_view();
|
||||
if (view) {
|
||||
if (this.viewmanager.active_view === "form") {
|
||||
if (this.viewmanager.active_view.type === "form") {
|
||||
if (view.controller.is_initialized.state() !== 'resolved') {
|
||||
return $.when(false);
|
||||
}
|
||||
return $.when(view.controller.save());
|
||||
} else if (this.viewmanager.active_view === "list") {
|
||||
} else if (this.viewmanager.active_view.type === "list") {
|
||||
return $.when(view.controller.ensure_saved());
|
||||
}
|
||||
}
|
||||
@@ -4258,7 +4247,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
|
||||
if (!view){
|
||||
return true;
|
||||
}
|
||||
switch (this.viewmanager.active_view) {
|
||||
switch (this.viewmanager.active_view.type) {
|
||||
case 'form':
|
||||
return _(view.controller.fields).chain()
|
||||
.invoke('is_valid')
|
||||
@@ -4275,10 +4264,9 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({
|
||||
template: 'One2Many.viewmanager',
|
||||
init: function(parent, dataset, views, flags) {
|
||||
this._super(parent, dataset, views, _.extend({}, flags, {$sidebar: false}));
|
||||
this.registry = this.registry.extend({
|
||||
this.registry = instance.web.views.extend({
|
||||
list: 'instance.web.form.One2ManyListView',
|
||||
form: 'instance.web.form.One2ManyFormView',
|
||||
kanban: 'instance.web.form.One2ManyKanbanView',
|
||||
});
|
||||
this.__ignore_blur = false;
|
||||
},
|
||||
@@ -4548,13 +4536,6 @@ instance.web.form.One2ManyFormView = instance.web.FormView.extend({
|
||||
}
|
||||
});
|
||||
|
||||
var lazy_build_o2m_kanban_view = function() {
|
||||
if (! instance.web_kanban || instance.web.form.One2ManyKanbanView)
|
||||
return;
|
||||
instance.web.form.One2ManyKanbanView = instance.web_kanban.KanbanView.extend({
|
||||
});
|
||||
};
|
||||
|
||||
instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(instance.web.form.CompletionFieldMixin, instance.web.form.ReinitializeFieldMixin, {
|
||||
template: "FieldMany2ManyTags",
|
||||
tag_template: "FieldMany2ManyTag",
|
||||
@@ -5147,8 +5128,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
|
||||
this.domain = domain || [];
|
||||
this.context = context || {};
|
||||
this.options = options;
|
||||
_.defaults(this.options, {
|
||||
});
|
||||
_.defaults(this.options, {});
|
||||
},
|
||||
init_dataset: function() {
|
||||
var self = this;
|
||||
@@ -5293,22 +5273,20 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
|
||||
this.display_popup();
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this.init_dataset();
|
||||
if (this.options.initial_view == "search") {
|
||||
instance.web.pyeval.eval_domains_and_contexts({
|
||||
var context = instance.web.pyeval.sync_eval_domains_and_contexts({
|
||||
domains: [],
|
||||
contexts: [this.context]
|
||||
}).done(function (results) {
|
||||
var search_defaults = {};
|
||||
_.each(results.context, function (value_, key) {
|
||||
var match = /^search_default_(.*)$/.exec(key);
|
||||
if (match) {
|
||||
search_defaults[match[1]] = value_;
|
||||
}
|
||||
});
|
||||
self.setup_search_view(search_defaults);
|
||||
}).context;
|
||||
var search_defaults = {};
|
||||
_.each(context, function (value_, key) {
|
||||
var match = /^search_default_(.*)$/.exec(key);
|
||||
if (match) {
|
||||
search_defaults[match[1]] = value_;
|
||||
}
|
||||
});
|
||||
this.setup_search_view(search_defaults);
|
||||
} else { // "form"
|
||||
this.new_object();
|
||||
}
|
||||
@@ -5318,12 +5296,9 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
|
||||
if (this.searchview) {
|
||||
this.searchview.destroy();
|
||||
}
|
||||
if (this.searchview_drawer) {
|
||||
this.searchview_drawer.destroy();
|
||||
}
|
||||
var $buttons = this.$('.oe-search-options');
|
||||
this.searchview = new instance.web.SearchView(this,
|
||||
this.dataset, false, search_defaults);
|
||||
this.searchview_drawer = new instance.web.SearchViewDrawer(this, this.searchview);
|
||||
this.dataset, false, search_defaults, {$buttons: $buttons});
|
||||
this.searchview.on('search_data', self, function(domains, contexts, groupbys) {
|
||||
if (self.initial_ids) {
|
||||
self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]),
|
||||
@@ -5333,7 +5308,8 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
|
||||
self.do_search(domains.concat([self.domain]), contexts.concat(self.context), groupbys);
|
||||
}
|
||||
});
|
||||
this.searchview.on("search_view_loaded", self, function() {
|
||||
this.searchview.appendTo(this.$(".oe_popup_search")).done(function() {
|
||||
self.searchview.toggle_visibility(true);
|
||||
self.view_list = new instance.web.form.SelectCreateListView(self,
|
||||
self.dataset, false,
|
||||
_.extend({'deletable': false,
|
||||
@@ -5368,8 +5344,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
|
||||
self.new_object();
|
||||
});
|
||||
});
|
||||
});
|
||||
this.searchview.appendTo(this.$(".oe_popup_search"));
|
||||
});
|
||||
},
|
||||
do_search: function(domains, contexts, groupbys) {
|
||||
var self = this;
|
||||
|
||||
@@ -289,7 +289,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
|
||||
|
||||
// Pager
|
||||
if (!this.$pager) {
|
||||
this.$pager = $(QWeb.render("ListView.pager", {'widget':self}));
|
||||
this.$pager = $(QWeb.render("ListView.pager", {'widget':self})).hide();
|
||||
if (this.options.$buttons) {
|
||||
this.$pager.appendTo(this.options.$pager);
|
||||
} else {
|
||||
@@ -404,11 +404,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
|
||||
|
||||
var total = dataset.size();
|
||||
var limit = this.limit() || total;
|
||||
if (total === 0)
|
||||
this.$pager.hide();
|
||||
else
|
||||
this.$pager.css("display", "");
|
||||
this.$pager.toggleClass('oe_list_pager_single_page', (total <= limit));
|
||||
this.$pager.find('.oe-pager-button').toggle(total > limit);
|
||||
this.$pager.find('.oe_pager_value').toggle(total !== 0);
|
||||
var spager = '-';
|
||||
if (total) {
|
||||
var range_start = this.page * limit + 1;
|
||||
@@ -1517,12 +1514,10 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
|
||||
}))
|
||||
.end()
|
||||
.find('button[data-pager-action=previous]')
|
||||
.css('visibility',
|
||||
page === 0 ? 'hidden' : '')
|
||||
.toggleClass('disabled', page === 0)
|
||||
.end()
|
||||
.find('button[data-pager-action=next]')
|
||||
.css('visibility',
|
||||
page === pages - 1 ? 'hidden' : '');
|
||||
.toggleClass('disabled', page === pages - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*---------------------------------------------------------
|
||||
* Odoo Pivot Table view
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var instance = openerp,
|
||||
_lt = instance.web._lt,
|
||||
_t = instance.web._t,
|
||||
QWeb = instance.web.qweb;
|
||||
|
||||
instance.web.views.add('pivot', 'instance.web.PivotView');
|
||||
|
||||
instance.web.PivotView = instance.web.View.extend({
|
||||
template: 'PivotView',
|
||||
display_name: _lt('Pivot'),
|
||||
view_type: 'pivot',
|
||||
|
||||
init: function(parent, dataset, view_id, options) {
|
||||
this._super(parent, dataset, view_id, options);
|
||||
this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true});
|
||||
this.action_manager = parent.action_manager;
|
||||
|
||||
this.$buttons = options.$buttons;
|
||||
this.fields = {};
|
||||
this.measures = {};
|
||||
this.groupable_fields = {};
|
||||
|
||||
this.row_groupbys = [];
|
||||
this.col_groupbys = [];
|
||||
this.active_measures = [];
|
||||
},
|
||||
start: function () {
|
||||
var self = this,
|
||||
load_fields = this.model.call('fields_get', [])
|
||||
.then(this.prepare_fields.bind(this));
|
||||
|
||||
return $.when(this._super(), load_fields).then(function () {
|
||||
var context = {measures: _.pairs(self.measures)};
|
||||
self.$buttons.html(QWeb.render('PivotView.buttons', self), context);
|
||||
});
|
||||
},
|
||||
view_loading: function (fvg) {
|
||||
var self = this;
|
||||
this.do_push_state({});
|
||||
fvg.arch.children.forEach(function (field) {
|
||||
var name = field.attrs.name + (field.attrs.interval || '');
|
||||
//noinspection FallThroughInSwitchStatementJS
|
||||
switch (field.attrs.type) {
|
||||
case 'measure':
|
||||
self.active_measures.push(name);
|
||||
break;
|
||||
case 'col':
|
||||
self.col_groupbys.push(name);
|
||||
break;
|
||||
default:
|
||||
if ('operator' in field.attrs) {
|
||||
self.active_measures.push(name);
|
||||
break;
|
||||
}
|
||||
case 'row':
|
||||
self.row_groupbys.push(name);
|
||||
}
|
||||
});
|
||||
},
|
||||
prepare_fields: function (fields) {
|
||||
var self = this,
|
||||
groupable_types = ['many2one', 'char', 'boolean',
|
||||
'selection', 'date', 'datetime'];
|
||||
this.fields = fields;
|
||||
_.each(fields, function (field, name) {
|
||||
if ((name !== 'id') && (field.store === true)) {
|
||||
if (field.type === 'integer' || field.type === 'float') {
|
||||
self.measures[name] = field;
|
||||
}
|
||||
if (_.contains(groupable_types, field.type)) {
|
||||
self.groupable_fields[name] = field;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
do_search: function (domain, context, group_by) {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
})();
|
||||
|
||||
+380
-606
File diff suppressed because it is too large
Load Diff
+253
-324
@@ -25,13 +25,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="Tipsy.alert">
|
||||
<a class="oe_tooltip_close oe_e">[</a>
|
||||
<span style="float:left; margin:2px 5px 0 0;" class="ui-icon ui-icon-alert ui-state-error"></span>
|
||||
<div class="oe_tooltip_message">
|
||||
<t t-esc="message"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="Dialog">
|
||||
<div class="modal" tabindex="-1" data-backdrop="static" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
@@ -476,82 +469,76 @@
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="ViewManager">
|
||||
<div class="oe_view_manager">
|
||||
<table class="oe_view_manager_header">
|
||||
<col width="20%"/>
|
||||
<col width="35%"/>
|
||||
<col width="15%"/>
|
||||
<col width="30%"/>
|
||||
<tr class="oe_header_row oe_header_row_top">
|
||||
<td colspan="2">
|
||||
<h2 class="oe_view_title" t-if="widget.flags.display_title !== false">
|
||||
<span class="oe_view_title_text oe_breadcrumb_title"/>
|
||||
</h2>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<div class="oe_view_manager_view_search"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="oe_header_row">
|
||||
<td>
|
||||
<div class="oe_view_manager_buttons"/>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<div class="oe_view_manager_sidebar"/>
|
||||
</td>
|
||||
<td>
|
||||
<ul class="oe_view_manager_switch oe_button_group oe_right">
|
||||
<t t-if="widget.views_src.length > 1" t-foreach="widget.views_src" t-as="view">
|
||||
<li class="oe_e">
|
||||
<a t-attf-class="oe_vm_switch_#{view.view_type}" t-att-data-view-type="view.view_type"
|
||||
t-att-title="view.button_label"/>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
<div class="oe_view_manager_pager oe_right"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="oe_view_manager_wrapper">
|
||||
<div>
|
||||
<div class="oe_view_manager_body">
|
||||
<div class="oe_searchview_drawer_container"/>
|
||||
<t t-foreach="widget.views_src" t-as="view">
|
||||
<div t-attf-class="oe_view_manager_view_#{view.view_type}"/>
|
||||
<div t-name="ViewManager" class="oe-view-manager">
|
||||
<div class="oe-view-manager-header container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-6 oe-header-title">
|
||||
<div t-if="widget.session.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>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="oe-view-manager-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>
|
||||
<div class="col-md-6">
|
||||
<div class="oe-search-options btn-group"/>
|
||||
<div class="oe-right-toolbar">
|
||||
<div class="oe-view-manager-pager"></div>
|
||||
<t t-if="widget.multiple_views">
|
||||
<div class="oe-view-manager-switch 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" t-if="view.type!=='form'">
|
||||
</button>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="ViewManagerAction" t-extend="ViewManager">
|
||||
<t t-jquery="h2.oe_view_title" t-operation="before">
|
||||
<select t-if="widget.session.debug" class="oe_debug_view"/>
|
||||
</t>
|
||||
</t>
|
||||
<div class="oe-view-manager-content">
|
||||
<div class="oe-view-manager-body">
|
||||
<div class="oe-view-manager-views">
|
||||
<t t-foreach="widget.views" t-as="view">
|
||||
<div t-attf-class="oe-view-manager-view-#{view}"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<t t-name="ViewManagerDebug">
|
||||
<option value="">Debug View#<t t-esc="view.fields_view.view_id"/></option>
|
||||
<t t-if="view_manager.active_view === 'form'">
|
||||
<option value="get_metadata">View Metadata</option>
|
||||
<option value="toggle_layout_outline">Toggle Form Layout Outline</option>
|
||||
<option value="set_defaults">Set Defaults</option>
|
||||
</t>
|
||||
<option value="tests">JS Tests</option>
|
||||
<option value="fields">View Fields</option>
|
||||
<option value="fvg">Fields View Get</option>
|
||||
<option value="manage_filters">Manage Filters</option>
|
||||
<t t-if="view_manager.session.uid === 1">
|
||||
<option value="translate">Technical translation</option>
|
||||
<option value="manage_views">Manage Views</option>
|
||||
<option value="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</option>
|
||||
<option t-if="view_manager.searchview" value="edit" data-model="ir.ui.view" t-att-data-id="view_manager.searchview.view_id">Edit SearchView</option>
|
||||
<option t-if="view_manager.action" value="edit" t-att-data-model="view_manager.action.type" t-att-data-id="view_manager.action.id">Edit Action</option>
|
||||
<option value="edit_workflow">Edit Workflow</option>
|
||||
<option value="print_workflow">Print Workflow</option>
|
||||
</t>
|
||||
<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'">
|
||||
<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>
|
||||
</t>
|
||||
<li><a data-action="tests">JS Tests</a></li>
|
||||
<li><a data-action="fields">View Fields</a></li>
|
||||
<li><a data-action="fvg">Fields View Get</a></li>
|
||||
<li><a data-action="manage_filters">Manage Filters</a></li>
|
||||
<t t-if="view_manager.session.uid === 1">
|
||||
<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><a data-action="edit_workflow">Edit Workflow</a></li>
|
||||
<li><a data-action="print_workflow">Print Workflow</a></li>
|
||||
<li class="divider"/>
|
||||
<li><a data-action="leave_debug">Leave Debug Mode</a></li>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
<t t-name="ViewManagerDebugViewLog">
|
||||
<div class="oe_debug_view_log">
|
||||
@@ -583,83 +570,69 @@
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="ViewPager">
|
||||
<div t-name="ViewPager">
|
||||
<div class="oe_pager_value">
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
<ul class="oe_pager_group">
|
||||
<!--
|
||||
<button class="oe_button oe_button_pager" type="button" data-pager-action="first">
|
||||
<img t-att-src='_s + "/web/static/src/img/pager_first.png"'/>
|
||||
</button>
|
||||
-->
|
||||
<li>
|
||||
<a class="oe_i" type="button" data-pager-action="previous">(</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="oe_i" type="button" data-pager-action="next">)</a>
|
||||
</li>
|
||||
<!--
|
||||
<button class="oe_button oe_button_pager" type="button" data-pager-action="last">
|
||||
<img t-att-src='_s + "/web/static/src/img/pager_last.png"'/>
|
||||
</button>
|
||||
-->
|
||||
</ul>
|
||||
</t>
|
||||
|
||||
<t t-name="Sidebar">
|
||||
<div class="oe_sidebar">
|
||||
<t t-foreach="widget.sections" t-as="section">
|
||||
<div class="oe_form_dropdown_section">
|
||||
<button class="oe_dropdown_toggle oe_dropdown_arrow" t-if="section.name != 'buttons'">
|
||||
<t t-if="section.name == 'files'" t-raw="widget.items[section.name].length || ''"/>
|
||||
<t t-esc="section.label"/>
|
||||
<i class="fa fa-caret-down"/>
|
||||
</button>
|
||||
<t t-if="section.name == 'buttons'" t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname">
|
||||
<button t-att-title="item.title or ''" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url"
|
||||
target="_blank" class="oe_sidebar_button oe_highlight">
|
||||
<t t-raw="item.label"/>
|
||||
</button>
|
||||
</t>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<li t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname">
|
||||
<t t-if="section.name == 'files'">
|
||||
<t t-set="item.title">
|
||||
<b>Attachment : </b><br/>
|
||||
<t t-raw="item.name"/>
|
||||
</t>
|
||||
<t t-if="item.create_uid and item.create_uid[0]" t-set="item.title">
|
||||
<t t-raw="item.title"/><br/>
|
||||
<b>Created by : </b><br/>
|
||||
<t t-raw="item.create_uid[1] + ' ' + item.create_date"/>
|
||||
</t>
|
||||
<t t-if="item.create_uid and item.write_uid and item.create_uid[0] != item.write_uid[0]" t-set="item.title">
|
||||
<t t-raw="item.title"/><br/>
|
||||
<b>Modified by : </b><br/>
|
||||
<t t-raw="item.write_uid[1] + ' ' + item.write_date"/>
|
||||
</t>
|
||||
</t>
|
||||
<a class="oe_sidebar_action_a" t-att-title="item.title or ''" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url" target="_blank">
|
||||
<t t-raw="item.label"/>
|
||||
</a>
|
||||
<a t-if="section.name == 'files' and !item.callback" class="oe_sidebar_delete_item" t-att-data-id="item.id" title="Delete this attachment">x</a>
|
||||
</li>
|
||||
<li t-if="section.name == 'files'" class="oe_sidebar_add_attachment">
|
||||
<t t-call="HiddenInputFile">
|
||||
<t t-set="fileupload_id" t-value="widget.fileupload_id"/>
|
||||
<t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t>
|
||||
<input type="hidden" name="model" t-att-value="widget.dataset and widget.dataset.model"/>
|
||||
<input type="hidden" name="id" t-att-value="widget.model_id"/>
|
||||
<input type="hidden" name="session_id" t-att-value="widget.session.session_id" t-if="widget.session.override_session"/>
|
||||
<span>Add...</span>
|
||||
</t>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
<div class="btn-group btn-group-sm oe-pager-buttons">
|
||||
<a class="fa fa-chevron-left btn btn-default oe-pager-button" type="button" data-pager-action="previous"></a>
|
||||
<a class="fa fa-chevron-right btn btn-default oe-pager-button" type="button" data-pager-action="next"></a>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<div t-name="Sidebar" class="oe_sidebar btn-group">
|
||||
<t t-foreach="widget.sections" t-as="section">
|
||||
<div class="oe_form_dropdown_section btn-group btn-group-sm">
|
||||
<button class="btn btn-default dropdown-toggle"
|
||||
t-if="section.name != 'buttons'"
|
||||
data-toggle="dropdown">
|
||||
<t t-if="section.name == 'files'" t-raw="widget.items[section.name].length || ''"/>
|
||||
<t t-esc="section.label"/>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<t t-if="section.name == 'buttons'" t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname">
|
||||
<button t-att-title="item.title or ''" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url"
|
||||
target="_blank" class="oe_sidebar_button oe_highlight">
|
||||
<t t-raw="item.label"/>
|
||||
</button>
|
||||
</t>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname">
|
||||
<t t-if="section.name == 'files'">
|
||||
<t t-set="item.title">
|
||||
<b>Attachment : </b><br/>
|
||||
<t t-raw="item.name"/>
|
||||
</t>
|
||||
<t t-if="item.create_uid and item.create_uid[0]" t-set="item.title">
|
||||
<t t-raw="item.title"/><br/>
|
||||
<b>Created by : </b><br/>
|
||||
<t t-raw="item.create_uid[1] + ' ' + item.create_date"/>
|
||||
</t>
|
||||
<t t-if="item.create_uid and item.write_uid and item.create_uid[0] != item.write_uid[0]" t-set="item.title">
|
||||
<t t-raw="item.title"/><br/>
|
||||
<b>Modified by : </b><br/>
|
||||
<t t-raw="item.write_uid[1] + ' ' + item.write_date"/>
|
||||
</t>
|
||||
</t>
|
||||
<a class="oe_file_attachment" t-att-title="item.title or ''" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url">
|
||||
<t t-raw="item.label"/>
|
||||
</a>
|
||||
<a t-if="section.name == 'files' and !item.callback" class="oe_sidebar_delete_item" t-att-data-id="item.id" title="Delete this attachment">x</a>
|
||||
</li>
|
||||
<li t-if="section.name == 'files'" class="oe_sidebar_add_attachment">
|
||||
<t t-call="HiddenInputFile">
|
||||
<t t-set="fileupload_id" t-value="widget.fileupload_id"/>
|
||||
<t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t>
|
||||
<input type="hidden" name="model" t-att-value="widget.dataset and widget.dataset.model"/>
|
||||
<input type="hidden" name="id" t-att-value="widget.model_id"/>
|
||||
<input type="hidden" name="session_id" t-att-value="widget.session.session_id" t-if="widget.session.override_session"/>
|
||||
<span>Add...</span>
|
||||
</t>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<t t-name="TreeView">
|
||||
<select t-if="toolbar" style="width: 30%">
|
||||
@@ -745,19 +718,14 @@
|
||||
<t t-name="ListView.buttons">
|
||||
<div class="oe_list_buttons">
|
||||
<t t-if="!widget.no_leaf and widget.options.action_buttons !== false and widget.options.addable and widget.is_action_enabled('create')">
|
||||
<button type="button" class="oe_button oe_list_add oe_highlight">
|
||||
<button type="button" class="oe_list_add btn btn-primary btn-sm">
|
||||
<t t-esc="widget.options.addable"/>
|
||||
</button>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="ListView.pager">
|
||||
<div class="oe_list_pager" t-att-colspan="widget.columns_count">
|
||||
<t t-if="!widget.no_leaf and widget.options.pager !== false" t-call="ViewPager">
|
||||
<span class="oe_list_pager_state">
|
||||
</span>
|
||||
</t>
|
||||
</div>
|
||||
<t t-name="ListView.pager" t-if="!widget.no_leaf and widget.options.pager !== false" t-call="ViewPager">
|
||||
<span class="oe_list_pager_state"></span>
|
||||
</t>
|
||||
<t t-name="ListView.rows" t-foreach="records.length" t-as="index">
|
||||
<t t-call="ListView.row">
|
||||
@@ -825,29 +793,29 @@
|
||||
<div class="oe_form_container"/>
|
||||
</div>
|
||||
</t>
|
||||
<div t-name="FormView.buttons" class="oe_form_buttons">
|
||||
<div t-name="FormView.buttons">
|
||||
<t t-if="widget.options.action_buttons !== false">
|
||||
<span class="oe_form_buttons_view">
|
||||
<!-- required for the bounce effect on button -->
|
||||
<div t-if="widget.is_action_enabled('edit')" style="display: inline-block;">
|
||||
<button type="button" class="oe_button oe_form_button_edit" accesskey="E">Edit</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm oe_form_buttons_view">
|
||||
<button t-if="widget.is_action_enabled('edit')"
|
||||
type="button"
|
||||
class="oe_form_button_edit btn btn-default" accesskey="E">
|
||||
Edit
|
||||
</button>
|
||||
<button t-if="widget.is_action_enabled('create')"
|
||||
type="button" class="oe_button oe_form_button_create" accesskey="C">Create</button>
|
||||
</span>
|
||||
type="button" class="oe_form_button_create btn btn-default"
|
||||
accesskey="C">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
<span class="oe_form_buttons_edit">
|
||||
<button type="button" class="oe_button oe_form_button_save oe_highlight" accesskey="S">Save</button>
|
||||
<button type="button" class="oe_form_button_save btn btn-primary btn-sm" accesskey="S">Save</button>
|
||||
<span class="oe_fade">or</span>
|
||||
<a href="#" class="oe_bold oe_form_button_cancel" accesskey="D">Discard</a>
|
||||
</span>
|
||||
</t>
|
||||
</div>
|
||||
<t t-name="FormView.pager">
|
||||
<div class="oe_form_pager">
|
||||
<t t-if="widget.options.pager !== false" t-call="ViewPager">
|
||||
<span class="oe_form_pager_state"></span>
|
||||
</t>
|
||||
</div>
|
||||
<t t-name="FormView.pager" t-if="widget.options.pager !== false" t-call="ViewPager">
|
||||
<span class="oe_form_pager_state"></span>
|
||||
</t>
|
||||
<form t-name="FormView.set_default">
|
||||
<t t-set="args" t-value="widget.dialog_options.args"/>
|
||||
@@ -947,6 +915,37 @@
|
||||
</label>
|
||||
</t>
|
||||
|
||||
<div t-name="PivotView" class="oe_pivot"/>
|
||||
|
||||
<t t-name="PivotView.buttons">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button class="btn btn-default fa fa-expand oe-pivot-flip"></button>
|
||||
<button class="btn btn-default fa fa-arrows-alt oe-pivot-expand-all"></button>
|
||||
<button class="btn btn-default fa fa-download oe-pivot-download"></button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
Measures <span class="caret"/>
|
||||
</button>
|
||||
<ul class="oe-measure-list dropdown-menu">
|
||||
<li t-foreach="measures" t-as="measure" t-att-data-field="measure">
|
||||
<a><t t-esc="measures[measure].string"/></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<div t-name="PivotView.nodata" class="oe_view_nocontent" >
|
||||
<div class="oe_empty_custom_dashboard">
|
||||
<p><b>No data to display.</b></p>
|
||||
<p>
|
||||
No data available for this pivot table. Try to add some records, or make sure
|
||||
that there is at least one measure and no active filter in the search bar.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<t t-name="Widget">
|
||||
Unhandled widget
|
||||
<t t-js="dict">console.warn('Unhandled widget', dict.widget);</t>
|
||||
@@ -1129,9 +1128,7 @@
|
||||
t-att-name="widget.name"
|
||||
t-att-placeholder="placeholder"
|
||||
class="oe_datepicker_master"
|
||||
/><span><img class="oe_input_icon oe_datepicker_trigger datepickerbutton" draggable="false"
|
||||
t-att-src='_s + "/web/static/src/img/ui/field_calendar.png"'
|
||||
title="Select date" width="16" height="16" border="0"/></span>
|
||||
/><span class="fa fa-calendar datepickerbutton"/>
|
||||
</div>
|
||||
</span>
|
||||
</t>
|
||||
@@ -1489,11 +1486,8 @@
|
||||
<table style="width:100%">
|
||||
<tr style="width:100%">
|
||||
<td style="width:100%">
|
||||
<div class="oe_popup_search" style="width:100%"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="width:100%">
|
||||
<td style="width:100%">
|
||||
<div class="oe-search-options btn-group"/>
|
||||
<div class="oe_popup_search"></div>
|
||||
<div class="oe_popup_list_pager"></div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1537,7 +1531,7 @@
|
||||
|
||||
<t t-name="One2Many.viewmanager" t-extend="ViewManager">
|
||||
<t t-jquery=".oe-view-manager-header">
|
||||
this.attr('t-if', 'views.length != 1');
|
||||
this.attr('t-if', 'widget.view_order.length != 1');
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="One2Many.formview" t-extend="FormView">
|
||||
@@ -1558,17 +1552,10 @@
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<div t-name="SearchView" class="oe_searchview">
|
||||
<div t-name="SearchView" class="oe_searchview form-control input-sm">
|
||||
<div class="oe_searchview_search fa fa-lg fa-search" title="Search Again"/>
|
||||
<div class="oe_searchview_facets"/>
|
||||
<div class="oe_searchview_clear"/>
|
||||
<div class="oe_searchview_unfold_drawer" title="Advanced Search..."/>
|
||||
<button type="button" class="oe_searchview_search"
|
||||
title="Search Again">Search</button>
|
||||
</div>
|
||||
|
||||
<div t-name="SearchViewDrawer" class="oe_searchview_drawer" style="display:none;">
|
||||
<div class="col-md-7"></div>
|
||||
<div class="col-md-5"></div>
|
||||
<div class="oe_searchview_unfold_drawer fa fa-lg fa-fw fa-chevron-right" title="Advanced Search..."/>
|
||||
</div>
|
||||
|
||||
<div t-name="SearchView.InputView"
|
||||
@@ -1577,86 +1564,28 @@
|
||||
tabindex="0"/>
|
||||
<!-- tabindex: makes div focusable -->
|
||||
<div t-name="SearchView.FacetView"
|
||||
class="oe_tag oe_tag_dark oe_searchview_facet"
|
||||
tabindex="0"
|
||||
><span class="oe_facet_remove">x</span
|
||||
><span class="oe_facet_category oe_i" t-if="widget.model.has('icon')">
|
||||
<t t-esc="widget.model.get('icon')"/>
|
||||
</span
|
||||
><span class="oe_facet_category" t-if="!widget.model.has('icon')">
|
||||
class="oe_tag oe_searchview_facet"
|
||||
tabindex="0">
|
||||
<span class="oe_facet_remove">x</span>
|
||||
<span t-if="widget.model.has('icon')"
|
||||
t-att-class="'label label-default fa ' + widget.model.get('icon')">
|
||||
</span>
|
||||
<span class="label label-default" t-if="!widget.model.has('icon')">
|
||||
<t t-esc="widget.model.get('category')"/>
|
||||
</span ><span class="oe_facet_values"
|
||||
/></div>
|
||||
</span >
|
||||
<span class="oe_facet_values"/>
|
||||
</div>
|
||||
<span t-name="SearchView.FacetView.Value" class="oe_facet_value">
|
||||
<t t-esc="widget.model.get('label')"/>
|
||||
</span>
|
||||
<t t-name="SearchView.managed-filters">
|
||||
<option class="oe_search_filters_title" value="">Filters</option>
|
||||
<optgroup label="-- Filters --">
|
||||
<t t-foreach="filters" t-as="filter">
|
||||
<option t-attf-value="get:#{filter_index}"
|
||||
t-att-disabled="filter.disabled and 'disabled'"
|
||||
t-att-title="filter.disabled and disabled_filter_message">
|
||||
<t t-esc="filter.name"/>
|
||||
</option>
|
||||
</t>
|
||||
</optgroup>
|
||||
<optgroup label="-- Actions --">
|
||||
<option value="advanced_filter">Add Advanced Filter</option>
|
||||
<option value="save_filter">Save Filter</option>
|
||||
<option value="manage_filters">Manage Filters</option>
|
||||
</optgroup>
|
||||
</t>
|
||||
<t t-name="SearchView.managed-filters.add">
|
||||
<div>
|
||||
<p>Filter Name:</p>
|
||||
<input type="text"/>
|
||||
<p>(Any existing filter with the same name will be replaced)</p>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="SearchView.render_lines">
|
||||
<table class="oe_search_render_line" border="0" cellspacing="0" cellpadding="0"
|
||||
t-foreach="lines" t-as="line">
|
||||
<tr>
|
||||
<td t-foreach="line" t-as="widget" class="oe_searchview_field">
|
||||
<t t-raw="widget.render(defaults)"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</t>
|
||||
<button t-name="SearchView.filter" type="button"
|
||||
t-att-id="element_id"
|
||||
t-att-title="attrs.help"
|
||||
t-att-class="classes.join(' ')"
|
||||
t-att-style="style"
|
||||
t-att-autofocus="attrs.default_focus === '1' ? 'autofocus' : undefined">
|
||||
<img t-att-src="_s + '/web/static/src/img/icons/' + (attrs.icon || 'gtk-home') + '.png'" width="16" height="16"/>
|
||||
<br t-if="attrs.string"/>
|
||||
<t t-esc="attrs.string"/>
|
||||
</button>
|
||||
<ul t-name="SearchView.filters">
|
||||
<t t-name="SearchView.filters">
|
||||
<li t-foreach="widget.filters" t-as="filter" t-if="!filter.visible || filter.visible()"
|
||||
t-att-title="filter.attrs.string ? filter.attrs.help : undefined"
|
||||
t-att-data-index="filter_index">
|
||||
<t t-esc="filter.attrs.string or filter.attrs.help or filter.attrs.name or 'Ω'"/>
|
||||
<a>
|
||||
<t t-esc="filter.attrs.string or filter.attrs.help or filter.attrs.name or 'Ω'"/>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<t t-name="SearchView.filters.facet">
|
||||
<div class="category oe_filter_category"><t t-esc="facet.get('category')"/></div>
|
||||
|
||||
<t t-set="val" t-value="facet.get('json')"/>
|
||||
|
||||
<div t-if="!(val instanceof Array)" class="search_facet_input_container">
|
||||
<t t-esc="facet.get('value')"/>
|
||||
</div>
|
||||
<t t-if="val instanceof Array">
|
||||
<div class="search_facet_input_container"
|
||||
t-foreach="facet.get('json')" t-as="filter">
|
||||
<t t-esc="filter.attrs.string || filter.attrs.name"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<div class="search_facet_remove VS-icon VS-icon-cancel"/>
|
||||
</t>
|
||||
<t t-name="SearchView.field">
|
||||
<label t-att-class="'oe_label' + (attrs.help ? '_help' : '')"
|
||||
@@ -1714,82 +1643,82 @@
|
||||
<t t-if="filters.length" t-raw="filters.render(defaults)"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="SearchView.util.expand">
|
||||
<div t-att-class="'searchview_group ' + (expand == '0' ? 'folded' : 'expanded')">
|
||||
<a t-if="label" class="searchview_group_string" href="#">
|
||||
<t t-esc="label"/>
|
||||
</a>
|
||||
<div class="searchview_group_content">
|
||||
<t t-raw="content"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-name="SearchView.FilterMenu" class="btn-group btn-group-sm">
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="fa fa-filter"/> Filters <span class="caret"/>
|
||||
</button>
|
||||
<ul class="dropdown-menu filters-menu" role="menu">
|
||||
<li class="oe-add-filter closed-menu"><a>Add Custom Filter</a></li>
|
||||
<li class="oe-add-filter-menu"><button class="btn btn-default oe-apply-filter">Apply</button><a class="oe-add-condition"><span class="fa fa-plus-circle"/> Add a condition</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div t-name="SearchView.GroupByMenu" class="btn-group btn-group-sm oe-groupby-menu">
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="fa fa-bars"/> Group By <span class="caret"/>
|
||||
</button>
|
||||
<ul class="dropdown-menu group-by-menu" role="menu">
|
||||
<li class="divider"/>
|
||||
<li class="add-custom-group closed-menu"><a>Add custom group</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<t t-name="GroupByMenuSelector">
|
||||
<li><select class="form-control oe-add-group oe-group-selector">
|
||||
<t t-foreach="groupable_fields" t-as="field">
|
||||
<option t-att-data-name="field"><t t-esc="groupable_fields[field].string"/></option>
|
||||
</t>
|
||||
</select></li>
|
||||
<li><button class="btn btn-default oe-add-group oe-select-group">Apply</button></li>
|
||||
</t>
|
||||
<div t-name="SearchView.Filters" class="oe_searchview_filters oe_searchview_section">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div t-name="SearchView.Custom" class="oe_searchview_custom oe_searchview_section">
|
||||
<dl class="dl-horizontal">
|
||||
<dt><span class="oe_i">M</span> Favorites</dt>
|
||||
<dd><ul class="oe_searchview_custom_list"/></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div t-name="SearchView.SaveFilter" class="oe_searchview_savefilter">
|
||||
<h4>Save current filter</h4>
|
||||
<form class="oe_form">
|
||||
<p class="oe_form_required"><input id="oe_searchview_custom_input" placeholder="Filter name"/></p>
|
||||
<p>
|
||||
<input id="oe_searchview_custom_public" type="checkbox"/>
|
||||
<label for="oe_searchview_custom_public">Share with all users</label>
|
||||
<input id="oe_searchview_custom_default" type="checkbox"/>
|
||||
<label for="oe_searchview_custom_default">Use by default</label>
|
||||
</p>
|
||||
<button>Save</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div t-name="SearchView.advanced" class="oe_searchview_advanced">
|
||||
<h4>Advanced Search</h4>
|
||||
<form>
|
||||
<ul>
|
||||
|
||||
</ul>
|
||||
<button class="oe_add_condition button" type="button">Add a condition</button><br/>
|
||||
<button class="oe_apply" type="submit">Apply</button>
|
||||
</form>
|
||||
<div t-name="SearchView.FavoriteMenu" class="btn-group btn-group-sm">
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="fa fa-star"/> Favorites <span class="caret"/>
|
||||
</button>
|
||||
<ul class="dropdown-menu favorites-menu" role="menu">
|
||||
<li class="divider"/>
|
||||
<li class="oe-save-search closed-menu"><a>Save current search</a></li>
|
||||
<li class="oe-save-name"><input type="text" class="form-control"></input></li>
|
||||
<li class="oe-save-name">
|
||||
<span><input type="checkbox"/>Use by default</span>
|
||||
</li>
|
||||
<li class="oe-save-name">
|
||||
<span><input type="checkbox"/>Share with all users</span>
|
||||
</li>
|
||||
<li class="oe-save-name"><button class="btn btn-default">Save</button></li>
|
||||
</ul>
|
||||
</div>
|
||||
<t t-name="SearchView.extended_search.proposition">
|
||||
<li>
|
||||
<span class="searchview_extended_prop_or">or</span>
|
||||
<select class="searchview_extended_prop_field">
|
||||
<t t-foreach="widget.attrs.fields" t-as="field">
|
||||
<option t-att="{'selected': field === widget.attrs.selected ? 'selected' : null}"
|
||||
t-att-value="field.name">
|
||||
<t t-esc="field.string"/>
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
<select class="searchview_extended_prop_op"/>
|
||||
<li class="oe-filter-condition">
|
||||
<span>
|
||||
<select class="searchview_extended_prop_field form-control">
|
||||
<t t-foreach="widget.attrs.fields" t-as="field">
|
||||
<option t-att="{'selected': field === widget.attrs.selected ? 'selected' : null}"
|
||||
t-att-value="field.name">
|
||||
<t t-esc="field.string"/>
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
<span class="searchview_extended_delete_prop fa fa-trash-o"/>
|
||||
</span>
|
||||
<select class="searchview_extended_prop_op form-control"/>
|
||||
<span class="searchview_extended_prop_value"/>
|
||||
<a class="searchview_extended_delete_prop button">x</a>
|
||||
</li>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search.proposition.char">
|
||||
<input class="field_char"/>
|
||||
<input class="field_char form-control"/>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search.proposition.empty">
|
||||
<span/>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search.proposition.integer">
|
||||
<input type="number" class="field_integer" value = "0" step="1"/>
|
||||
<input type="number" class="field_integer form-control" value = "0" step="1"/>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search.proposition.float">
|
||||
<input type="number" class="field_float" value = "0.0" step="0.01"/>
|
||||
<input type="number" class="field_float form-control" value = "0.0" step="0.01"/>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search.proposition.selection">
|
||||
<select>
|
||||
<select class="form-control">
|
||||
<t t-foreach="widget.field.selection" t-as="element">
|
||||
<option t-att-value="element[0]"><t t-esc="element[1]"/></option>
|
||||
</t>
|
||||
|
||||
@@ -146,7 +146,7 @@ openerp.testing.section('search.query', {
|
||||
* @param [defaults={}]
|
||||
* @return {instance.web.SearchView}
|
||||
*/
|
||||
var makeSearchView = function (instance, dummy_widget_attributes, defaults) {
|
||||
var makeSearchView = function (instance, dummy_widget_attributes, defaults, options) {
|
||||
instance.web.search.fields.add(
|
||||
'dummy', 'instance.dummy.DummyWidget');
|
||||
instance.dummy = {};
|
||||
@@ -175,8 +175,8 @@ var makeSearchView = function (instance, dummy_widget_attributes, defaults) {
|
||||
|
||||
var dataset = new instance.web.DataSet(null, 'dummy.model');
|
||||
var mock_parent = {getParent: function () {return null;}};
|
||||
|
||||
var view = new instance.web.SearchView(mock_parent, dataset, false, defaults);
|
||||
options = _.defaults(options || {}, {$buttons: $('<div>')});
|
||||
var view = new instance.web.SearchView(mock_parent, dataset, false, defaults, options);
|
||||
var self = this;
|
||||
view.on('invalid_search', self, function () {
|
||||
ok(false, JSON.stringify([].slice(arguments)));
|
||||
@@ -1018,42 +1018,21 @@ openerp.testing.section('search.serialization', {
|
||||
return $.when(t1, t2);
|
||||
});
|
||||
});
|
||||
openerp.testing.section('search.removal', {
|
||||
openerp.testing.section('search.menus', {
|
||||
dependencies: ['web.search'],
|
||||
rpc: 'mock',
|
||||
templates: true
|
||||
}, function (test) {
|
||||
test('clear button', {asserts: 2}, function (instance, $fix) {
|
||||
var view = makeSearchView(instance, {
|
||||
facet_for_defaults: function (defaults) {
|
||||
return $.when({
|
||||
field: this,
|
||||
category: 'Dummy',
|
||||
values: [{label: 'dummy', value: defaults.dummy}]
|
||||
});
|
||||
}
|
||||
}, {dummy: 42});
|
||||
test('is-drawn', {asserts: 3}, function (instance, $fix) {
|
||||
var view = makeSearchView(instance, false, false, {$buttons: $('<div>')});
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
equal(view.query.length, 1, "view should have default facet");
|
||||
$fix.find('.oe_searchview_clear').click();
|
||||
equal(view.query.length, 0, "cleared view should not have any facet");
|
||||
});
|
||||
});
|
||||
});
|
||||
openerp.testing.section('search.drawer', {
|
||||
dependencies: ['web.search'],
|
||||
rpc: 'mock',
|
||||
templates: true
|
||||
}, function (test) {
|
||||
test('is-drawn', {asserts: 2}, function (instance, $fix) {
|
||||
var view = makeSearchView(instance);
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
ok($fix.find('.oe_searchview_filters').length,
|
||||
"filters drawer control has been drawn");
|
||||
ok($fix.find('.oe_searchview_advanced').length,
|
||||
"filters advanced search has been drawn");
|
||||
ok(view.$buttons.find('.filters-menu').length,
|
||||
"filters menu has been drawn");
|
||||
ok(view.$buttons.find('.group-by-menu').length,
|
||||
"group by menu has been drawn");
|
||||
ok(view.$buttons.find('.favorites-menu').length,
|
||||
"favorites menu has been drawn");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1076,18 +1055,25 @@ openerp.testing.section('search.filters', {
|
||||
});
|
||||
}
|
||||
}, function (test) {
|
||||
test('drawn', {asserts: 3}, function (instance, $fix) {
|
||||
test('drawn', {asserts: 4}, function (instance, $fix) {
|
||||
var view = makeSearchView(instance);
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $fs = $fix.find('.oe_searchview_filters ul');
|
||||
// 3 filters, 1 filtergroup, 1 custom report widget,
|
||||
// 1 Filters, 1 SaveFilter widget, and 1 advanced
|
||||
equal(view.drawer.inputs.length, 8,
|
||||
'view should have 8 inputs total');
|
||||
equal($fs.children().length, 3,
|
||||
"drawer should have a filter group with 3 filters");
|
||||
equal(_.str.strip($fs.children().eq(0).text()), "Foo1",
|
||||
var $filters = view.$buttons.find('.filters-menu li'),
|
||||
$favorites = view.$buttons.find('.favorites-menu li'),
|
||||
$groupby = view.$buttons.find('.group-by-menu li');
|
||||
// 3 filters, 1 separator, 1 button add filter,
|
||||
// 1 filter condition menu, 1 apply button
|
||||
equal($filters.length, 7,
|
||||
'filter menu should have 7 elements total');
|
||||
// 1 divider, 1 save search button, 1 text input, 2 checkboxes,
|
||||
// 1 save button
|
||||
equal($favorites.length, 6,
|
||||
"favorites menu should have 6 elements");
|
||||
// 1 divider, 1 add custom group button, 1 select groupby, 1 apply button,
|
||||
equal($groupby.length, 4,
|
||||
"groupby menu should have 4 element");
|
||||
equal(_.str.strip($filters.find('a')[0].textContent), "Foo1",
|
||||
"Text content of first filter option should match filter string");
|
||||
});
|
||||
});
|
||||
@@ -1095,8 +1081,8 @@ openerp.testing.section('search.filters', {
|
||||
var view = makeSearchView(instance);
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $fs = $fix.find('.oe_searchview_filters ul');
|
||||
$fs.children(':eq(2)').trigger('click');
|
||||
var $fs = view.$buttons.find('.filters-menu li a');
|
||||
$fs.eq(2).trigger('click');
|
||||
equal(view.query.length, 1, "click should have added a facet");
|
||||
var facet = view.query.at(0);
|
||||
equal(facet.values.length, 1, "facet should have a single value");
|
||||
@@ -1111,8 +1097,8 @@ openerp.testing.section('search.filters', {
|
||||
var view = makeSearchView(instance, {}, {foo2: true});
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $fs = $fix.find('.oe_searchview_filters ul');
|
||||
$fs.children(':eq(2)').trigger('click');
|
||||
var $fs = view.$buttons.find('.filters-menu li a');
|
||||
$fs.eq(2).trigger('click');
|
||||
equal(view.query.length, 1, "click should not have changed facet count");
|
||||
var facet = view.query.at(0);
|
||||
equal(facet.values.length, 2, "facet should have a second value");
|
||||
@@ -1132,11 +1118,11 @@ openerp.testing.section('search.filters', {
|
||||
});
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $fs = $fix.find('.oe_searchview_filters ul');
|
||||
var $fs = view.$buttons.find('.filters-menu li a');
|
||||
// sanity check
|
||||
equal(view.query.length, 1, "query should have default facet");
|
||||
strictEqual(calls, 0);
|
||||
$fs.children(':eq(1)').trigger('click');
|
||||
$fs.eq(1).trigger('click');
|
||||
equal(view.query.length, 0, "click should have removed facet");
|
||||
strictEqual(calls, 1, "one search should have been triggered");
|
||||
});
|
||||
@@ -1148,7 +1134,7 @@ openerp.testing.section('search.groupby', {
|
||||
templates: true,
|
||||
}, function (test) {
|
||||
test('basic', {
|
||||
asserts: 7,
|
||||
asserts: 12,
|
||||
setup: function (instance, $s, mock) {
|
||||
mock('dummy.model:fields_view_get', function () {
|
||||
return {
|
||||
@@ -1168,22 +1154,20 @@ openerp.testing.section('search.groupby', {
|
||||
var view = makeSearchView(instance);
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
// 3 filters, 1 filtergroup group, 1 custom filter, 1 advanced, 1 Filters
|
||||
// and 1 SaveFilter widget
|
||||
equal(view.drawer.inputs.length, 8,
|
||||
'should have 8 inputs total');
|
||||
var group = _.find(view.drawer.inputs, function (f) {
|
||||
return f instanceof instance.web.search.GroupbyGroup;
|
||||
});
|
||||
ok(group, "should have a GroupbyGroup input");
|
||||
ok(group.getParent() === view.drawer,
|
||||
"group's parent should be the drawer");
|
||||
equal(view.search_fields.length, 0); // 0 fields
|
||||
equal(view.filters.length, 0); // 0 filters (in filter menu)
|
||||
equal(view.groupbys.length, 1); // 1 group of groupbys
|
||||
var group = view.groupbys[0];
|
||||
ok(group instanceof instance.web.search.GroupbyGroup,
|
||||
'should have a GroupbyGroup input');
|
||||
equal(group.filters.length, 3); // 3 group bys in group
|
||||
ok(group.getParent() === view,
|
||||
"group's parent should be the searchview");
|
||||
|
||||
group.toggle(group.filters[0]);
|
||||
group.toggle(group.filters[2]);
|
||||
|
||||
var results = view.build_search_data();
|
||||
deepEqual(results.errors, [], "should have no errors");
|
||||
deepEqual(results.domains, [], "should have no domain");
|
||||
deepEqual(results.contexts, [
|
||||
new instance.web.CompoundContext(
|
||||
@@ -1193,10 +1177,14 @@ openerp.testing.section('search.groupby', {
|
||||
"{'group_by': 'foo'}",
|
||||
"{'group_by': 'baz'}"
|
||||
], "should have sequence of contexts");
|
||||
|
||||
ok(view.filter_menu instanceof instance.web.search.FilterMenu, 'should have a filter menu');
|
||||
ok(view.groupby_menu instanceof instance.web.search.GroupByMenu, 'should have a group by menu');
|
||||
ok(view.favorite_menu instanceof instance.web.search.FavoriteMenu, 'should have a favorite menu');
|
||||
});
|
||||
});
|
||||
test('unified multiple groupby groups', {
|
||||
asserts: 4,
|
||||
asserts: 3,
|
||||
setup: function (instance, $s, mock) {
|
||||
mock('dummy.model:fields_view_get', function () {
|
||||
return {
|
||||
@@ -1218,14 +1206,7 @@ openerp.testing.section('search.groupby', {
|
||||
var view = makeSearchView(instance);
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
// 3 filters, 3 filtergroups, 1 custom filter, 1 advanced, 1 Filters,
|
||||
// and 1 SaveFilter widget
|
||||
equal(view.drawer.inputs.length, 10, "should have 10 inputs total");
|
||||
|
||||
var groups = _.filter(view.drawer.inputs, function (f) {
|
||||
return f instanceof instance.web.search.GroupbyGroup;
|
||||
});
|
||||
|
||||
var groups = view.groupbys;
|
||||
equal(groups.length, 3, "should have 3 GroupbyGroups");
|
||||
|
||||
groups[0].toggle(groups[0].filters[0]);
|
||||
@@ -1233,7 +1214,6 @@ openerp.testing.section('search.groupby', {
|
||||
equal(view.query.length, 1,
|
||||
"should have unified groupby groups in single facet");
|
||||
deepEqual(view.build_search_data(), {
|
||||
errors: [],
|
||||
domains: [],
|
||||
contexts: [new instance.web.CompoundContext(
|
||||
"{'group_by': 'foo'}", "{'group_by': 'baz'}")],
|
||||
@@ -1255,10 +1235,10 @@ openerp.testing.section('search.filters.saved', {
|
||||
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $span = $fix.find('.oe_searchview_custom_list span:first').click();
|
||||
var $li = view.favorite_menu.$el.find('li:first').click();
|
||||
|
||||
ok($span.hasClass('badge'), "should check/select the filter's row");
|
||||
ok($span.hasClass("oe_searchview_custom_private"),
|
||||
ok($li.hasClass('selected'), "should check/select the filter's row");
|
||||
ok($li.hasClass("oe_searchview_custom_private"),
|
||||
"should have private filter note/class");
|
||||
equal(view.query.length, 1, "should have only one facet");
|
||||
var values = view.query.at(0).values;
|
||||
@@ -1278,10 +1258,10 @@ openerp.testing.section('search.filters.saved', {
|
||||
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $row = $fix.find('.oe_searchview_custom li:first').click();
|
||||
var $row = view.favorite_menu.$el.find('li:first').click();
|
||||
|
||||
view.query.remove(view.query.at(0));
|
||||
ok(!$row.hasClass('badge'),
|
||||
ok(!$row.hasClass('selected'),
|
||||
"should not be checked anymore");
|
||||
});
|
||||
});
|
||||
@@ -1293,7 +1273,7 @@ openerp.testing.section('search.filters.saved', {
|
||||
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $row = $fix.find('.oe_searchview_custom_list span:first').click();
|
||||
var $row = view.favorite_menu.$el.find('li:first').click();
|
||||
equal(view.query.length, 1, "should have one facet");
|
||||
$row.click();
|
||||
equal(view.query.length, 0, "should have removed facet");
|
||||
@@ -1309,13 +1289,13 @@ openerp.testing.section('search.filters.saved', {
|
||||
});
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
$fix.find('.oe_searchview_custom_list span:eq(0)').click();
|
||||
view.favorite_menu.$el.find('li:first').click();
|
||||
equal(view.query.length, 1, "should have one facet");
|
||||
deepEqual(
|
||||
view.query.at(0).get('field').get_context(),
|
||||
{'private': 1},
|
||||
"should have selected first filter");
|
||||
$fix.find('.oe_searchview_custom_list span:eq(1)').click();
|
||||
view.favorite_menu.$el.find('li').eq(1).click();
|
||||
equal(view.query.length, 1, "should have one facet");
|
||||
deepEqual(
|
||||
view.query.at(0).get('field').get_context(),
|
||||
@@ -1338,10 +1318,8 @@ openerp.testing.section('search.filters.saved', {
|
||||
});
|
||||
return view.appendTo($fix)
|
||||
.then(function () {
|
||||
$fix.find('.oe_searchview_savefilter input#oe_searchview_custom_input')
|
||||
.val("filter name")
|
||||
.end()
|
||||
.find('.oe_searchview_savefilter button').click();
|
||||
view.favorite_menu.$el.find('.oe-save-name input').first().val("filter name");
|
||||
view.favorite_menu.$el.find('.oe-save-name button').click();
|
||||
return done.promise();
|
||||
});
|
||||
});
|
||||
@@ -1356,16 +1334,16 @@ openerp.testing.section('search.advanced', {
|
||||
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $advanced = $fix.find('.oe_searchview_advanced');
|
||||
var $filter_menu = view.filter_menu.$el;
|
||||
// open advanced search (not actually useful)
|
||||
$advanced.find('> h4').click();
|
||||
$filter_menu.find('.oe-add-filter').click();
|
||||
// select proposition (only one)
|
||||
var $prop = $advanced.find('> form li:first');
|
||||
var $prop = $filter_menu.find('.oe-filter-condition');
|
||||
// field select should have two possible values, dummy and id
|
||||
equal($prop.find('.searchview_extended_prop_field option').length,
|
||||
equal($prop.find('select:first option').length,
|
||||
2, "advanced search should provide choice between two fields");
|
||||
// field should be dummy
|
||||
equal($prop.find('.searchview_extended_prop_field').val(),
|
||||
equal($prop.find('select:first').val(),
|
||||
'dummy',
|
||||
"only field should be dummy");
|
||||
// operator should be "contains"/'ilike'
|
||||
@@ -1375,8 +1353,7 @@ openerp.testing.section('search.advanced', {
|
||||
$prop.find('.searchview_extended_prop_value input')
|
||||
.val("stupid value");
|
||||
// validate advanced search
|
||||
$advanced.find('button.oe_apply').click();
|
||||
|
||||
$filter_menu.find('button.oe-apply-filter').click();
|
||||
// resulting search
|
||||
equal(view.query.length, 1, "search query should have a single facet");
|
||||
var facet = view.query.at(0);
|
||||
@@ -1392,34 +1369,35 @@ openerp.testing.section('search.advanced', {
|
||||
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
var $advanced = $fix.find('.oe_searchview_advanced');
|
||||
var $filter_menu = view.filter_menu.$el;
|
||||
// open advanced search (not actually useful)
|
||||
$advanced.find('> h4').click();
|
||||
$filter_menu.find('.oe-add-filter').click();
|
||||
// open second condition
|
||||
$advanced.find('button.oe_add_condition').click();
|
||||
$filter_menu.find('a.oe-add-condition').click();
|
||||
|
||||
// select first proposition
|
||||
var $prop1 = $advanced.find('> form li:first');
|
||||
$prop1.find('.searchview_extended_prop_field').val('dummy').change();
|
||||
$prop1.find('.searchview_extended_prop_op').val('ilike');
|
||||
var $prop1 = $filter_menu.find('.oe-filter-condition:first');
|
||||
$prop1.find('select.searchview_extended_prop_field').val("dummy").change();
|
||||
$prop1.find('select.searchview_extended_prop_op').val('ilike');
|
||||
$prop1.find('.searchview_extended_prop_value input')
|
||||
.val("stupid value");
|
||||
|
||||
// select first proposition
|
||||
var $prop2 = $advanced.find('> form li:last');
|
||||
var $prop2 = $filter_menu.find('.oe-filter-condition:last');
|
||||
// need to trigger event manually or op not changed
|
||||
$prop2.find('.searchview_extended_prop_field').val('id').change();
|
||||
$prop2.find('.searchview_extended_prop_op').val('=');
|
||||
$prop2.find('select.searchview_extended_prop_field').val('id').change();
|
||||
$prop2.find('select.searchview_extended_prop_op').val('=');
|
||||
$prop2.find('.searchview_extended_prop_value input')
|
||||
.val(42);
|
||||
// validate advanced search
|
||||
$advanced.find('button.oe_apply').click();
|
||||
$filter_menu.find('button.oe-apply-filter').click();
|
||||
|
||||
// resulting search
|
||||
equal(view.query.length, 1, "search query should have a single facet");
|
||||
var facet = view.query.at(0);
|
||||
ok(!facet.get('field').get_context(facet),
|
||||
"advanced search facets should yield no context");
|
||||
deepEqual(facet.get('field').get_domain(facet),
|
||||
deepEqual(facet.get('field').get_domain(facet).eval(),
|
||||
['|', ['dummy', 'ilike', "stupid value"],
|
||||
['id', '=', 42]],
|
||||
"advanced search facet should return proposed domain");
|
||||
@@ -1427,179 +1405,5 @@ openerp.testing.section('search.advanced', {
|
||||
});
|
||||
// TODO: UI tests?
|
||||
});
|
||||
openerp.testing.section('search.invisible', {
|
||||
dependencies: ['web.search'],
|
||||
rpc: 'mock',
|
||||
templates: true,
|
||||
}, function (test) {
|
||||
var registerTestField = function (instance, methods) {
|
||||
instance.testing.TestWidget = instance.web.search.Field.extend(methods);
|
||||
instance.web.search.fields.add('test', 'instance.testing.TestWidget');
|
||||
};
|
||||
var makeView = function (instance, mock, fields, arch, defaults) {
|
||||
mock('ir.filters:get_filters', function () { return []; });
|
||||
mock('test.model:fields_get', function () { return fields; });
|
||||
mock('test.model:fields_view_get', function () {
|
||||
return { type: 'search', fields: fields, arch: arch };
|
||||
});
|
||||
var ds = new instance.web.DataSet(null, 'test.model');
|
||||
return new instance.web.SearchView(null, ds, false, defaults);
|
||||
};
|
||||
// Invisible fields should not auto-complete
|
||||
test('invisible-field-no-autocomplete', {asserts: 1}, function (instance, $fix, mock) {
|
||||
registerTestField(instance, {
|
||||
complete: function () {
|
||||
return $.when([{label: this.attrs.string}]);
|
||||
},
|
||||
});
|
||||
var view = makeView(instance, mock, {
|
||||
field0: {type: 'test', string: 'Field 0'},
|
||||
field1: {type: 'test', string: 'Field 1'},
|
||||
}, ['<search>',
|
||||
'<field name="field0"/>',
|
||||
'<field name="field1" modifiers="{"invisible": true}"/>',
|
||||
'</search>'].join(''));
|
||||
return view.appendTo($fix)
|
||||
.then(function () {
|
||||
var done = $.Deferred();
|
||||
view.complete_global_search({term: 'test'}, function (comps) {
|
||||
done.resolve(comps);
|
||||
});
|
||||
return done;
|
||||
}).then(function (completions) {
|
||||
deepEqual(completions, [{label: 'Field 0'}],
|
||||
"should only complete the visible field");
|
||||
});
|
||||
});
|
||||
// Invisible filters should not appear in the drawer
|
||||
test('invisible-filter-no-drawer', {asserts: 4}, function (instance, $fix, mock) {
|
||||
var view = makeView(instance, mock, {}, [
|
||||
'<search>',
|
||||
'<filter string="filter 0"/>',
|
||||
'<filter string="filter 1" modifiers="{"invisible": true}"/>',
|
||||
'</search>'].join(''));
|
||||
return view.appendTo($fix)
|
||||
.then(function () {
|
||||
var $fs = $fix.find('.oe_searchview_filters ul');
|
||||
strictEqual($fs.children().length,
|
||||
1,
|
||||
"should only display one filter");
|
||||
strictEqual(_.str.trim($fs.children().text()),
|
||||
"filter 0",
|
||||
"should only display filter 0");
|
||||
var done = $.Deferred();
|
||||
view.complete_global_search({term: 'filter'}, function (comps) {
|
||||
done.resolve();
|
||||
strictEqual(comps.length, 1, "should only complete visible filter");
|
||||
strictEqual(comps[0].label, "Filter on: filter 0",
|
||||
"should complete filter 0");
|
||||
});
|
||||
return done;
|
||||
});
|
||||
});
|
||||
test('invisible-previous-sibling', {asserts: 3}, function (instance, $fix, mock) {
|
||||
var view = makeView(instance, mock, {}, [
|
||||
'<search>',
|
||||
'<filter string="filter 0" context="{"test": 0}"/>',
|
||||
'<filter string="filter 1" modifiers="{"invisible": true}" context="{"test": 1}"/>',
|
||||
'<filter string="filter 2" modifiers="{"invisible": true}" context="{"test": 2}"/>',
|
||||
'<filter string="filter 3" context="{"test": 3}"/>',
|
||||
'</search>'].join(''));
|
||||
return view.appendTo($fix)
|
||||
.done(function () {
|
||||
// Select filter 3
|
||||
$fix.find('.oe_searchview_filters ul li:contains("filter 3")').click();
|
||||
equal(view.query.length, 1, "should have selected a filter");
|
||||
var facet = view.query.at(0);
|
||||
strictEqual(facet.values.at(0).get('label'), "filter 3",
|
||||
"should have correctly labelled the facet");
|
||||
deepEqual(view.build_search_data().contexts, [{test: 3}],
|
||||
"should have built correct context");
|
||||
});
|
||||
});
|
||||
// Invisible filter groups should not appear in the drawer
|
||||
// Group invisibility should be inherited by children
|
||||
test('group-invisibility', {asserts: 6}, function (instance, $fix, mock) {
|
||||
registerTestField(instance, {
|
||||
complete: function () {
|
||||
return $.when([{label: this.attrs.string}]);
|
||||
},
|
||||
});
|
||||
var view = makeView(instance, mock, {
|
||||
field0: {type: 'test', string: 'Field 0'},
|
||||
field1: {type: 'test', string: 'Field 1'},
|
||||
}, [
|
||||
'<search>',
|
||||
'<group string="Visibles">',
|
||||
'<field name="field0"/>',
|
||||
'<filter string="Filter 0"/>',
|
||||
'</group>',
|
||||
'<group string="Invisibles" modifiers="{"invisible": true}">',
|
||||
'<field name="field1"/>',
|
||||
'<filter string="Filter 1"/>',
|
||||
'</group>',
|
||||
'</search>'
|
||||
].join(''));
|
||||
return view.appendTo($fix)
|
||||
.then(function () {
|
||||
strictEqual($fix.find('.oe_searchview_filters dt').length,
|
||||
1,
|
||||
"should only display one group");
|
||||
strictEqual($fix.find('.oe_searchview_filters dt').text(),
|
||||
'w Visibles',
|
||||
"should only display the Visibles group (and its icon char)");
|
||||
|
||||
var $fs = $fix.find('.oe_searchview_filters ul');
|
||||
strictEqual($fs.children().length, 1,
|
||||
"should only have one filter in the drawer");
|
||||
strictEqual(_.str.trim($fs.text()), "Filter 0",
|
||||
"should have filter 0 as sole filter");
|
||||
|
||||
var done = $.Deferred();
|
||||
view.complete_global_search({term: 'filter'}, function (compls) {
|
||||
done.resolve();
|
||||
console.log("completions", compls);
|
||||
strictEqual(compls.length, 5,
|
||||
"should have 5 completions"); // 2 filters and 3 separators
|
||||
deepEqual(_.pluck(compls, 'label'),
|
||||
[undefined, 'Field 0', 'Filter on: Filter 0', undefined, undefined],
|
||||
"should complete on field 0 and filter 0");
|
||||
});
|
||||
return done;
|
||||
});
|
||||
});
|
||||
// Default on invisible fields should still work, for fields and filters both
|
||||
test('invisible-defaults', {asserts: 1}, function (instance, $fix, mock) {
|
||||
var view = makeView(instance, mock, {
|
||||
field: {type: 'char', string: "Field"},
|
||||
field2: {type: 'char', string: "Field 2"},
|
||||
}, [
|
||||
'<search>',
|
||||
'<field name="field2"/>',
|
||||
'<filter name="filter2" string="Filter"',
|
||||
' domain="[[\'qwa\', \'=\', 42]]"/>',
|
||||
'<group string="Invisibles" modifiers="{"invisible": true}">',
|
||||
'<field name="field"/>',
|
||||
'<filter name="filter" string="Filter"',
|
||||
' domain="[[\'whee\', \'=\', \'42\']]"/>',
|
||||
'</group>',
|
||||
'</search>'
|
||||
].join(''), {field: "foo", filter: true});
|
||||
|
||||
return view.appendTo($fix)
|
||||
.then(function () {
|
||||
deepEqual(view.build_search_data(), {
|
||||
errors: [],
|
||||
groupbys: [],
|
||||
contexts: [],
|
||||
domains: [
|
||||
// Generated from field
|
||||
[['field', 'ilike', 'foo']],
|
||||
// generated from filter
|
||||
"[['whee', '=', '42']]"
|
||||
],
|
||||
}, "should yield invisible fields selected by defaults");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
<script type="text/javascript" src="/web/static/src/js/view_list.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/view_form.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/view_list_editable.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/view_pivot.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/view_tree.js"></script>
|
||||
<script type="text/javascript" src="/base/static/src/js/apps.js"></script>
|
||||
|
||||
|
||||
@@ -88,6 +88,8 @@ openerp.web_calendar = function(instance) {
|
||||
this.range_start = null;
|
||||
this.range_stop = null;
|
||||
this.selected_filters = [];
|
||||
|
||||
this.shown = $.Deferred();
|
||||
},
|
||||
|
||||
set_default_options: function(options) {
|
||||
@@ -229,6 +231,7 @@ openerp.web_calendar = function(instance) {
|
||||
this.info_fields.push(fv.arch.children[fld].attrs.name);
|
||||
}
|
||||
|
||||
self.shown.done(this._do_show_init.bind(this));
|
||||
var edit_check = new instance.web.Model(this.dataset.model)
|
||||
.call("check_access_rights", ["write", false])
|
||||
.then(function (write_right) {
|
||||
@@ -238,15 +241,18 @@ openerp.web_calendar = function(instance) {
|
||||
.call("check_access_rights", ["create", false])
|
||||
.then(function (create_right) {
|
||||
self.create_right = create_right;
|
||||
self.init_calendar().then(function() {
|
||||
$(window).trigger('resize');
|
||||
self.trigger('calendar_view_loaded', fv);
|
||||
self.ready.resolve();
|
||||
});
|
||||
self.ready.resolve();
|
||||
self.trigger('calendar_view_loaded', fv);
|
||||
});
|
||||
return $.when(edit_check, init);
|
||||
},
|
||||
|
||||
_do_show_init: function () {
|
||||
var self = this;
|
||||
this.init_calendar().then(function() {
|
||||
$(window).trigger('resize');
|
||||
self.trigger('calendar_view_loaded', self.fields_view);
|
||||
});
|
||||
},
|
||||
get_fc_init_options: function () {
|
||||
//Documentation here : http://arshaw.com/fullcalendar/docs/
|
||||
var self = this;
|
||||
@@ -647,7 +653,13 @@ openerp.web_calendar = function(instance) {
|
||||
return data;
|
||||
},
|
||||
|
||||
do_search: function(domain, context, _group_by) {
|
||||
do_search: function (domain, context, _group_by) {
|
||||
var self = this;
|
||||
this.shown.done(function () {
|
||||
self._do_search(domain, context, _group_by);
|
||||
});
|
||||
},
|
||||
_do_search: function(domain, context, _group_by) {
|
||||
var self = this;
|
||||
if (! self.all_filters) {
|
||||
self.all_filters = {}
|
||||
@@ -854,11 +866,12 @@ openerp.web_calendar = function(instance) {
|
||||
return false;
|
||||
},
|
||||
|
||||
do_show: function() {
|
||||
do_show: function() {
|
||||
if (this.$buttons) {
|
||||
this.$buttons.show();
|
||||
}
|
||||
this.do_push_state({});
|
||||
this.shown.resolve();
|
||||
return this._super();
|
||||
},
|
||||
do_hide: function () {
|
||||
|
||||
@@ -31,6 +31,14 @@ instance.web_graph.GraphView = instance.web.View.extend({
|
||||
get_domain: function () {},
|
||||
get_groupby: function () {},
|
||||
};
|
||||
this.$buttons = options.$buttons;
|
||||
this.view_loaded = $.Deferred();
|
||||
},
|
||||
|
||||
start: function() {
|
||||
var $buttons = instance.web.qweb.render("graph-view-buttons");
|
||||
this.$buttons.html($buttons);
|
||||
return this._super();
|
||||
},
|
||||
|
||||
view_loading: function (fields_view_get) {
|
||||
@@ -45,6 +53,7 @@ instance.web_graph.GraphView = instance.web.View.extend({
|
||||
row_groupby: [],
|
||||
col_groupby: [],
|
||||
graph_view: this,
|
||||
$buttons: this.$buttons
|
||||
};
|
||||
|
||||
_.each(arch.children, function (field) {
|
||||
@@ -72,9 +81,17 @@ instance.web_graph.GraphView = instance.web.View.extend({
|
||||
if (self.widget_config.measures.length === 0) {
|
||||
self.widget_config.measures.push('__count');
|
||||
}
|
||||
this.view_loaded.resolve();
|
||||
},
|
||||
|
||||
do_search: function (domain, context, group_by) {
|
||||
var self = this;
|
||||
this.view_loaded.done(function () {
|
||||
self._do_search(domain, context, group_by);
|
||||
});
|
||||
},
|
||||
|
||||
_do_search: function (domain, context, group_by) {
|
||||
if (this.ignore_do_search) {
|
||||
this.ignore_do_search = false;
|
||||
return;
|
||||
@@ -97,12 +114,8 @@ instance.web_graph.GraphView = instance.web.View.extend({
|
||||
this.widget_config.measures = measures;
|
||||
}
|
||||
this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config);
|
||||
this.graph_widget.appendTo(this.$el);
|
||||
this.ViewManager.on('switch_mode', this, function (e) {
|
||||
if (e === 'graph') {
|
||||
var group_bys = self.get_groupbys_from_searchview();
|
||||
this.graph_widget.set(domain, group_bys.group_by, group_bys.col_group_by, group_bys.measures);
|
||||
}
|
||||
this.graph_widget.appendTo(this.$el).done(function () {
|
||||
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -209,7 +222,7 @@ instance.web_graph.GraphView = instance.web.View.extend({
|
||||
return {
|
||||
category:'GroupBy',
|
||||
values: this.make_groupby_values(groupbys, 'group_by'),
|
||||
icon:'w',
|
||||
icon:'fa fa-bars',
|
||||
field: this.search_view._s_groupby
|
||||
};
|
||||
},
|
||||
@@ -218,7 +231,7 @@ instance.web_graph.GraphView = instance.web.View.extend({
|
||||
return {
|
||||
category:'ColGroupBy',
|
||||
values: this.make_groupby_values(groupbys, 'col_group_by'),
|
||||
icon:'f',
|
||||
icon:'fa fa-level-down',
|
||||
field: this.col_search_field
|
||||
};
|
||||
},
|
||||
|
||||
@@ -20,12 +20,12 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
this.model = model;
|
||||
this.domain = domain;
|
||||
this.mode = options.mode || 'pivot'; // pivot, bar, pie, line
|
||||
this.heatmap_mode = options.heatmap_mode || 'none';
|
||||
this.visible_ui = options.visible_ui || true;
|
||||
this.bar_ui = options.bar_ui || 'group';
|
||||
this.graph_view = options.graph_view || null;
|
||||
this.pivot_options = options;
|
||||
this.title = options.title || 'Data';
|
||||
this.$buttons = options.$buttons;
|
||||
},
|
||||
|
||||
start: function() {
|
||||
@@ -33,8 +33,28 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
this.table = $('<table>');
|
||||
this.$('.graph_main_content').append(this.table);
|
||||
|
||||
this.$buttons.find('.oe-pivot-mode').click(function () {
|
||||
self.set_mode.bind(self)('pivot');
|
||||
});
|
||||
this.$measure_list = this.$buttons.find('.oe-measure-list');
|
||||
|
||||
this.$buttons.find('.oe-bar-mode').click(function () {
|
||||
self.set_mode.bind(self)('bar');
|
||||
});
|
||||
this.$buttons.find('.oe-line-mode').click(function () {
|
||||
self.set_mode.bind(self)('line');
|
||||
});
|
||||
this.$buttons.find('.oe-pie-mode').click(function () {
|
||||
self.set_mode.bind(self)('pie');
|
||||
});
|
||||
this.$buttons.find('.fa-expand').click(this.swap_axis.bind(this));
|
||||
this.$buttons.find('.fa-arrows-alt').click(function () {
|
||||
self.pivot.expand_all().then(self.proxy('display_data'));
|
||||
});
|
||||
this.$buttons.find('.fa-download').click(this.export_xls.bind(this));
|
||||
|
||||
var indexes = {'pivot': 0, 'bar': 1, 'line': 2, 'chart': 3};
|
||||
this.$('.graph_mode_selection label').eq(indexes[this.mode]).addClass('active');
|
||||
this.$('.graph_mode_selection label').eq(indexes[this.mode]).addClass('selected');
|
||||
|
||||
if (this.mode !== 'pivot') {
|
||||
this.$('.graph_heatmap label').addClass('disabled');
|
||||
@@ -42,7 +62,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
} else {
|
||||
this.$('.graph_main_content').addClass('graph_pivot_mode');
|
||||
}
|
||||
|
||||
// get search view
|
||||
var parent = this.getParent();
|
||||
while (!(parent instanceof openerp.web.ViewManager)) {
|
||||
@@ -103,6 +122,11 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
// this method gets the fields that appear in the search view, under the
|
||||
// 'Groupby' heading
|
||||
get_search_fields: function () {
|
||||
// this method is disabled for now. This requires extensive changes because the
|
||||
// search view works quite differently: But the graph view is going to be split
|
||||
// soon in pivot view and graph view. The pivot view will then properly handle
|
||||
// groupbys.
|
||||
return [];
|
||||
var self = this;
|
||||
|
||||
var groupbygroups = _(this.search_view.drawer.inputs).select(function (g) {
|
||||
@@ -142,12 +166,13 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
},
|
||||
|
||||
add_measures_to_options: function() {
|
||||
this.$('.graph_measure_selection').append(
|
||||
this.$measure_list.append(
|
||||
_.map(this.measure_list, function (measure) {
|
||||
return $('<li>').append($('<a>').attr('data-choice', measure.field)
|
||||
.attr('href', '#')
|
||||
.text(measure.string));
|
||||
}));
|
||||
this.$measure_list.find('li').click(this.measure_selection.bind(this));
|
||||
},
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -212,15 +237,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
this.display_data();
|
||||
},
|
||||
|
||||
set_heatmap_mode: function (mode) { // none, row, col, all
|
||||
this.heatmap_mode = mode;
|
||||
if (mode === 'none') {
|
||||
this.$('.graph_heatmap label').removeClass('disabled');
|
||||
this.$('.graph_heatmap label').removeClass('active');
|
||||
}
|
||||
this.display_data();
|
||||
},
|
||||
|
||||
create_field_value: function (f) {
|
||||
var field = (_.contains(f, ':')) ? f.split(':')[0] : f,
|
||||
groupby_field = _.findWhere(this.groupby_fields, {field:field}),
|
||||
@@ -281,11 +297,11 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
|
||||
put_measure_checkmarks: function () {
|
||||
var self = this,
|
||||
measures_li = this.$('.graph_measure_selection a');
|
||||
measures_li.removeClass('oe_selected');
|
||||
measures_li = this.$measure_list.find('li');
|
||||
measures_li.removeClass('selected');
|
||||
_.each(this.measure_list, function (measure, index) {
|
||||
if (_.findWhere(self.pivot.measures, measure)) {
|
||||
measures_li.eq(index).addClass('oe_selected');
|
||||
measures_li.eq(index).addClass('selected');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -309,17 +325,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
}
|
||||
},
|
||||
|
||||
heatmap_mode_selection: function (event) {
|
||||
event.preventDefault();
|
||||
var mode = event.currentTarget.getAttribute('data-mode');
|
||||
if (this.heatmap_mode === mode) {
|
||||
event.stopPropagation();
|
||||
this.set_heatmap_mode('none');
|
||||
} else {
|
||||
this.set_heatmap_mode(mode);
|
||||
}
|
||||
},
|
||||
|
||||
header_cell_clicked: function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
@@ -497,14 +502,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
var formatted_value = raw && !_.isUndefined(value) ? value : openerp.web.format_value(value, {type:this.pivot.measures[index].type}),
|
||||
cell = {value:formatted_value};
|
||||
|
||||
if (this.heatmap_mode === 'none') { return cell; }
|
||||
var total = (this.heatmap_mode === 'both') ? this.pivot.get_total()[index]
|
||||
: (this.heatmap_mode === 'row') ? this.pivot.get_total(row)[index]
|
||||
: this.pivot.get_total(col)[index];
|
||||
var color = Math.floor(90 + 165*(total - Math.abs(value))/total);
|
||||
if (color < 255) {
|
||||
cell.color = color;
|
||||
}
|
||||
return cell;
|
||||
},
|
||||
|
||||
@@ -570,7 +567,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
|
||||
this.$('.graph_main_content svg').remove();
|
||||
this.$('.graph_main_content div').remove();
|
||||
this.table.empty();
|
||||
this.table.toggleClass('heatmap', this.heatmap_mode !== 'none');
|
||||
this.$('.graph_options_selection label').last().toggleClass('disabled', this.pivot.no_data);
|
||||
this.width = this.$el.width();
|
||||
this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width()));
|
||||
|
||||
@@ -1,59 +1,25 @@
|
||||
<templates>
|
||||
|
||||
<t t-name="graph-view-buttons">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button class="btn btn-default fa fa-table oe-pivot-mode"></button>
|
||||
<button class="btn btn-default fa fa-bar-chart-o oe-bar-mode"></button>
|
||||
<button class="btn btn-default fa fa-line-chart oe-line-mode"></button>
|
||||
<button class="btn btn-default fa fa-pie-chart oe-pie-mode"></button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button class="btn btn-default fa fa-expand oe-pivot"></button>
|
||||
<button class="btn btn-default fa fa-arrows-alt oe-pivot"></button>
|
||||
<button class="btn btn-default fa fa-download oe-pivot"></button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
Measures <span class="caret"/>
|
||||
</button>
|
||||
<ul class="oe-measure-list dropdown-menu"/>
|
||||
</div>
|
||||
</t>
|
||||
<div t-name="GraphWidget" class="graph_widget">
|
||||
<div class="graph_header">
|
||||
|
||||
<div class="btn-toolbar hidden-print" role="toolbar">
|
||||
|
||||
<div class="btn-group graph_mode_selection" data-toggle="buttons">
|
||||
<label class="btn btn-default" data-mode="pivot" title="Table Mode">
|
||||
<input type="radio" name="modes"/><span class="fa fa-table"></span>
|
||||
</label>
|
||||
<label class="btn btn-default" data-mode="bar" title="Bar Chart">
|
||||
<input type="radio" name="modes"/><span class="fa fa-bar-chart-o"></span>
|
||||
</label>
|
||||
<label class="btn btn-default" data-mode="line" title="Line Chart">
|
||||
<input type="radio" name="modes"/><span class="fa fa-check-square"></span>
|
||||
</label>
|
||||
<label class="btn btn-default" data-mode="pie" title="Pie Chart">
|
||||
<input type="radio" name="modes"/><span class="fa fa-adjust"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="btn-group graph_heatmap" data-toggle="buttons" >
|
||||
<label class="btn btn-default" data-mode="both" title="Heat Map">
|
||||
<input type="radio" name="heatmap"/><span class="fa fa-th"></span>
|
||||
</label>
|
||||
<label class="btn btn-default" data-mode="row" title="Heat Map (rows)">
|
||||
<input type="radio" name="heatmap"/><span class="fa fa-bars"></span>
|
||||
</label>
|
||||
<label class="btn btn-default" data-mode="col" title="Heat Map (columns)">
|
||||
<input type="radio" name="heatmap"/><span class="fa fa-bars fa-rotate-90"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="btn-group graph_options_selection">
|
||||
<label class="btn btn-default" data-choice="swap_axis" title="Swap Axis">
|
||||
<span class="fa fa-expand"></span>
|
||||
</label>
|
||||
<label class="btn btn-default" data-choice="expand_all" title="Expand All">
|
||||
<span class="fa fa-arrows-alt"></span>
|
||||
</label>
|
||||
<label class="btn btn-default" data-choice="update_values" title="Reload Data">
|
||||
<span class="fa fa-refresh"></span>
|
||||
</label>
|
||||
<label class="btn btn-default" data-choice="export_data" title="Export Data" style="display:none">
|
||||
<span class="fa fa-download"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<label class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
Measures <span class="caret"></span>
|
||||
</label>
|
||||
<ul class="dropdown-menu graph_measure_selection" role="menu">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="graph_main_content"></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
this.currently_dragging = {};
|
||||
this.limit = options.limit || 40;
|
||||
this.add_group_mutex = new $.Mutex();
|
||||
if (!this.options.$buttons || !this.options.$buttons.length) {
|
||||
this.options.$buttons = false;
|
||||
}
|
||||
},
|
||||
view_loading: function(r) {
|
||||
return this.load_kanban(r);
|
||||
@@ -69,13 +72,12 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
if (unsorted && default_order) {
|
||||
this.dataset.set_sort(default_order.split(','));
|
||||
}
|
||||
|
||||
this.$el.addClass(this.fields_view.arch.attrs['class']);
|
||||
this.$buttons = $(QWeb.render("KanbanView.buttons", {'widget': this}));
|
||||
if (this.options.$buttons) {
|
||||
this.$buttons.appendTo(this.options.$buttons);
|
||||
} else {
|
||||
this.$el.find('.oe_kanban_buttons').replaceWith(this.$buttons);
|
||||
this.$('.oe_kanban_buttons').replaceWith(this.$buttons);
|
||||
}
|
||||
this.$buttons
|
||||
.on('click', 'button.oe_kanban_button_new', this.do_add_record)
|
||||
@@ -252,12 +254,12 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
self.fields_keys = _.unique(self.fields_keys.concat(grouping_fields));
|
||||
}
|
||||
var grouping = new instance.web.Model(self.dataset.model, context, domain).query(self.fields_keys).group_by(grouping_fields);
|
||||
return self.alive($.when(grouping)).done(function(groups) {
|
||||
return self.alive($.when(grouping)).then(function(groups) {
|
||||
self.remove_no_result();
|
||||
if (groups) {
|
||||
self.do_process_groups(groups);
|
||||
return self.do_process_groups(groups);
|
||||
} else {
|
||||
self.do_process_dataset();
|
||||
return self.do_process_dataset();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -266,12 +268,12 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
var self = this;
|
||||
this.$el.find('table:first').show();
|
||||
this.$el.removeClass('oe_kanban_ungrouped').addClass('oe_kanban_grouped');
|
||||
this.add_group_mutex.exec(function() {
|
||||
return this.add_group_mutex.exec(function() {
|
||||
self.do_clear_groups();
|
||||
self.dataset.ids = [];
|
||||
if (!groups.length) {
|
||||
self.no_result();
|
||||
return false;
|
||||
return $.when();
|
||||
}
|
||||
self.nb_records = 0;
|
||||
var remaining = groups.length - 1,
|
||||
@@ -306,8 +308,8 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
var self = this;
|
||||
this.$el.find('table:first').show();
|
||||
this.$el.removeClass('oe_kanban_grouped').addClass('oe_kanban_ungrouped');
|
||||
var def = $.Deferred();
|
||||
this.add_group_mutex.exec(function() {
|
||||
var def = $.Deferred();
|
||||
self.do_clear_groups();
|
||||
self.dataset.read_slice(self.fields_keys.concat(['__last_update']), { 'limit': self.limit }).done(function(records) {
|
||||
var kgroup = new instance.web_kanban.KanbanGroup(self, records, null, self.dataset);
|
||||
@@ -326,8 +328,8 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
}).done(null, function() {
|
||||
def.reject();
|
||||
});
|
||||
return def;
|
||||
});
|
||||
return def;
|
||||
},
|
||||
do_reload: function() {
|
||||
this.do_search(this.search_domain, this.search_context, this.search_group_by);
|
||||
@@ -490,7 +492,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
},
|
||||
|
||||
do_show: function() {
|
||||
if (this.$buttons) {
|
||||
if (this.options.$buttons) {
|
||||
this.$buttons.show();
|
||||
}
|
||||
this.do_push_state({});
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
<div t-name="KanbanView.buttons" class="oe_kanban_buttons">
|
||||
<t t-if="widget.options.action_buttons !== false">
|
||||
<t t-if="widget.is_action_enabled('create')">
|
||||
<button type="button" class="oe_kanban_button_new oe_highlight">
|
||||
<button type="button" class="oe_kanban_button_new btn btn-primary btn-sm">
|
||||
<t t-esc="widget.options.create_text || _t('Create')"/>
|
||||
</button>
|
||||
<span t-if="widget.is_action_enabled('group_create')" class="oe_alternative" style="display: none">
|
||||
<span class="oe_fade">or</span>
|
||||
<div class="oe_bounce_container">
|
||||
<a href="#" class="oe_bold oe_kanban_add_column">Add a new column</a>
|
||||
<a href="#" class="oe_kanban_add_column text-info">Add a new column</a>
|
||||
</div>
|
||||
</span>
|
||||
</t>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
.oe_bunchaforms > div {
|
||||
float: left;
|
||||
}
|
||||
|
||||
body.openerp {
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
openerp.web_view_editor = function(instance) {
|
||||
var _t = instance.web._t;
|
||||
var QWeb = instance.web.qweb;
|
||||
instance.web.ViewManagerAction.include({
|
||||
instance.web.ViewManager.include({
|
||||
on_debug_changed:function(evt){
|
||||
var val = $(evt.currentTarget).find('option:selected').val(),
|
||||
current_view = this.views[this.active_view].controller;
|
||||
var val = $(evt.target).data('action'),
|
||||
current_view = this.active_view.controller;
|
||||
if(val === "manage_views"){
|
||||
if (current_view.fields_view && current_view.fields_view.arch) {
|
||||
var view_editor = new instance.web_view_editor.ViewEditor(current_view, current_view.$el, this.dataset, current_view.fields_view.arch);
|
||||
@@ -13,7 +13,6 @@ instance.web.ViewManagerAction.include({
|
||||
this.do_warn(_t("Manage Views"),
|
||||
_t("Could not find current view declaration"));
|
||||
}
|
||||
evt.currentTarget.selectedIndex = 0;
|
||||
}else{
|
||||
return this._super.apply(this,arguments);
|
||||
}
|
||||
@@ -51,6 +50,7 @@ instance.web_view_editor.ViewEditor = instance.web.Widget.extend({
|
||||
views_switcher: false,
|
||||
action_buttons: false,
|
||||
search_view: false,
|
||||
headless: true,
|
||||
pager: false,
|
||||
radio: true,
|
||||
select_view_id: self.parent.fields_view.view_id
|
||||
@@ -71,7 +71,7 @@ instance.web_view_editor.ViewEditor = instance.web.Widget.extend({
|
||||
this.action_manager.appendTo(this.view_edit_dialog.$el);
|
||||
$.when(this.action_manager.do_action(action)).done(function() {
|
||||
var viewmanager = self.action_manager.inner_widget;
|
||||
var controller = viewmanager.views[viewmanager.active_view].controller;
|
||||
var controller = viewmanager.active_view.controller;
|
||||
$(controller.groups).bind({
|
||||
'selected': function (e, ids, records, deselected) {
|
||||
self.main_view_id = ids[0];
|
||||
@@ -408,7 +408,7 @@ instance.web_view_editor.ViewEditor = instance.web.Widget.extend({
|
||||
action_manager.do_action(action);
|
||||
}},
|
||||
{text: _t("Close"), click: function(){
|
||||
self.action_manager.inner_widget.views[self.action_manager.inner_widget.active_view].controller.reload_content();
|
||||
self.action_manager.inner_widget.active_view.controller.reload_content();
|
||||
self.edit_xml_dialog.close();
|
||||
}}
|
||||
]
|
||||
|
||||
@@ -186,6 +186,7 @@ class view(osv.osv):
|
||||
('tree','Tree'),
|
||||
('form','Form'),
|
||||
('graph', 'Graph'),
|
||||
('pivot', 'Pivot'),
|
||||
('calendar', 'Calendar'),
|
||||
('diagram','Diagram'),
|
||||
('gantt', 'Gantt'),
|
||||
|
||||
@@ -671,6 +671,15 @@
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="pivot">
|
||||
<rng:element name="pivot">
|
||||
<rng:optional><rng:attribute name="string" /></rng:optional>
|
||||
<rng:zeroOrMore>
|
||||
<rng:ref name="field"/>
|
||||
</rng:zeroOrMore>
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="button">
|
||||
<rng:element name="button">
|
||||
<rng:ref name="overload"/>
|
||||
@@ -742,6 +751,7 @@
|
||||
<rng:ref name="tree" />
|
||||
<rng:ref name="notebook" />
|
||||
<rng:ref name="graph" />
|
||||
<rng:ref name="pivot" />
|
||||
<rng:ref name="calendar" />
|
||||
<rng:ref name="gantt" />
|
||||
<rng:ref name="xpath" />
|
||||
@@ -769,6 +779,7 @@
|
||||
<rng:ref name="tree" />
|
||||
<rng:ref name="notebook" />
|
||||
<rng:ref name="graph" />
|
||||
<rng:ref name="pivot" />
|
||||
<rng:ref name="calendar" />
|
||||
<rng:ref name="data" />
|
||||
<rng:ref name="gantt" />
|
||||
|
||||
Reference in New Issue
Block a user