diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 4ddc674255a..567c54abcb1 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -1367,7 +1367,6 @@ var FieldMany2ManyTags = AbstractField.extend({ 'click .o_delete': '_onDeleteTag', }), fieldsToFetch: { - color: {type: 'integer'}, display_name: {type: 'char'}, }, @@ -1380,6 +1379,8 @@ var FieldMany2ManyTags = AbstractField.extend({ if (this.mode === 'edit') { this.className += ' o_input'; } + + this.colorField = this.nodeOptions.color_field; }, //-------------------------------------------------------------------------- @@ -1444,6 +1445,7 @@ var FieldMany2ManyTags = AbstractField.extend({ _getRenderTagsContext: function () { var elements = this.value ? _.pluck(this.value.data, 'data') : []; return { + colorField: this.colorField, elements: elements, readonly: this.mode === "readonly", }; @@ -1571,7 +1573,7 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({ _onOpenColorPicker: function (event) { var tag_id = $(event.currentTarget).data('id'); var tag = _.findWhere(this.value.data, { res_id: tag_id }); - if (tag && 'color' in tag.data) { // if there is a color field on the related model + if (tag && this.colorField in tag.data) { // if there is a color field on the related model this.$color_picker = $(qweb.render('FieldMany2ManyTag.colorpicker', { 'widget': this, 'tag_id': tag_id, @@ -1596,11 +1598,11 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({ if (color === current_color) { return; } + var changes = {}; + changes[this.colorField] = color; this.trigger_up('field_changed', { dataPointID: _.findWhere(this.value.data, {res_id: id}).id, - changes: { - color: color, - }, + changes: changes, force_save: true, }); }, @@ -1611,12 +1613,19 @@ var KanbanFieldMany2ManyTags = FieldMany2ManyTags.extend({ var self = this; this.$el.empty().addClass('o_field_many2manytags o_kanban_tags'); _.each(this.value.data, function (m2m) { - // 10th color is invisible - if ('color' in m2m.data && m2m.data.color !== 10) { - $('') - .addClass('o_tag o_tag_color_' + m2m.data.color) + var $tag = $('') .attr('title', _.str.escapeHTML(m2m.data.display_name)) .appendTo(self.$el); + if (self.colorField in m2m.data) { + if (m2m.data[self.colorField] === 10) { + // 10th color is invisible + $tag.hide(); + } else { + $tag.addClass('o_tag o_tag_color_' + m2m.data[self.colorField]); + } + } else { + // display tags in grey by default + $tag.addClass('o_tag o_tag_color_0'); } }); }, diff --git a/addons/web/static/src/js/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js index 41fc293e383..c1e69a72ce3 100644 --- a/addons/web/static/src/js/services/data_manager.js +++ b/addons/web/static/src/js/services/data_manager.js @@ -355,6 +355,11 @@ return core.Class.extend({ return {}; }), }; + if (attrs.options.color_field) { + // used by m2m tags + attrs.relatedFields[attrs.options.color_field] = { type: 'integer' }; + attrs.fieldsInfo.default[attrs.options.color_field] = {}; + } } } return attrs; diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 06e6b8b2285..80d40404f28 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -759,7 +759,7 @@ - + diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 5c2a93ee775..d4d3a6307f9 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -6017,8 +6017,37 @@ QUnit.module('relational_fields', { QUnit.module('FieldMany2ManyTags'); - QUnit.test('fieldmany2many tags: rendering and edition', function (assert) { - assert.expect(17); + QUnit.test('fieldmany2many tags without color', function (assert) { + assert.expect(4); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '', + mockRPC: function (route, args) { + if (args.method ==='read' && args.model === 'partner_type') { + assert.deepEqual(args.args , [[12], ['display_name']], "should not read any color field"); + } + return this._super.apply(this, arguments); + } + }); + var $input = form.$('.o_field_many2manytags input'); + $input.click(); // opens the dropdown + assert.strictEqual($input.autocomplete('widget').find('li').length, 3, + "autocomplete dropdown should have 3 entries (2 values + 'Search and Edit...')"); + $input.autocomplete('widget').find('li:first()').click(); // adds a tag + assert.strictEqual(form.$('.o_field_many2manytags > span').length, 1, + "should contain 1 tag"); + assert.ok(form.$('.o_field_many2manytags > span:contains("gold")').length, + "should contain newly added tag 'gold'"); + form.destroy(); + }); + + QUnit.test('fieldmany2many tags with color: rendering and edition', function (assert) { + assert.expect(20); this.data.partner.records[0].timmy = [12, 14]; this.data.partner_type.records.push({id: 13, display_name: "red", color: 8}); @@ -6027,7 +6056,7 @@ QUnit.module('relational_fields', { model: 'partner', data: this.data, arch:'
' + - '' + + '' + '', res_id: 1, mockRPC: function (route, args) { @@ -6038,6 +6067,9 @@ QUnit.module('relational_fields', { assert.ok(_.isEqual(_.sortBy(commands[0][2], _.identity.bind(_)), [12, 13]), "new value should be [12, 13]"); } + if (args.method ==='read' && args.model === 'partner_type') { + assert.deepEqual(args.args[1], ['display_name', 'color'], "should read the color field"); + } return this._super.apply(this, arguments); }, }); @@ -6183,7 +6215,7 @@ QUnit.module('relational_fields', { model: 'partner', data: this.data, arch:'
' + - '' + + '' + '', res_id: 1, }); diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js index e8ebae3d6be..f3a653113ec 100644 --- a/addons/web/static/tests/views/kanban_tests.js +++ b/addons/web/static/tests/views/kanban_tests.js @@ -445,7 +445,7 @@ QUnit.module('Views', { arch: '' + '' + '
' + - '' + + '' + '' + '' + '
' +