diff options
| author | Christophe Simonis <chs@odoo.com> | 2017-11-28 16:57:58 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2017-11-28 16:57:58 +0100 |
| commit | 29590a61cda332a691d4edcdcef2c0dc6499394d (patch) | |
| tree | d4fca4b50f5b40c90ce013f6748d18b95e541228 /addons/web/static/src | |
| parent | f132c8862fb3416cb53c559be32acd880c3a1c7d (diff) | |
| parent | 8fb25e185bb2e78ce7864205b4338022b2f44909 (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.js | 5 | ||||
| -rw-r--r-- | addons/web/static/src/js/core/misc.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/core/rpc.js | 12 | ||||
| -rw-r--r-- | addons/web/static/src/js/fields/basic_fields.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/services/data_manager.js | 6 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/abstract_view.js | 23 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_model.js | 6 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form/form_controller.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form/form_renderer.js | 40 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/kanban/kanban_column.js | 5 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/kanban/kanban_record.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/kanban/kanban_renderer.js | 7 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/list/list_renderer.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/less/layout_boxed.less | 1 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 8 |
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> |
