summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/fields
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2019-09-13 18:07:59 +0200
committerChristophe Simonis <chs@odoo.com>2019-09-13 18:07:59 +0200
commit6c948c36bbf72dd896e0bff03aa7fbddadcbb0cd (patch)
treef8620905c011735d8a3c340c46d1417a54a75972 /addons/web/static/src/js/fields
parent48503fcf08eac6fed12e080d4f501f9bbc8d257d (diff)
parent197474e5b9ad43ab2d587a98136a1a809ce9a2e7 (diff)
[MERGE] forward port branch saas-12.5 up to 197474e5b9a
Diffstat (limited to 'addons/web/static/src/js/fields')
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js58
-rw-r--r--addons/web/static/src/js/fields/field_registry.js1
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js126
-rw-r--r--addons/web/static/src/js/fields/special_fields.js4
4 files changed, 120 insertions, 69 deletions
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index a782e128bc7..da46488cffa 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -40,13 +40,9 @@ var TranslatableFieldMixin = {
* @returns {jQuery}
*/
_renderTranslateButton: function () {
- if (_t.database.multi_lang && this.field.translate && this.res_id) {
+ if (_t.database.multi_lang && this.field.translate) {
var lang = _t.database.parameters.code.split('_')[0].toUpperCase();
- return $('<button>', {
- type: 'button',
- 'class': 'o_field_translate fa fa-globe btn btn-link',
- 'data-code': lang,
- })
+ return $(`<span class="o_field_translate btn btn-link">${lang}</span>`)
.on('click', this._onTranslate.bind(this));
}
return $();
@@ -59,10 +55,16 @@ var TranslatableFieldMixin = {
/**
* open the translation view for the current field
*
+ * @param {MouseEvent} ev
* @private
*/
- _onTranslate: function () {
- this.trigger_up('translate', {fieldName: this.name, id: this.dataPointID});
+ _onTranslate: function (ev) {
+ ev.preventDefault();
+ this.trigger_up('translate', {
+ fieldName: this.name,
+ id: this.dataPointID,
+ isComingFromTranslationAlert: false,
+ });
},
};
@@ -213,7 +215,9 @@ var InputField = DebouncedField.extend({
if (!event || event === this.lastChangeEvent) {
this.isDirty = false;
}
- if (this.isDirty || (event && event.target === this && event.data.changes[this.name] === this.value)) {
+ if (this.isDirty || (event && event.target === this &&
+ event.data.changes &&
+ event.data.changes[this.name] === this.value)) {
if (this.attrs.decorations) {
// if a field is modified, then it could have triggered an onchange
// which changed some of its decorations. Since we bypass the
@@ -498,7 +502,10 @@ var FieldChar = InputField.extend(TranslatableFieldMixin, {
if (this.field.size && this.field.size > 0) {
this.$el.attr('maxlength', this.field.size);
}
- this.$el = this.$el.add(this._renderTranslateButton());
+ if (this.field.translate) {
+ this.$el = this.$el.add(this._renderTranslateButton());
+ this.$el.addClass('o_field_translate');
+ }
return def;
},
/**
@@ -1327,8 +1334,10 @@ var FieldText = InputField.extend(TranslatableFieldMixin, {
start: function () {
if (this.mode === 'edit') {
dom.autoresize(this.$el, this.autoResizeOptions);
-
- this.$el = this.$el.add(this._renderTranslateButton());
+ if (this.field.translate) {
+ this.$el = this.$el.add(this._renderTranslateButton());
+ this.$el.addClass('o_field_translate');
+ }
}
return this._super();
},
@@ -1380,7 +1389,7 @@ var HandleWidget = AbstractField.extend({
description: _lt("Handle"),
noLabel: true,
className: 'o_row_handle fa fa-arrows ui-sortable-handle',
- widthInList: '32px',
+ widthInList: '33px',
tagName: 'span',
supportedFieldTypes: ['integer'],
@@ -1822,8 +1831,11 @@ var FieldBinaryImage = AbstractFieldBinary.extend({
if(this.nodeOptions.zoom) {
var unique = this.recordData.__last_update;
- var url = this._getImageUrl(this.model, this.res_id, 'image', unique);
+ var url = this._getImageUrl(this.model, this.res_id, 'image_1920', unique);
var $img;
+ var imageField = _.find(Object.keys(this.recordData), function(o) {
+ return o.startsWith('image_');
+ });
if(this.nodeOptions.background)
{
@@ -1844,7 +1856,7 @@ var FieldBinaryImage = AbstractFieldBinary.extend({
$img = this.$('img');
}
- if(this.recordData.image) {
+ if(this.recordData[imageField]) {
$img.attr('data-zoom', 1);
$img.attr('data-zoom-image', url);
@@ -1867,6 +1879,17 @@ var FieldBinaryImage = AbstractFieldBinary.extend({
},
});
+var KanbanFieldBinaryImage = FieldBinaryImage.extend({
+ // In kanban views, there is a weird logic to determine whether or not a
+ // click on a card should open the record in a form view. This logic checks
+ // if the clicked element has click handlers bound on it, and if so, does
+ // not open the record (assuming that the click will be handle by someone
+ // else). In the case of this widget, there are clicks handler but they
+ // only apply in edit mode, which is never the case in kanban views, so we
+ // simply remove them.
+ events: {},
+});
+
var FieldBinaryFile = AbstractFieldBinary.extend({
description: _lt("File"),
template: 'FieldBinaryFile',
@@ -1941,7 +1964,7 @@ var FieldBinaryFile = AbstractFieldBinary.extend({
'download': true,
'data': utils.is_bin_size(this.value) ? null : this.value,
},
- error: () => this.call('crash_manager', 'rpc_error', ...arguments),
+ error: (error) => this.call('crash_manager', 'rpc_error', error),
url: '/web/content',
});
ev.stopPropagation();
@@ -3266,6 +3289,7 @@ return {
FieldPdfViewer: FieldPdfViewer,
AbstractFieldBinary: AbstractFieldBinary,
FieldBinaryImage: FieldBinaryImage,
+ KanbanFieldBinaryImage: KanbanFieldBinaryImage,
FieldBoolean: FieldBoolean,
BooleanToggle: BooleanToggle,
FieldChar: FieldChar,
@@ -3278,7 +3302,7 @@ return {
FieldFloatTime: FieldFloatTime,
FieldFloatFactor: FieldFloatFactor,
FieldFloatToggle: FieldFloatToggle,
- FieldPercentage : FieldPercentage,
+ FieldPercentage: FieldPercentage,
FieldInteger: FieldInteger,
FieldMonetary: FieldMonetary,
FieldPercentPie: FieldPercentPie,
diff --git a/addons/web/static/src/js/fields/field_registry.js b/addons/web/static/src/js/fields/field_registry.js
index 942e6fc094a..9adb578639f 100644
--- a/addons/web/static/src/js/fields/field_registry.js
+++ b/addons/web/static/src/js/fields/field_registry.js
@@ -39,6 +39,7 @@ registry
.add('CopyClipboardText', basic_fields.TextCopyClipboard)
.add('CopyClipboardChar', basic_fields.CharCopyClipboard)
.add('image', basic_fields.FieldBinaryImage)
+ .add('kanban.image', basic_fields.KanbanFieldBinaryImage)
.add('binary', basic_fields.FieldBinaryFile)
.add('pdf_viewer', basic_fields.FieldPdfViewer)
.add('monetary', basic_fields.FieldMonetary)
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index c539a3ce12d..b2d3379aef1 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -402,6 +402,52 @@ var FieldMany2One = AbstractField.extend({
};
},
/**
+ * @private
+ * @param {Object} values
+ * @param {string} search_val
+ * @param {Object} domain
+ * @param {Object} context
+ * @returns {Object}
+ */
+ _manageSearchMore: function (values, search_val, domain, context) {
+ var self = this;
+ values = values.slice(0, this.limit);
+ values.push({
+ label: _t("Search More..."),
+ action: function () {
+ var prom;
+ if (search_val !== '') {
+ prom = self._rpc({
+ model: self.field.relation,
+ method: 'name_search',
+ kwargs: {
+ name: search_val,
+ args: domain,
+ operator: "ilike",
+ limit: self.SEARCH_MORE_LIMIT,
+ context: context,
+ },
+ });
+ }
+ Promise.resolve(prom).then(function (results) {
+ var dynamicFilters;
+ if (results) {
+ var ids = _.map(results, function (x) {
+ return x[0];
+ });
+ dynamicFilters = [{
+ description: _.str.sprintf(_t('Quick search: %s'), search_val),
+ domain: [['id', 'in', ids]],
+ }];
+ }
+ self._searchCreatePopup("search", false, {}, dynamicFilters);
+ });
+ },
+ classname: 'o_m2o_dropdown_option',
+ });
+ return values;
+ },
+ /**
* Listens to events 'field_changed' to keep track of the last event that
* has been trigerred. This allows to detect that all changes have been
* acknowledged by the environment.
@@ -552,40 +598,7 @@ var FieldMany2One = AbstractField.extend({
// search more... if more results than limit
if (values.length > self.limit) {
- values = values.slice(0, self.limit);
- values.push({
- label: _t("Search More..."),
- action: function () {
- var prom;
- if (search_val !== '') {
- prom = self._rpc({
- model: self.field.relation,
- method: 'name_search',
- kwargs: {
- name: search_val,
- args: domain,
- operator: "ilike",
- limit: self.SEARCH_MORE_LIMIT,
- context: context,
- },
- });
- }
- Promise.resolve(prom).then(function (results) {
- var dynamicFilters;
- if (results) {
- var ids = _.map(results, function (x) {
- return x[0];
- });
- dynamicFilters = [{
- description: _.str.sprintf(_t('Quick search: %s'), search_val),
- domain: [['id', 'in', ids]],
- }];
- }
- self._searchCreatePopup("search", false, {}, dynamicFilters);
- });
- },
- classname: 'o_m2o_dropdown_option',
- });
+ values = self._manageSearchMore(values, search_val, domain, context);
}
var create_enabled = self.can_create && !self.nodeOptions.no_create;
// quick create
@@ -1768,21 +1781,13 @@ var FieldMany2Many = FieldX2Many.extend({
supportedFieldTypes: ['many2many'],
//--------------------------------------------------------------------------
- // Handlers
+ // Public
//--------------------------------------------------------------------------
-
/**
- * Opens a SelectCreateDialog.
- *
- * @override
- * @private
- * @param {OdooEvent|MouseEvent} ev this event comes either from the 'Add
- * record' link in the list editable renderer, or from the 'Create' button
- * in the kanban view
+ * Opens a SelectCreateDialog
*/
- _onAddRecord: function (ev) {
+ onAddRecordOpenDialog: function () {
var self = this;
- ev.stopPropagation();
var domain = this.record.getDomain({fieldName: this.name});
new dialogs.SelectCreateDialog(this, {
@@ -1808,6 +1813,25 @@ var FieldMany2Many = FieldX2Many.extend({
}
}).open();
},
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Opens a SelectCreateDialog.
+ *
+ * @override
+ * @private
+ * @param {OdooEvent|MouseEvent} ev this event comes either from the 'Add
+ * record' link in the list editable renderer, or from the 'Create' button
+ * in the kanban view
+ */
+ _onAddRecord: function (ev) {
+ ev.stopPropagation();
+ this.onAddRecordOpenDialog();
+ },
+
/**
* Intercepts the 'open_record' event to edit its data and lets it bubble up
* to the form view.
@@ -2552,7 +2576,7 @@ var FieldSelection = AbstractField.extend({
description: _lt("Selection"),
template: 'FieldSelection',
specialData: "_fetchSpecialRelation",
- supportedFieldTypes: ['selection', 'many2one'],
+ supportedFieldTypes: ['selection'],
events: _.extend({}, AbstractField.prototype.events, {
'change': '_onChange',
}),
@@ -2605,10 +2629,14 @@ var FieldSelection = AbstractField.extend({
*/
_renderEdit: function () {
this.$el.empty();
+ var required = this.attrs.modifiersValue && this.attrs.modifiersValue.required;
for (var i = 0 ; i < this.values.length ; i++) {
+ var disabled = required && this.values[i][0] === false;
+
this.$el.append($('<option/>', {
value: JSON.stringify(this.values[i][0]),
- text: this.values[i][1]
+ text: this.values[i][1],
+ style: disabled ? "display: none" : "",
}));
}
var value = this.value;
@@ -2647,9 +2675,7 @@ var FieldSelection = AbstractField.extend({
return v[0] === false && v[1] === '';
});
}
- if (!this.attrs.modifiersValue || !this.attrs.modifiersValue.required) {
- this.values = [[false, this.attrs.placeholder || '']].concat(this.values);
- }
+ this.values = [[false, this.attrs.placeholder || '']].concat(this.values);
},
//--------------------------------------------------------------------------
diff --git a/addons/web/static/src/js/fields/special_fields.js b/addons/web/static/src/js/fields/special_fields.js
index 7b8e53095e1..cfadd9f101a 100644
--- a/addons/web/static/src/js/fields/special_fields.js
+++ b/addons/web/static/src/js/fields/special_fields.js
@@ -51,7 +51,7 @@ var FieldTimezoneMismatch = FieldSelection.extend({
* @private
*/
_renderDateTimeTimezone: function () {
- if (!this.mismatch) {
+ if (!this.mismatch || !this.$option.html()) {
return;
}
var offset = this.recordData.tz_offset.match(/([+-])([0-9]{2})([0-9]{2})/);
@@ -76,7 +76,7 @@ var FieldTimezoneMismatch = FieldSelection.extend({
var value = this.$el.val();
var $span = $('<span class="fa fa-exclamation-triangle o_tz_warning"/>');
- if (this.$option) {
+ if (this.$option && this.$option.html()) {
this.$option.html(this.$option.html().split(' ')[0]);
}