summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2017-11-28 15:12:31 +0100
committerChristophe Simonis <chs@odoo.com>2017-11-28 15:12:31 +0100
commit5851a69aa3ac2b140ffccdbe43427cdad3e74e0c (patch)
tree2da1f6c4d65f4466bc8c263328ae55b007ca6da7 /addons/web/static/src
parent41d2470093a5e18ecebc86f2f878813f1879462d (diff)
parent3f66814a0d01a81bef5456a07da4b1ac8e2281e7 (diff)
[MERGE] forward port branch saas-16 up to 3f66814a0d0
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/rpc.js12
-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/basic/basic_renderer.js12
-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.js28
-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/less/layout_boxed.less1
12 files changed, 76 insertions, 31 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/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/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js
index e99f9ebb6f2..501961d6d76 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 a6cfea6e3be..6cc8a3c8143 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/basic/basic_renderer.js b/addons/web/static/src/js/views/basic/basic_renderer.js
index 543ce01191e..21fabbc2274 100644
--- a/addons/web/static/src/js/views/basic/basic_renderer.js
+++ b/addons/web/static/src/js/views/basic/basic_renderer.js
@@ -357,6 +357,17 @@ var BasicRenderer = AbstractRenderer.extend({
return this.state.count !== 0;
},
/**
+ * This function is called each time a field widget is created, when it is
+ * ready (after its willStart and Start methods are complete). This is the
+ * place where work having to do with $el should be done.
+ *
+ * @private
+ * @param {Widget} widget the field widget instance
+ * @param {Object} node the attrs coming from the arch
+ */
+ _postProcessField: function (widget, node) {
+ },
+ /**
* Registers or updates the modifiers data associated to the given node.
* This method is quiet complex as it handles all the needs of the basic
* renderers:
@@ -524,6 +535,7 @@ var BasicRenderer = AbstractRenderer.extend({
));
},
}, modifiersOptions || {}));
+ self._postProcessField(widget, node);
});
return widget;
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 7b53b60f90c..88e8a99de53 100644
--- a/addons/web/static/src/js/views/form/form_controller.js
+++ b/addons/web/static/src/js/views/form/form_controller.js
@@ -485,6 +485,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 55c23b5d3a2..e18615c8caf 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -247,6 +247,17 @@ var FormRenderer = BasicRenderer.extend({
return idForLabel;
},
/**
+ * @override
+ * @private
+ */
+ _postProcessField: function (widget, node) {
+ this._setIDForLabel(widget, this._getIDForLabel(node.attrs.name));
+ this._handleAttributes(widget.$el, node);
+ if (JSON.parse(node.attrs.default_focus || "0")) {
+ this.defaultFocusField = widget;
+ }
+ },
+ /**
* @private
* @param {Object} node
* @returns {jQueryElement}
@@ -308,23 +319,6 @@ var FormRenderer = BasicRenderer.extend({
return $result;
},
/**
- * @override
- * @private
- * @param {string} node
- * @param {Object} record
- * @param {Object} [options]
- * @returns {AbstractField}
- */
- _renderFieldWidget: function (node, record, options, modifiersOptions) {
- var widget = this._super.apply(this, arguments);
- this._setIDForLabel(widget, this._getIDForLabel(node.attrs.name));
- this._handleAttributes(widget.$el, node);
- if (JSON.parse(node.attrs.default_focus || "0")) {
- this.defaultFocusField = widget;
- }
- return widget;
- },
- /**
* @private
* @param {Object} node
* @returns {jQueryElement}
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 495f98b28ee..361573fd3a1 100644
--- a/addons/web/static/src/js/views/kanban/kanban_record.js
+++ b/addons/web/static/src/js/views/kanban/kanban_record.js
@@ -36,7 +36,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/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;