diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index ace5ef2dbf6..9ddcf9ca872 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1,4 +1,4 @@ -@charset "UTF-8"; +@charset "utf-8"; @font-face { font-family: "mnmliconsRegular"; src: url("/web/static/src/font/mnmliconsv21-webfont.eot") format("eot"); @@ -352,9 +352,17 @@ width: 37px; text-align: center; } +.openerp .oe_button_box .oe_stat_button .oe_form_field_percent_pie { + width: 42px; +} +.openerp .oe_button_box .oe_stat_button .oe_form_field_bar_chart { + width: 42px; +} .openerp .oe_button_box .oe_stat_button svg { width: 38px; height: 38px; + display: inline; + vertical-align: middle; } .openerp .oe_avatar > img { max-height: 90px; @@ -2768,7 +2776,7 @@ padding: 3px 6px; white-space: pre-line; } -.openerp .oe_list_content > tbody > tr > td > button, .openerp .oe_list_content > tbody > tr > th > button { +.openerp .oe_list_content > tbody > tr > td > button.btn_img, .openerp .oe_list_content > tbody > tr > th > button.btn_img { border: none; background: transparent; padding: 0; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index c148d95d7b1..d3153ee5d62 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -362,9 +362,15 @@ $sheet-padding: 16px padding: 0px 3px width: 37px text-align: center + .oe_form_field_percent_pie + width: 42px + .oe_form_field_bar_chart + width: 42px svg width: 38px height: 38px + display: inline + vertical-align: middle .oe_avatar > img max-height: 90px @@ -2241,7 +2247,7 @@ $sheet-padding: 16px padding: 3px 6px white-space: pre-line > td, > th - > button + > button.btn_img border: none background: transparent padding: 0 diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 8a9c909d9d6..33845ec8ed5 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -2438,6 +2438,76 @@ instance.web.form.FieldFloat = instance.web.form.FieldChar.extend({ } }); +instance.web.form.FieldCharDomain = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, { + init: function(field_manager, node) { + this._super.apply(this, arguments); + }, + start: function() { + var self = this; + this._super.apply(this, arguments); + this.on("change:effective_readonly", this, function () { + this.display_field(); + this.render_value(); + }); + this.display_field(); + return this._super(); + }, + render_value: function() { + this.$('button.select_records').css('visibility', this.get('effective_readonly') ? 'hidden': ''); + }, + set_value: function(value_) { + var self = this; + this.set('value', value_ || false); + this.display_field(); + }, + display_field: function() { + var self = this; + this.$el.html(instance.web.qweb.render("FieldCharDomain", {widget: this})); + if (this.get('value')) { + var domain = instance.web.pyeval.eval('domain', this.get('value')); + var relation = this.getParent().fields.mailing_model.get('value')[0]; + var ds = new instance.web.DataSetStatic(self, relation, self.build_context()); + ds.call('search_count', [domain]).then(function (results) { + $('.oe_domain_count', self.$el).text(results + ' records selected'); + $('button span', self.$el).text(' Change selection'); + }); + } else { + $('.oe_domain_count', this.$el).text('0 record selected'); + $('button span', this.$el).text(' Select records'); + }; + this.$('.select_records').on('click', self.on_click); + }, + on_click: function(ev) { + var self = this; + var model = this.options.model || this.field_manager.get_field_value(this.options.model_field); + this.pop = new instance.web.form.SelectCreatePopup(this); + this.pop.select_element( + model, {title: 'Select records...'}, + [], this.build_context()); + this.pop.on("elements_selected", self, function(element_ids) { + if (this.pop.$('input.oe_list_record_selector').prop('checked')) { + var search_data = this.pop.searchview.build_search_data(); + var domain_done = instance.web.pyeval.eval_domains_and_contexts({ + domains: search_data.domains, + contexts: search_data.contexts, + group_by_seq: search_data.groupbys || [] + }).then(function (results) { + return results.domain; + }); + } + else { + var domain = ["id", "in", element_ids]; + var domain_done = $.Deferred().resolve(domain); + } + $.when(domain_done).then(function (domain) { + var domain = self.pop.dataset.domain.concat(domain || []); + self.set_value(JSON.stringify(domain)) + }); + }); + event.preventDefault(); + }, +}); + instance.web.DateTimeWidget = instance.web.Widget.extend({ template: "web.datepicker", jqueryui_object: 'datetimepicker', @@ -2833,10 +2903,10 @@ instance.web.form.FieldPercentPie = instance.web.form.AbstractField.extend({ svg.innerHTML = ""; nv.addGraph(function() { - var size=43; + var width = 42, height = 42; var chart = nv.models.pieChart() - .width(size) - .height(size) + .width(width) + .height(height) .margin({top: 0, right: 0, bottom: 0, left: 0}) .donut(true) .showLegend(false) @@ -2849,11 +2919,11 @@ instance.web.form.FieldPercentPie = instance.web.form.AbstractField.extend({ .datum([{'x': 'value', 'y': value}, {'x': 'complement', 'y': 100 - value}]) .transition() .call(chart) - .attr({width:size, height:size}); + .attr('style', 'width: ' + width + 'px; height:' + height + 'px;'); d3.select(svg) .append("text") - .attr({x: size/2, y: size/2 + 3, 'text-anchor': 'middle'}) + .attr({x: width/2, y: height/2 + 3, 'text-anchor': 'middle'}) .style({"font-size": "10px", "font-weight": "bold"}) .text(formatted_value); @@ -2863,6 +2933,43 @@ instance.web.form.FieldPercentPie = instance.web.form.AbstractField.extend({ } }); +/** + The FieldBarChart expectsa list of values (indeed) +*/ +instance.web.form.FieldBarChart = instance.web.form.AbstractField.extend({ + template: 'FieldBarChart', + + render_value: function() { + var value = JSON.parse(this.get('value')); + var svg = this.$('svg')[0]; + svg.innerHTML = ""; + nv.addGraph(function() { + var width = 34, height = 34; + var chart = nv.models.discreteBarChart() + .x(function (d) { return d.tooltip }) + .y(function (d) { return d.value }) + .width(width) + .height(height) + .margin({top: 0, right: 0, bottom: 0, left: 0}) + .tooltips(false) + .showValues(false) + .transitionDuration(350) + .showXAxis(false) + .showYAxis(false); + + d3.select(svg) + .datum([{key: 'values', values: value}]) + .transition() + .call(chart) + .attr('style', 'width: ' + (width + 4) + 'px; height: ' + (height + 8) + 'px;'); + + nv.utils.windowResize(chart.update); + + return chart; + }); + + } +}); instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, { @@ -3419,7 +3526,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc } self.floating = false; } - if (used && self.get("value") === false && ! self.no_ed) { + if (used && self.get("value") === false && ! self.no_ed && (self.options.no_create === false || self.options.no_create === undefined)) { self.ed_def.reject(); self.uned_def.reject(); self.ed_def = $.Deferred(); @@ -5919,20 +6026,30 @@ instance.web.form.X2ManyCounter = instance.web.form.AbstractField.extend(instanc display a simple string "