summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2015-11-25 16:18:10 +0100
committerChristophe Simonis <chs@odoo.com>2015-11-25 16:18:10 +0100
commitd4906307459f3c67270d6461a7db2367cc24cd20 (patch)
treee0bfd33e7afe2634de8228ed68027bdf2fcc10b6 /addons/web/static/src
parent0ff9a1c34a8019081c1fb2d5f97c984b9c6a1b99 (diff)
parentb2939537d97624122bddfecaadb2490d2f4c477c (diff)
[MERGE] forward port of branch 9.0 up to b293953
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/img/enterprise_upgrade.jpgbin0 -> 375229 bytes
-rw-r--r--addons/web/static/src/js/boot.js3
-rw-r--r--addons/web/static/src/js/framework/data.js6
-rw-r--r--addons/web/static/src/js/framework/mixins.js1
-rw-r--r--addons/web/static/src/js/framework/utils.js11
-rw-r--r--addons/web/static/src/js/views/form_common.js14
-rw-r--r--addons/web/static/src/js/views/form_relational_widgets.js7
-rw-r--r--addons/web/static/src/js/views/form_view.js17
-rw-r--r--addons/web/static/src/js/views/form_widgets.js20
-rw-r--r--addons/web/static/src/js/views/graph_widget.js12
-rw-r--r--addons/web/static/src/js/views/list_view.js23
-rw-r--r--addons/web/static/src/xml/base.xml19
12 files changed, 92 insertions, 41 deletions
diff --git a/addons/web/static/src/img/enterprise_upgrade.jpg b/addons/web/static/src/img/enterprise_upgrade.jpg
new file mode 100644
index 00000000000..3b30a3ca05b
--- /dev/null
+++ b/addons/web/static/src/img/enterprise_upgrade.jpg
Binary files differ
diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js
index c63acb01bdf..65cf45827a0 100644
--- a/addons/web/static/src/js/boot.js
+++ b/addons/web/static/src/js/boot.js
@@ -51,6 +51,7 @@
testing: typeof QUnit === "object",
debug: debug,
remaining_jobs: jobs,
+ version: "community",
__DEBUG__: {
get_dependencies: function (name, transitive) {
@@ -262,7 +263,7 @@
log_when_loaded();
}
});
- }, 1000);
+ }, 4000);
};
$(log_when_loaded);
diff --git a/addons/web/static/src/js/framework/data.js b/addons/web/static/src/js/framework/data.js
index 8dd34cd4b93..e92bbd98c53 100644
--- a/addons/web/static/src/js/framework/data.js
+++ b/addons/web/static/src/js/framework/data.js
@@ -761,6 +761,12 @@ var BufferedDataSet = DataSetStatic.extend({
_.extend(cached.from_read, options.from_read);
_.extend(cached.changes, options.changes);
_.extend(cached.readonly_fields, options.readonly_fields);
+ // discard values from cached.changes that are in cached.from_read
+ _.each(cached.changes, function (v, k) {
+ if (cached.from_read[k] === v) {
+ delete cached.changes[k];
+ }
+ });
if (options.to_create !== undefined) cached.to_create = options.to_create;
if (options.to_delete !== undefined) cached.to_delete = options.to_delete;
}
diff --git a/addons/web/static/src/js/framework/mixins.js b/addons/web/static/src/js/framework/mixins.js
index 2f96da09872..40bdaeb51b4 100644
--- a/addons/web/static/src/js/framework/mixins.js
+++ b/addons/web/static/src/js/framework/mixins.js
@@ -288,6 +288,7 @@ var EventDispatcherMixin = _.extend({}, ParentedMixin, {
this._trigger_up(event);
},
_trigger_up: function(event) {
+ var parent;
this.__edispatcherEvents.trigger(event.name, event);
if (!event.is_stopped() && (parent = this.getParent())) {
parent._trigger_up(event);
diff --git a/addons/web/static/src/js/framework/utils.js b/addons/web/static/src/js/framework/utils.js
index f99d99ccc14..f1f28d83613 100644
--- a/addons/web/static/src/js/framework/utils.js
+++ b/addons/web/static/src/js/framework/utils.js
@@ -322,7 +322,16 @@ function round_precision (value, precision) {
var epsilon_magnitude = Math.log(Math.abs(normalized_value))/Math.log(2);
var epsilon = Math.pow(2, epsilon_magnitude - 53);
normalized_value += normalized_value >= 0 ? epsilon : -epsilon;
- var rounded_value = Math.round(normalized_value);
+
+ /**
+ * Javascript performs strictly the round half up method, which is asymmetric. However, in
+ * Python, the method is symmetric. For example:
+ * - In JS, Math.round(-0.5) is equal to -0.
+ * - In Python, round(-0.5) is equal to -1.
+ * We want to keep the Python behavior for consistency.
+ */
+ var sign = normalized_value < 0 ? -1.0 : 1.0;
+ var rounded_value = sign * Math.round(Math.abs(normalized_value));
return rounded_value * precision;
}
diff --git a/addons/web/static/src/js/views/form_common.js b/addons/web/static/src/js/views/form_common.js
index 7ec310be6fc..3e31579826a 100644
--- a/addons/web/static/src/js/views/form_common.js
+++ b/addons/web/static/src/js/views/form_common.js
@@ -868,11 +868,15 @@ var FormViewDialog = ViewDialog.extend({
if(!readonly) {
options.buttons.splice(0, 0, {text: _t("Save") + ((multi_select)? _t(" & Close") : ""), classes: "btn-primary o_formdialog_save", click: function() { // o_formdialog_save class for web_tests!
- $.when(self.view_form.save()).done(function() {
- self.view_form.reload_mutex.exec(function() {
- self.trigger('record_saved');
- self.close();
- });
+ self.view_form.onchanges_mutex.def.then(function() {
+ if (!self.view_form.warning_displayed) {
+ $.when(self.view_form.save()).done(function() {
+ self.view_form.reload_mutex.exec(function() {
+ self.trigger('record_saved');
+ self.close();
+ });
+ });
+ }
});
}
});
diff --git a/addons/web/static/src/js/views/form_relational_widgets.js b/addons/web/static/src/js/views/form_relational_widgets.js
index 3a3c2208e58..7c3048ee24b 100644
--- a/addons/web/static/src/js/views/form_relational_widgets.js
+++ b/addons/web/static/src/js/views/form_relational_widgets.js
@@ -655,6 +655,10 @@ var AbstractManyField = common.AbstractField.extend({
if (record.to_create) {
command_list.push(COMMANDS.create(values));
} else {
+ if (index === -1) {
+ // because the UPDATE below does not imply LINK_TO
+ command_list.push(COMMANDS.link_to(id));
+ }
command_list.push(COMMANDS.update(record.id, values));
}
return;
@@ -961,7 +965,8 @@ var X2ManyListView = ListView.extend({
field.no_rerender = true;
current_values[field.name] = field.get('value');
});
- var valid = _.every(this.dataset.cache, function(record){
+ var cached_records = _.filter(this.dataset.cache, function(item){return !_.isEmpty(item.values)});
+ var valid = _.every(cached_records, function(record){
_.each(fields, function(field){
var value = record.values[field.name];
field.set_value(_.isArray(value) && _.isArray(value[0]) ? [COMMANDS.delete_all()].concat(value) : value);
diff --git a/addons/web/static/src/js/views/form_view.js b/addons/web/static/src/js/views/form_view.js
index e6b2390c35d..5e32d8578e4 100644
--- a/addons/web/static/src/js/views/form_view.js
+++ b/addons/web/static/src/js/views/form_view.js
@@ -589,11 +589,16 @@ var FormView = View.extend(common.FieldManagerMixin, {
}
// FIXME XXX a list of warnings?
if (!_.isEmpty(result.warning)) {
- new Dialog(this, {
+ this.warning_displayed = true;
+ var dialog = new Dialog(this, {
size: 'medium',
title:result.warning.title,
$content: QWeb.render("CrashManager.warning", result.warning)
- }).open();
+ });
+ dialog.open();
+ dialog.on('closed', this, function () {
+ this.warning_displayed = false;
+ });
}
return $.Deferred().resolve();
@@ -697,12 +702,11 @@ var FormView = View.extend(common.FieldManagerMixin, {
this.set({actual_mode: mode});
},
check_actual_mode: function(source, options) {
- var self = this;
if(this.get("actual_mode") === "view") {
- self.$el.removeClass('oe_form_editable').addClass('oe_form_readonly');
+ this.$el.removeClass('oe_form_editable').addClass('oe_form_readonly');
} else {
- self.$el.removeClass('oe_form_readonly').addClass('oe_form_editable');
- this.autofocus();
+ this.$el.removeClass('oe_form_readonly').addClass('oe_form_editable');
+ _.defer(_.bind(this.autofocus, this));
}
},
autofocus: function() {
@@ -1009,6 +1013,7 @@ var FormView = View.extend(common.FieldManagerMixin, {
} else {
var fields = _.keys(self.fields_view.fields);
fields.push('display_name');
+ fields.push('__last_update');
return self.dataset.read_index(fields,
{
context: { 'bin_size': true },
diff --git a/addons/web/static/src/js/views/form_widgets.js b/addons/web/static/src/js/views/form_widgets.js
index a68bbf730a0..c1cc05ce156 100644
--- a/addons/web/static/src/js/views/form_widgets.js
+++ b/addons/web/static/src/js/views/form_widgets.js
@@ -1657,7 +1657,8 @@ var AbstractFieldUpgrade = {
},
open_dialog: function() {
- var message = _t('Upgrade to <a href="https://www.odoo.com/editions">Odoo Enterprise</a> to activate this feature.');
+ var message = $(QWeb.render('EnterpriseUpgrade'));
+
var buttons = [
{
text: _t("Upgrade now"),
@@ -1682,21 +1683,8 @@ var AbstractFieldUpgrade = {
},
confirm_upgrade: function() {
- new Model("res.users").call("read", [session.uid, ["partner_id"]]).done(function(data) {
- if(data.partner_id) {
- new Model("res.partner").call("read", [data.partner_id[0], ["name", "lang", "country_id", "email", "phone"]]).done(function(data) {
- // Remove false value
- data.country_id = data.country_id[0];
- var sanitized_data = _.omit(data, function(value, key, object) {
- if (_.isUndefined(value) || ( (_.isBoolean(value)) && (value === false) ) || key === "id") {
- return true;
- }
- });
- // prepare to url (+urlencode)
- var url_args = $.param(sanitized_data);
- framework.redirect("https://www.odoo.com/odoo-enterprise/upgrade?" + url_args);
- });
- }
+ new Model("res.users").call("search_count", [[["share", "=", false]]]).then(function(data) {
+ framework.redirect("https://www.odoo.com/odoo-enterprise/upgrade?num_users=" + data);
});
},
diff --git a/addons/web/static/src/js/views/graph_widget.js b/addons/web/static/src/js/views/graph_widget.js
index 989db33c289..340050eb0dc 100644
--- a/addons/web/static/src/js/views/graph_widget.js
+++ b/addons/web/static/src/js/views/graph_widget.js
@@ -1,6 +1,7 @@
odoo.define('web.GraphWidget', function (require) {
"use strict";
+var config = require('web.config');
var core = require('web.core');
var Model = require('web.DataModel');
var Widget = require('web.Widget');
@@ -8,6 +9,9 @@ var Widget = require('web.Widget');
var _t = core._t;
var QWeb = core.qweb;
+// hide top legend when too many item for device size
+var MAX_LEGEND_LENGTH = 25 * (1 + config.device.size_class);
+
return Widget.extend({
init: function (parent, model, options) {
this._super(parent);
@@ -159,7 +163,7 @@ return Widget.extend({
chart.options({
delay: 250,
transition: 10,
- showLegend: true,
+ showLegend: _.size(data) <= MAX_LEGEND_LENGTH,
showXAxis: true,
showYAxis: true,
rightAlignYAxis: false,
@@ -209,9 +213,13 @@ return Widget.extend({
svg.transition().duration(100);
+ var legend_right = config.device.size_class > config.device.SIZES.XS;
+
var chart = nv.models.pieChart();
chart.options({
delay: 250,
+ showLegend: legend_right || _.size(data) <= MAX_LEGEND_LENGTH,
+ legendPosition: legend_right ? 'right' : 'top',
transition: 100,
color: d3.scale.category10().range(),
});
@@ -285,7 +293,7 @@ return Widget.extend({
chart.options({
margin: {left: 50, right: 50},
useInteractiveGuideline: true,
- showLegend: true,
+ showLegend: _.size(data) <= MAX_LEGEND_LENGTH,
showXAxis: true,
showYAxis: true,
});
diff --git a/addons/web/static/src/js/views/list_view.js b/addons/web/static/src/js/views/list_view.js
index ae8fffbe7a4..86ae1790632 100644
--- a/addons/web/static/src/js/views/list_view.js
+++ b/addons/web/static/src/js/views/list_view.js
@@ -635,16 +635,21 @@ var ListView = View.extend( /** @lends instance.web.ListView# */ {
_(ids).each(function (id) {
self.records.remove(self.records.get(id));
});
- if (self.records.length === 0 && self.dataset.size() > 0) {
- //Trigger previous manually to navigate to previous page,
- //If all records are deleted on current page.
- self.$pager.find('ul li:first a').trigger('click');
- } else if (self.dataset.size() == self._limit) {
- //Reload listview to update current page with next page records
- //because pager going to be hidden if dataset.size == limit
- self.reload();
+ // Hide the table if there is no more record in the dataset
+ if (self.dataset.size() === 0) {
+ self.no_result();
} else {
- self.configure_pager(self.dataset);
+ if (self.records.length === 0 && self.dataset.size() > 0) {
+ //Trigger previous manually to navigate to previous page,
+ //If all records are deleted on current page.
+ self.$pager.find('ul li:first a').trigger('click');
+ } else if (self.dataset.size() === self._limit) {
+ //Reload listview to update current page with next page records
+ //because pager going to be hidden if dataset.size == limit
+ self.reload();
+ } else {
+ self.configure_pager(self.dataset);
+ }
}
self.compute_aggregates();
});
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index d11f5ad0847..e2c7bf09006 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -1471,4 +1471,23 @@
</t>
</t>
+<t t-name="EnterpriseUpgrade">
+ <div class="row">
+ <div class="col-xs-6">
+ Get this feature and much more with Odoo Enterprise!
+ <ul class="list-unstyled">
+ <li><i class="fa fa-check"></i> Access to all Enterprise Apps</li>
+ <li><i class="fa fa-check"></i> New design</li>
+ <li><i class="fa fa-check"></i> Mobile support</li>
+ <li><i class="fa fa-check"></i> Upgrade to future versions</li>
+ <li><i class="fa fa-check"></i> Bugfixes guarantee</li>
+ <li><a href="http://www.odoo.com/editions" target="_blank"><i class="fa fa-plus"></i> And more</a></li>
+ </ul>
+ </div>
+ <div class="col-xs-6">
+ <img class="img-responsive" t-att-src='_s + "/web/static/src/img/enterprise_upgrade.jpg"' draggable="false"/>
+ </div>
+ </div>
+</t>
+
</templates>