summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/core/abstract_storage_service.js11
-rw-r--r--addons/web/static/src/js/core/py_utils.js10
-rw-r--r--addons/web/static/src/js/core/utils.js12
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js1
-rw-r--r--addons/web/static/src/js/views/control_panel/control_panel_model.js17
-rw-r--r--addons/web/static/src/js/views/control_panel/search/filter_menu.js2
-rw-r--r--addons/web/static/src/js/views/control_panel/search/search_filters.js11
-rw-r--r--addons/web/static/src/js/views/graph/graph_renderer.js7
-rw-r--r--addons/web/static/src/js/views/pivot/pivot_model.js8
-rw-r--r--addons/web/static/src/js/views/pivot/pivot_renderer.js3
-rw-r--r--addons/web/static/src/scss/form_view.scss4
-rw-r--r--addons/web/static/src/scss/graph_view.scss29
-rw-r--r--addons/web/static/src/xml/base.xml2
13 files changed, 94 insertions, 23 deletions
diff --git a/addons/web/static/src/js/core/abstract_storage_service.js b/addons/web/static/src/js/core/abstract_storage_service.js
index 34dd24b2be6..ef828b5dd5c 100644
--- a/addons/web/static/src/js/core/abstract_storage_service.js
+++ b/addons/web/static/src/js/core/abstract_storage_service.js
@@ -13,6 +13,17 @@ var AbstractStorageService = AbstractService.extend({
// this abstraction
storage: null,
+ /**
+ * @override
+ */
+ destroy: function () {
+ // storage can be permanent or transient, destroy transient ones
+ if ((this.storage || {}).destroy) {
+ this.storage.destroy();
+ }
+ this._super.apply(this, arguments);
+ },
+
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
diff --git a/addons/web/static/src/js/core/py_utils.js b/addons/web/static/src/js/core/py_utils.js
index 9bcd66864e5..296ab5c3089 100644
--- a/addons/web/static/src/js/core/py_utils.js
+++ b/addons/web/static/src/js/core/py_utils.js
@@ -415,7 +415,15 @@ function _formatAST(ast, lbp) {
case "(number)":
return String(ast.value);
case "(string)":
- return "'" + ast.value + "'";
+ // ast.value is a string that may contain a mix of single and double quotes.
+ // But we need to return a string that represents the string ast.value.
+ // We use for that JSON.stringify. It will return a string with quotes correctly
+ // escaped. For instance, for x = `""` JSON.stringify(x) is `"\"\""`.
+ // But this means that if we pass several times here, escapes will be
+ // done again and again, leading to a profusion of backslashes that we don't want.
+ // For fun consider y = `\\` and y = JSON.stringify(y).
+ // This is why we first deescape particular characters in ast.value.
+ return JSON.stringify(ast.value.replace(/(\\(['"\\]))/g,"\$2"));
case "(constant)":
return ast.value;
case "(name)":
diff --git a/addons/web/static/src/js/core/utils.js b/addons/web/static/src/js/core/utils.js
index cf64de72eef..44e09933a25 100644
--- a/addons/web/static/src/js/core/utils.js
+++ b/addons/web/static/src/js/core/utils.js
@@ -303,7 +303,17 @@ var utils = {
var d2 = Math.pow(10, decimals);
var val = _t('kMGTPE');
var symbol = '';
- for (var i = val.length - 1 ; i > 0 ; i--) {
+ var numberMagnitude = number.toExponential().split('e')[1];
+ // the case numberMagnitude >= 21 corresponds to a number
+ // better expressed in the scientific format.
+ if (numberMagnitude >= 21) {
+ // we do not use number.toExponential(decimals) because we want to
+ // avoid the possible useless O decimals: 1e.+24 prefered to 1.0e+24
+ number = Math.round(number * Math.pow(10, decimals - numberMagnitude)) / d2;
+ // formatterCallback seems useless here.
+ return number + 'e' + numberMagnitude;
+ }
+ for (var i = val.length; i > 0 ; i--) {
var s = Math.pow(10, i * 3);
if (s <= number / Math.pow(10, minDigits - 1)) {
number = Math.round(number * d2 / s) / d2;
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index dcfdc982b7d..c6df3885a86 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -2914,6 +2914,7 @@ var AceEditor = DebouncedField.extend({
if (this.aceEditor) {
this.aceEditor.destroy();
}
+ this._super.apply(this, arguments);
},
//--------------------------------------------------------------------------
diff --git a/addons/web/static/src/js/views/control_panel/control_panel_model.js b/addons/web/static/src/js/views/control_panel/control_panel_model.js
index f58fbc93c4f..e59dbfb1036 100644
--- a/addons/web/static/src/js/views/control_panel/control_panel_model.js
+++ b/addons/web/static/src/js/views/control_panel/control_panel_model.js
@@ -927,10 +927,21 @@ var ControlPanelModel = mvc.Model.extend({
}
var sort = JSON.parse(favorite.sort);
var orderedBy = sort.map(function (order) {
- var orderTerms = order.split(' ');
+ var fieldName;
+ var asc;
+ var sqlNotation = order.split(' ');
+ if (sqlNotation.length > 1) {
+ // regex: \fieldName (asc|desc)?\
+ fieldName = sqlNotation[0];
+ asc = sqlNotation[1] === 'asc';
+ } else {
+ // legacy notation -- regex: \-?fieldName\
+ fieldName = order[0] === '-' ? order.slice(1) : order;
+ asc = order[0] === '-' ? false : true;
+ }
return {
- name: orderTerms[0],
- asc: orderTerms.length === 2 && orderTerms[1] === 'asc',
+ name: fieldName,
+ asc: asc,
};
});
return {
diff --git a/addons/web/static/src/js/views/control_panel/search/filter_menu.js b/addons/web/static/src/js/views/control_panel/search/filter_menu.js
index 70a242dd0f8..04f333b37c4 100644
--- a/addons/web/static/src/js/views/control_panel/search/filter_menu.js
+++ b/addons/web/static/src/js/views/control_panel/search/filter_menu.js
@@ -89,8 +89,6 @@ var FilterMenu = DropdownMenu.extend({
domain: Domain.prototype.arrayToString(preFilter.attrs.domain),
};
});
- // TO DO intercepts 'new_filters' and decide what to do whith filters
- // rewrite web.search_filters?
this.trigger_up('new_filters', {filters: filters});
_.invoke(this.propositions, 'destroy');
this.propositions = [];
diff --git a/addons/web/static/src/js/views/control_panel/search/search_filters.js b/addons/web/static/src/js/views/control_panel/search/search_filters.js
index 4703995ac7c..80a9019c02d 100644
--- a/addons/web/static/src/js/views/control_panel/search/search_filters.js
+++ b/addons/web/static/src/js/views/control_panel/search/search_filters.js
@@ -171,15 +171,6 @@ var Char = Field.extend({
{value: "∃", text: _lt("is set")},
{value: "∄", text: _lt("is not set")}
],
- get_domain: function (field, operator) {
- switch (operator.value) {
- case '∃': return [[field.name, '!=', false]];
- case '∄': return [[field.name, '=', false]];
- // does not work in all cases
- // default: return "[('" + field.name + "', '" + operator.value + "', '" + this.get_value() + "')]";
- default: return [[field.name, operator.value, this.get_value()]];
- }
- },
get_value: function () {
return this.$el.val();
}
@@ -251,7 +242,7 @@ var DateTime = Field.extend({
_create_new_widget: function (name) {
this[name] = new (this._get_widget_class())(this);
return this[name].appendTo(this.$el).then((function () {
- this[name].setValue(moment(new Date()));
+ this[name].setValue(moment());
}).bind(this));
},
_get_widget_class: function () {
diff --git a/addons/web/static/src/js/views/graph/graph_renderer.js b/addons/web/static/src/js/views/graph/graph_renderer.js
index 549fa56eefa..9353301ca09 100644
--- a/addons/web/static/src/js/views/graph/graph_renderer.js
+++ b/addons/web/static/src/js/views/graph/graph_renderer.js
@@ -21,6 +21,7 @@ var CHART_TYPES = ['pie', 'bar', 'line'];
// hide top legend when too many items for device size
var MAX_LEGEND_LENGTH = 25 * (Math.max(1, config.device.size_class));
+var SPLIT_THRESHOLD = config.device.isMobile ? Infinity : 20;
return AbstractRenderer.extend({
className: "o_graph_renderer",
@@ -456,7 +457,11 @@ return AbstractRenderer.extend({
}
}
- var $svgContainer = $('<div/>', {class: 'o_graph_svg_container'});
+ var $svgContainer = $('<div/>', { class: 'o_graph_svg_container'});
+ // Split the tooltip into columns for large data because some portion goes out off the screen.
+ if (data.length >= SPLIT_THRESHOLD) {
+ $svgContainer.addClass('o_tooltip_split_in_columns');
+ }
this.$el.append($svgContainer);
var svg = d3.select($svgContainer[0]).append('svg');
svg.datum(data);
diff --git a/addons/web/static/src/js/views/pivot/pivot_model.js b/addons/web/static/src/js/views/pivot/pivot_model.js
index 4c37b823639..3f195c1ea24 100644
--- a/addons/web/static/src/js/views/pivot/pivot_model.js
+++ b/addons/web/static/src/js/views/pivot/pivot_model.js
@@ -237,7 +237,7 @@ var PivotModel = AbstractModel.extend({
[
this.data.timeRangeDescription.toString(),
this.data.comparisonTimeRangeDescription.toString(),
- 'Variation'
+ _t('Variation')
],
makeMeasure
)
@@ -443,8 +443,10 @@ var PivotModel = AbstractModel.extend({
self._updateMainGroupBys(old_row, self.data.main_row);
}
- self._updateTree(old_col.root, self.data.main_col.root);
- self._updateMainGroupBys(old_col, self.data.main_col);
+ if (!('pivot_column_groupby' in (params.context || {}))) {
+ self._updateTree(old_col.root, self.data.main_col.root);
+ self._updateMainGroupBys(old_col, self.data.main_col);
+ }
});
},
/**
diff --git a/addons/web/static/src/js/views/pivot/pivot_renderer.js b/addons/web/static/src/js/views/pivot/pivot_renderer.js
index 813dc5d38b3..1a3c451f064 100644
--- a/addons/web/static/src/js/views/pivot/pivot_renderer.js
+++ b/addons/web/static/src/js/views/pivot/pivot_renderer.js
@@ -7,6 +7,7 @@ var field_utils = require('web.field_utils');
var config = require('web.config');
var QWeb = core.qweb;
+var _t = core._t;
var PivotRenderer = AbstractRenderer.extend({
tagName: 'table',
@@ -173,7 +174,7 @@ var PivotRenderer = AbstractRenderer.extend({
$thead.append($row);
}
if (this.compare) {
- var colLabels = [this.timeRangeDescription, this.comparisonTimeRangeDescription, 'Variation'];
+ var colLabels = [this.timeRangeDescription, this.comparisonTimeRangeDescription, _t('Variation')];
var dataTypes = ['data', 'comparisonData', 'variation'];
$row = $('<tr>');
for (i = 0; i < 3 * nbrCols; i++) {
diff --git a/addons/web/static/src/scss/form_view.scss b/addons/web/static/src/scss/form_view.scss
index 5642e656dea..0645e00544e 100644
--- a/addons/web/static/src/scss/form_view.scss
+++ b/addons/web/static/src/scss/form_view.scss
@@ -744,6 +744,10 @@
.o_field_widget {
width: 50%;
flex: 0 0 auto;
+
+ &.o_field_many2manytags > .o_field_widget {
+ flex: 1 0 50px;
+ }
}
button.btn-link:first-child {
padding-left: 0;
diff --git a/addons/web/static/src/scss/graph_view.scss b/addons/web/static/src/scss/graph_view.scss
index 71ec5fbca9c..e67edbd3cb5 100644
--- a/addons/web/static/src/scss/graph_view.scss
+++ b/addons/web/static/src/scss/graph_view.scss
@@ -24,6 +24,35 @@
// ligther area color
fill-opacity: 0.1;
}
+ .nv-lineChart .nv-x.nv-axis .nv-axisMaxMin-x {
+ &.nv-axisMin-x text {
+ text-anchor: start !important;
+ }
+ &.nv-axisMax-x text {
+ text-anchor: end !important;
+ }
+ }
+ }
+
+ /* Use less than 50% of the screen area for tooltip and show legends in 3 column of 33% each */
+ &.o_tooltip_split_in_columns .nvtooltip {
+ max-width: 48%;
+ tbody {
+ display: flex;
+ flex-flow: wrap;
+ tr {
+ width: 33%;
+ td {
+ display: inline-block;
+ &.key {
+ min-width: 160px;
+ max-width: 70%;
+ overflow-x: hidden;
+ text-overflow: ellipsis;
+ }
+ }
+ }
+ }
}
}
}
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 43d8f6900e8..8126fcf11c4 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -347,7 +347,7 @@
<t t-raw="item.label"/>
</a>
</t>
- <div class="dropdown-menu" role="menu">
+ <div class="dropdown-menu o_dropdown_menu" role="menu">
<t t-foreach="widget.items[section.name]" t-as="item">
<t t-if="section.name == 'files'">
<t t-set="item.title">