diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-09-07 14:43:48 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-09-07 14:43:48 +0200 |
| commit | 49c3264ce0f73a746f9a229dba423f6c0ea3d485 (patch) | |
| tree | 9cd4603a7b9708d061802f9e0f638e5c684d15a9 /addons/web/static/src | |
| parent | b4c72220c72e22328b3a96024c59d79889b71ae5 (diff) | |
| parent | 4850fb08385de3f0851a732c97c90402e89838b7 (diff) | |
[MERGE] forward port branch saas-11.3 up to 4850fb08385
Diffstat (limited to 'addons/web/static/src')
9 files changed, 70 insertions, 28 deletions
diff --git a/addons/web/static/src/js/core/pyeval.js b/addons/web/static/src/js/core/pyeval.js index ee4ac697fd9..810cb7f38bd 100644 --- a/addons/web/static/src/js/core/pyeval.js +++ b/addons/web/static/src/js/core/pyeval.js @@ -642,13 +642,15 @@ var relativedelta = py.type('relativedelta', null, { this._fix(); }, _fix: function () { + var self = this; var months = asJS(this.ops.months); if (Math.abs(months) > 11) { var s = months > 0 ? 1 : -1; - var r = utils.divmod(months * s, 12); - this.ops.months = py.float.fromJSON(r.mod*s); - this.ops.years = py.float.fromJSON( - asJS(this.ops.years) + r.div*s); + utils.divmod(months * s, 12, function (years, months) { + self.ops.months = py.float.fromJSON(months*s); + self.ops.years = py.float.fromJSON( + asJS(self.ops.years) + years*s); + }); } this._has_time = 0; }, diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 4a3f3230ef7..a7bd0fd5e8d 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -447,7 +447,7 @@ var FieldDate = InputField.extend({ this.datewidget = this._makeDatePicker(); this.datewidget.on('datetime_changed', this, function () { var value = this._getValue(); - if ((!value && this.value) || (value && !value.isSame(this.value))) { + if ((!value && this.value) || (value && !this._isSameValue(value))) { this._setValue(value); } }); @@ -2348,19 +2348,18 @@ var FieldDomain = AbstractField.extend({ // Convert char value to array value var value = this.value || "[]"; - var domain = Domain.prototype.stringToArray(value); // Create the domain selector or change the value of the current one... var def; if (!this.domainSelector) { - this.domainSelector = new DomainSelector(this, this._domainModel, domain, { + this.domainSelector = new DomainSelector(this, this._domainModel, value, { readonly: this.mode === "readonly" || this.inDialog, filters: this.fsFilters, debugMode: session.debug, }); def = this.domainSelector.prependTo(this.$el); } else { - def = this.domainSelector.setDomain(domain); + def = this.domainSelector.setDomain(value); } // ... then replace the other content (matched records, etc) return def.then(this._replaceContent.bind(this)); diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index deccd3d7709..25722cd3db9 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -578,10 +578,11 @@ var FieldMany2One = AbstractField.extend({ * @param {OdooEvent} ev */ _onInputKeyup: function (ev) { - if (ev.which === $.ui.keyCode.ENTER) { - // If we pressed enter, we want to prevent _onInputFocusout from + if (ev.which === $.ui.keyCode.ENTER || ev.which === $.ui.keyCode.TAB) { + // If we pressed enter or tab, we want to prevent _onInputFocusout from // executing since it would open a M2O dialog to request // confirmation that the many2one is not properly set. + // It's a case that is already handled by the autocomplete lib. return; } this.isDirty = true; 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 32bab9373a9..10283c308f6 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -2447,11 +2447,11 @@ var BasicModel = AbstractModel.extend({ } var def = $.Deferred(); - + var evalContext = this._getEvalContext(record); this._rpc({ model: domainModel, method: 'search_count', - args: [Domain.prototype.stringToArray(domainValue)], + args: [Domain.prototype.stringToArray(domainValue, evalContext)], context: context }) .then(_.identity, function (error, e) { diff --git a/addons/web/static/src/js/views/kanban/kanban_model.js b/addons/web/static/src/js/views/kanban/kanban_model.js index 6c4ea1f133c..5d606324023 100644 --- a/addons/web/static/src/js/views/kanban/kanban_model.js +++ b/addons/web/static/src/js/views/kanban/kanban_model.js @@ -61,11 +61,15 @@ var KanbanModel = BasicModel.extend({ if (!groupByField || groupByField.type !== 'many2one') { return $.Deferred().reject(); // only supported when grouped on m2o } + // ignore action default which may be for another model + var context = _.pick(parent.context, function (value, key) { + return key.slice(0,8) !== 'default_'; + }); return this._rpc({ model: groupByField.relation, method: 'name_create', args: [name], - context: parent.context, // todo: combine with view context + context: context, // todo: combine with view context }) .then(function (result) { var newGroup = self._makeDataPoint({ @@ -272,6 +276,9 @@ var KanbanModel = BasicModel.extend({ options.groupBy = this.defaultGroupedBy; } var def = this._super(id, options); + if (options && options.loadMoreOffset) { + return def; + } return this._reloadProgressBarGroupFromRecord(id, def); }, /** 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 76ad3a82063..682b98f82fe 100644 --- a/addons/web/static/src/js/views/list/list_renderer.js +++ b/addons/web/static/src/js/views/list/list_renderer.js @@ -193,7 +193,6 @@ var ListRenderer = BasicRenderer.extend({ reject = columnInvisibleFields[c.attrs.name]; } if (!reject && c.attrs.widget === 'handle') { - self.hasHandle = true; self.handleField = c.attrs.name; } return reject; @@ -657,6 +656,8 @@ var ListRenderer = BasicRenderer.extend({ this._computeAggregates(); $table.toggleClass('o_list_view_grouped', is_grouped); $table.toggleClass('o_list_view_ungrouped', !is_grouped); + this.hasHandle = this.state.orderedBy.length === 0 || + this.state.orderedBy[0].name === this.handleField; if (is_grouped) { $table .append(this._renderHeader(true)) 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 b5648d358a9..390ccfed6e1 100644 --- a/addons/web/static/src/js/views/pivot/pivot_renderer.js +++ b/addons/web/static/src/js/views/pivot/pivot_renderer.js @@ -14,6 +14,16 @@ var PivotRenderer = AbstractRenderer.extend({ 'hover td': '_onTdHover', }), + /** + * @override + * @param {Object} [params.widgets] mapping (fieldName -> widget) used to + * format the cells + */ + init: function (parent, state, params) { + this._super.apply(this, arguments); + this.fieldWidgets = params.widgets || {}; + }, + //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- @@ -141,7 +151,8 @@ var PivotRenderer = AbstractRenderer.extend({ if (value !== undefined) { name = this.state.measures[j % nbrMeasures]; measure = this.state.fields[name]; - value = field_utils.format[measureTypes[j % nbrMeasures]](value, measure); + var formatter = this.fieldWidgets[name] || measureTypes[j % nbrMeasures]; + value = field_utils.format[formatter](value, measure); } $cell = $('<td>') .data('id', rows[i].id) diff --git a/addons/web/static/src/js/views/pivot/pivot_view.js b/addons/web/static/src/js/views/pivot/pivot_view.js index 251fa10200d..519037e95bf 100644 --- a/addons/web/static/src/js/views/pivot/pivot_view.js +++ b/addons/web/static/src/js/views/pivot/pivot_view.js @@ -44,6 +44,7 @@ var PivotView = AbstractView.extend({ var measures = {}; var groupableFields = {}; + var widgets = {}; this.fields.__count = {string: _t("Count"), type: "integer"}; _.each(this.fields, function (field, name) { @@ -65,6 +66,10 @@ var PivotView = AbstractView.extend({ name += ':' + field.attrs.interval; } + if (field.attrs.widget) { + widgets[name] = field.attrs.widget; + } + // add active measures to the measure list. This is very rarely // necessary, but it can be useful if one is working with a // functional field non stored, but in a model with an overrided @@ -96,6 +101,8 @@ var PivotView = AbstractView.extend({ this.loadParams.rowGroupBys = rowGroupBys; this.loadParams.fields = this.fields; + this.rendererParams.widgets = widgets; + this.controllerParams.title = params.title || this.arch.attrs.string || _t("Untitled"); this.controllerParams.enableLinking = !this.arch.attrs.disable_linking; this.controllerParams.measures = measures; diff --git a/addons/web/static/src/js/widgets/domain_selector.js b/addons/web/static/src/js/widgets/domain_selector.js index c5a561b1b77..c06340cd61c 100644 --- a/addons/web/static/src/js/widgets/domain_selector.js +++ b/addons/web/static/src/js/widgets/domain_selector.js @@ -177,18 +177,12 @@ var DomainTree = DomainNode.extend({ * operator from the domain. * @see DomainTree._addFlattenedChildren */ - init: function (parent, model, domain, options) { + init: function (parent, model, domain) { this._super.apply(this, arguments); - try { - domain = Domain.prototype.stringToArray(domain); - } catch (err) { - // TODO: domain could contain `parent` for example, which is - // currently not handled by the DomainSelector - this.invalidDomain = true; - this.children = []; - return; + var parsedDomain = this._parseDomain(domain); + if (parsedDomain) { + this._initialize(parsedDomain); } - this._initialize(domain); }, /** * @see DomainNode.start @@ -386,6 +380,23 @@ var DomainTree = DomainNode.extend({ }); }).bind(this)); }, + /** + * @param {string} domain + * @returns {Array[]} + */ + _parseDomain: function (domain) { + var parsedDomain = false; + try { + parsedDomain = Domain.prototype.stringToArray(domain); + this.invalidDomain = false; + } catch (err) { + // TODO: domain could contain `parent` for example, which is + // currently not handled by the DomainSelector + this.invalidDomain = true; + this.children = []; + } + return parsedDomain; + }, //-------------------------------------------------------------------------- // Handlers @@ -471,14 +482,17 @@ var DomainSelector = DomainTree.extend({ * If the internal domain value was already equal to the given one, this * does nothing. * - * @param {Array|string} domain + * @param {string} domain * @returns {Deferred} resolved when the rerendering is finished */ setDomain: function (domain) { - if (Domain.prototype.arrayToString(domain) === Domain.prototype.arrayToString(this.getDomain())) { + if (domain === Domain.prototype.arrayToString(this.getDomain())) { return $.when(); } - return this._redraw(domain); + var parsedDomain = this._parseDomain(domain); + if (parsedDomain) { + return this._redraw(parsedDomain); + } }, //-------------------------------------------------------------------------- |
