summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2017-11-28 16:57:58 +0100
committerChristophe Simonis <chs@odoo.com>2017-11-28 16:57:58 +0100
commit29590a61cda332a691d4edcdcef2c0dc6499394d (patch)
treed4fca4b50f5b40c90ce013f6748d18b95e541228 /addons/web/static/src
parentf132c8862fb3416cb53c559be32acd880c3a1c7d (diff)
parent8fb25e185bb2e78ce7864205b4338022b2f44909 (diff)
[MERGE] forward port branch 11.0 up to 8fb25e185bb
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/chrome/search_filters.js5
-rw-r--r--addons/web/static/src/js/core/misc.js2
-rw-r--r--addons/web/static/src/js/core/rpc.js12
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js1
-rw-r--r--addons/web/static/src/js/services/data_manager.js6
-rw-r--r--addons/web/static/src/js/views/abstract_view.js23
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js6
-rw-r--r--addons/web/static/src/js/views/form/form_controller.js1
-rw-r--r--addons/web/static/src/js/views/form/form_renderer.js40
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_column.js5
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_record.js1
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_renderer.js7
-rw-r--r--addons/web/static/src/js/views/list/list_renderer.js2
-rw-r--r--addons/web/static/src/less/layout_boxed.less1
-rw-r--r--addons/web/static/src/xml/base.xml8
15 files changed, 90 insertions, 30 deletions
diff --git a/addons/web/static/src/js/chrome/search_filters.js b/addons/web/static/src/js/chrome/search_filters.js
index b9cf1b0fce9..e2eff03546d 100644
--- a/addons/web/static/src/js/chrome/search_filters.js
+++ b/addons/web/static/src/js/chrome/search_filters.js
@@ -187,7 +187,10 @@ var DateTime = Field.extend({
{value: "∄", text: _lt("is not set")}
],
get_value: function (index) {
- return this["datewidget_" + (index || 0)].getValue();
+ // retrieve the datepicker value
+ var value = this["datewidget_" + (index || 0)].getValue();
+ // convert to utc
+ return value.add(-this.getSession().getTZOffset(value), 'minutes');
},
get_domain: function (field, operator) {
switch (operator.value) {
diff --git a/addons/web/static/src/js/core/misc.js b/addons/web/static/src/js/core/misc.js
index 983b26d3606..99c21c14038 100644
--- a/addons/web/static/src/js/core/misc.js
+++ b/addons/web/static/src/js/core/misc.js
@@ -59,12 +59,14 @@ function blockUI() {
var throbber = new Throbber();
throbbers.push(throbber);
throbber.appendTo($(".oe_blockui_spin_container"));
+ $(document.body).addClass('o_ui_blocked');
return tmp;
}
function unblockUI() {
_.invoke(throbbers, 'destroy');
throbbers = [];
+ $(document.body).removeClass('o_ui_blocked');
return $.unblockUI.apply($, arguments);
}
diff --git a/addons/web/static/src/js/core/rpc.js b/addons/web/static/src/js/core/rpc.js
index 6ad91c0e4f9..53d298c9019 100644
--- a/addons/web/static/src/js/core/rpc.js
+++ b/addons/web/static/src/js/core/rpc.js
@@ -51,9 +51,15 @@ return {
}
if (options.method === 'read_group') {
- params.kwargs.domain = options.domain || params.domain || params.kwargs.domain || [];
- params.kwargs.fields = options.fields || params.fields || params.kwargs.fields || [];
- params.kwargs.groupby = options.groupBy || params.groupBy || params.kwargs.groupby || [];
+ if (!(params.args && params.args[0] !== undefined)) {
+ params.kwargs.domain = options.domain || params.domain || params.kwargs.domain || [];
+ }
+ if (!(params.args && params.args[1] !== undefined)) {
+ params.kwargs.fields = options.fields || params.fields || params.kwargs.fields || [];
+ }
+ if (!(params.args && params.args[2] !== undefined)) {
+ params.kwargs.groupby = options.groupBy || params.groupBy || params.kwargs.groupby || [];
+ }
params.kwargs.offset = options.offset || params.offset || params.kwargs.offset;
params.kwargs.limit = options.limit || params.limit || params.kwargs.limit;
// In kwargs, we look for "orderby" rather than "orderBy" (note the absence of capital B),
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index 2872be972a5..2c8b79e7de8 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -652,6 +652,7 @@ var FieldMonetary = InputField.extend({
var currencyField = this.nodeOptions.currency_field || this.field.currency_field || 'currency_id';
var currencyID = this.record.data[currencyField] && this.record.data[currencyField].res_id;
this.currency = session.get_currency(currencyID);
+ this.formatOptions.currency = this.currency; // _formatValue() uses formatOptions
},
});
diff --git a/addons/web/static/src/js/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js
index 449961dd4b8..47cd29399b5 100644
--- a/addons/web/static/src/js/services/data_manager.js
+++ b/addons/web/static/src/js/services/data_manager.js
@@ -423,8 +423,12 @@ return core.Class.extend({
if (fieldsInfo[node.attrs.name].fieldDependencies) {
var deps = fieldsInfo[node.attrs.name].fieldDependencies;
for (var dependency_name in deps) {
+ var dependency_dict = {name: dependency_name, type: deps[dependency_name].type};
if (!(dependency_name in fieldsInfo)) {
- fieldsInfo[dependency_name] = {'name': dependency_name, 'type': deps[dependency_name].type, 'options': deps[dependency_name].options || {}};
+ fieldsInfo[dependency_name] = _.extend({}, dependency_dict, {options: deps[dependency_name].options || {}});
+ }
+ if (!(dependency_name in fields)) {
+ fields[dependency_name] = dependency_dict;
}
}
}
diff --git a/addons/web/static/src/js/views/abstract_view.js b/addons/web/static/src/js/views/abstract_view.js
index 0221ca42cdf..7fb2141db35 100644
--- a/addons/web/static/src/js/views/abstract_view.js
+++ b/addons/web/static/src/js/views/abstract_view.js
@@ -226,9 +226,6 @@ var AbstractView = Class.extend({
return;
}
- attrs.limit = attrs.mode === "tree" ? 80 :
- (attrs.widget === 'many2many_tags' ? 1000 : 40);
-
if (attrs.Widget.prototype.useSubview && !attrs.__no_fetch && !attrs.views[attrs.mode]) {
var context = {};
var regex = /'([a-z]*_view_ref)' *: *'(.*?)'/g;
@@ -244,12 +241,30 @@ var AbstractView = Class.extend({
for (var viewName in views) {
attrs.views[viewName] = views[viewName];
}
+ self._setSubViewLimit(attrs);
}));
+ } else {
+ self._setSubViewLimit(attrs);
}
});
}
return $.when.apply($, defs);
- }
+ },
+ /**
+ * We set here the limit for the number of records fetched (in one page).
+ * This method is only called for subviews, not for main views.
+ *
+ * @private
+ * @param {Object} attrs
+ */
+ _setSubViewLimit: function (attrs) {
+ var view = attrs.views && attrs.views[attrs.mode];
+ var limit = view && view.arch.attrs.limit && parseInt(view.arch.attrs.limit);
+ if (!limit && attrs.widget === 'many2many_tags') {
+ limit = 1000;
+ }
+ attrs.limit = limit || 40;
+ },
});
return AbstractView;
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index 4bd12bf2bc3..c16f635a604 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -1588,7 +1588,9 @@ var BasicModel = AbstractModel.extend({
return $.when.apply($, defs).then(function () {
// ensure to fetch up to 'limit' records (may be useful if records of
// the current page have been removed)
- return self._readUngroupedList(list);
+ return self._readUngroupedList(list).then(function () {
+ return self._fetchX2ManysBatched(list);
+ });
});
},
/**
@@ -2516,6 +2518,8 @@ var BasicModel = AbstractModel.extend({
changes[fieldName] = value ?
this.localData[value].model + ',' + this.localData[value].res_id :
false;
+ } else if (type === 'char' && changes[fieldName] === '') {
+ changes[fieldName] = false;
} else if (changes[fieldName] === null) {
changes[fieldName] = false;
}
diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js
index 39be65a47d6..05c57c435fc 100644
--- a/addons/web/static/src/js/views/form/form_controller.js
+++ b/addons/web/static/src/js/views/form/form_controller.js
@@ -486,6 +486,7 @@ var FormController = BasicController.extend({
* @param {OdooEvent} event
*/
_onOpenRecord: function (event) {
+ event.stopPropagation();
var self = this;
var record = this.model.get(event.data.id, {raw: true});
new dialogs.FormViewDialog(self, {
diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js
index c356b6c761a..3cc08cc35ea 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -200,6 +200,26 @@ var FormRenderer = BasicRenderer.extend({
//--------------------------------------------------------------------------
/**
+ * Add a tooltip on a button
+ *
+ * @private
+ * @param {Object} node
+ * @param {jQuery} $button
+ */
+ _addButtonTooltip: function (node, $button) {
+ var self = this;
+ $button.tooltip({
+ delay: { show: 1000, hide: 0 },
+ title: function () {
+ return qweb.render('WidgetButton.tooltip', {
+ debug: config.debug,
+ state: self.state,
+ node: node,
+ });
+ },
+ });
+ },
+ /**
* @private
* @param {jQueryElement} $el
* @param {Object} node
@@ -316,7 +336,6 @@ var FormRenderer = BasicRenderer.extend({
* @returns {jQueryElement}
*/
_renderHeaderButton: function (node) {
- var self = this;
var $button = $('<button>')
.text(node.attrs.string)
.addClass('btn btn-sm btn-default');
@@ -326,16 +345,7 @@ var FormRenderer = BasicRenderer.extend({
// Display tooltip
if (config.debug || node.attrs.help) {
- $button.tooltip({
- delay: { show: 1000, hide: 0 },
- title: function () {
- return qweb.render('WidgetButton.tooltip', {
- debug: config.debug,
- state: self.state,
- node: node,
- });
- },
- });
+ this._addButtonTooltip(node, $button);
}
return $button;
},
@@ -546,6 +556,12 @@ var FormRenderer = BasicRenderer.extend({
this._addOnClickAction($button, node);
this._handleAttributes($button, node);
this._registerModifiers(node, this.state, $button);
+
+ // Display tooltip
+ if (config.debug || node.attrs.help) {
+ this._addButtonTooltip(node, $button);
+ }
+
return $button;
},
/**
@@ -612,6 +628,8 @@ var FormRenderer = BasicRenderer.extend({
$statusbar.append(widget.$el);
}
});
+ this._handleAttributes($statusbar, node);
+ this._registerModifiers(node, this.state, $statusbar);
return $statusbar;
},
/**
diff --git a/addons/web/static/src/js/views/kanban/kanban_column.js b/addons/web/static/src/js/views/kanban/kanban_column.js
index 907d312365d..d39a3b280e1 100644
--- a/addons/web/static/src/js/views/kanban/kanban_column.js
+++ b/addons/web/static/src/js/views/kanban/kanban_column.js
@@ -52,7 +52,7 @@ var KanbanColumn = Widget.extend({
this.grouped_by_m2o = options.grouped_by_m2o;
this.editable = options.editable;
this.deletable = options.deletable;
- this.draggable = recordOptions.draggable;
+ this.draggable = options.draggable;
this.records_editable = options.records_editable;
this.records_deletable = options.records_deletable;
this.relation = options.relation;
@@ -97,12 +97,13 @@ var KanbanColumn = Widget.extend({
}
this.$header.find('.o_kanban_header_title').tooltip();
- if (!config.device.isMobile && this.draggable !== false) {
+ if (!config.device.isMobile) {
// deactivate sortable in mobile mode. It does not work anyway,
// and it breaks horizontal scrolling in kanban views. Someday, we
// should find a way to use the touch events to make sortable work.
this.$el.sortable({
connectWith: '.o_kanban_group',
+ containment: this.draggable ? '.o_kanban_view' : 'parent',
revert: 0,
delay: 0,
items: '> .o_kanban_record:not(.o_updating)',
diff --git a/addons/web/static/src/js/views/kanban/kanban_record.js b/addons/web/static/src/js/views/kanban/kanban_record.js
index 67279306581..3688d6918c5 100644
--- a/addons/web/static/src/js/views/kanban/kanban_record.js
+++ b/addons/web/static/src/js/views/kanban/kanban_record.js
@@ -37,7 +37,6 @@ var KanbanRecord = Widget.extend({
this.options = options;
this.editable = options.editable;
this.deletable = options.deletable;
- this.draggable = options.draggable;
this.read_only_mode = options.read_only_mode;
this.qweb = options.qweb;
this.subWidgets = {};
diff --git a/addons/web/static/src/js/views/kanban/kanban_renderer.js b/addons/web/static/src/js/views/kanban/kanban_renderer.js
index c9239d97d03..029cef7cf0b 100644
--- a/addons/web/static/src/js/views/kanban/kanban_renderer.js
+++ b/addons/web/static/src/js/views/kanban/kanban_renderer.js
@@ -323,7 +323,7 @@ var KanbanRenderer = BasicRenderer.extend({
var groupByFieldInfo = state.fieldsInfo.kanban[state.groupedBy[0]];
// Deactivate the drag'n'drop if the groupedBy field:
// - is a date or datetime since we group by month or
- // - is readonly
+ // - is readonly (on the field attrs or in the view)
var draggable = true;
if (groupByFieldAttrs) {
if (groupByFieldAttrs.type === "date" || groupByFieldAttrs.type === "datetime") {
@@ -332,6 +332,11 @@ var KanbanRenderer = BasicRenderer.extend({
draggable = !(groupByFieldAttrs.readonly);
}
}
+ if (groupByFieldInfo) {
+ if (draggable && groupByFieldInfo.readonly !== undefined) {
+ draggable = !(groupByFieldInfo.readonly);
+ }
+ }
this.groupedByM2O = groupByFieldAttrs && (groupByFieldAttrs.type === 'many2one');
var grouped_by_field = this.groupedByM2O && groupByFieldAttrs.relation;
var groupByTooltip = groupByFieldInfo && groupByFieldInfo.options.group_by_tooltip;
diff --git a/addons/web/static/src/js/views/list/list_renderer.js b/addons/web/static/src/js/views/list/list_renderer.js
index 00c7415b40f..0ee834a0efc 100644
--- a/addons/web/static/src/js/views/list/list_renderer.js
+++ b/addons/web/static/src/js/views/list/list_renderer.js
@@ -306,7 +306,7 @@ var ListRenderer = BasicRenderer.extend({
} else {
$button.text(node.attrs.string);
}
-
+ this._handleAttributes($button, node);
this._registerModifiers(node, record, $button);
if (record.res_id) {
diff --git a/addons/web/static/src/less/layout_boxed.less b/addons/web/static/src/less/layout_boxed.less
index a81e09f347b..21fcf66efc5 100644
--- a/addons/web/static/src/less/layout_boxed.less
+++ b/addons/web/static/src/less/layout_boxed.less
@@ -15,6 +15,7 @@
}
}
.o_boxed_footer {
+ white-space: nowrap;
border-top: 3px solid @gray;
ul {
margin: 4px 0;
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 78ffa4cac1e..6ecc29652a7 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -41,9 +41,9 @@
<span class="oe_tooltip_technical_title">Domain:</span>
<t t-esc="widget.attrs.domain || JSON.stringify(widget.field.domain)"/>
</li>
- <li t-if="widget.attrs.modifiers and widget.attrs.modifiers != '{}'" data-item="modifiers">
+ <li t-if="widget.attrs.modifiers and !_.isEmpty(widget.attrs.modifiers)" data-item="modifiers">
<span class="oe_tooltip_technical_title">Modifiers:</span>
- <t t-esc="widget.attrs.modifiers"/>
+ <t t-esc="JSON.stringify(widget.attrs.modifiers)"/>
</li>
<li t-if="widget.field and widget.field.change_default" data-item="change_default">
<span class="oe_tooltip_technical_title">Change default:</span>
@@ -90,9 +90,9 @@
<span class="oe_tooltip_technical_title">Context:</span>
<t t-esc="node.attrs.context || widget.field.context"/>
</li>
- <li t-if="node.attrs.modifiers and node.attrs.modifiers != '{}'" data-item="modifiers">
+ <li t-if="node.attrs.modifiers and !_.isEmpty(node.attrs.modifiers)" data-item="modifiers">
<span class="oe_tooltip_technical_title">Modifiers:</span>
- <t t-esc="node.attrs.modifiers"/>
+ <t t-esc="JSON.stringify(node.attrs.modifiers)"/>
</li>
<li t-if="node.attrs.special" data-item="special">
<span class="oe_tooltip_technical_title">Special:</span>