[IMP] web: filter when clicking on tags in Kanban

This commit adds a feature to the widget Many2ManyTags for kanban
views. When a tag is clicked, records are filtered on the given
tag, in addition to the active filters in the search view.
This commit is contained in:
Parth Gajjar
2017-08-31 14:09:32 +02:00
committed by Aaron Bohy
parent db546a3880
commit b6ef149b0d
4 changed files with 81 additions and 2 deletions
@@ -603,6 +603,34 @@ var SearchView = Widget.extend({
current_category = filter.category; current_category = filter.category;
}); });
}, },
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* Activates a filter for a given domain.
* FIXME: the way it is done could be improved, but the actual state of the
* searchview doesn't allow to do much better. For instance, if the same
* filter is added twice, it appears twice in the facets. This should be
* improved when the searchview will be rewrote.
* @param {string} domain the domain to filter on
* @param {string} help the text to display in the facet
*/
addFilter: function (domain, help) {
var filter = {
attrs: {
domain: domain,
help: help,
},
};
var filterWidget = new search_inputs.Filter(filter);
var filterGroup = new search_inputs.FilterGroup([filterWidget], this);
var facet = filterGroup.make_facet([filterGroup.make_value(filter)]);
this.query.add([facet], {silent: true});
this.query.trigger('reset');
},
}); });
_.extend(SearchView, { _.extend(SearchView, {
@@ -28,6 +28,7 @@ var ViewManager = Widget.extend(ControlPanelMixin, {
_.extend(this.env, this._process_search_data(d.domains, d.contexts, d.groupbys)); _.extend(this.env, this._process_search_data(d.domains, d.contexts, d.groupbys));
this.active_view.controller.reload(_.extend({}, this.env)); this.active_view.controller.reload(_.extend({}, this.env));
}, },
add_filter: '_onAddFilter',
switch_view: function(event) { switch_view: function(event) {
if ('res_id' in event.data) { if ('res_id' in event.data) {
this.env.currentId = event.data.res_id; this.env.currentId = event.data.res_id;
@@ -649,6 +650,14 @@ var ViewManager = Widget.extend(ControlPanelMixin, {
// Handlers // Handlers
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/**
* @private
*/
_onAddFilter: function (event) {
if (this.searchview) {
this.searchview.addFilter(event.data.domain, event.data.help);
}
},
/** /**
* This handler is probably called by a sub form view when the user discards * This handler is probably called by a sub form view when the user discards
* its value. The usual result of this is that we switch back to the * its value. The usual result of this is that we switch back to the
@@ -1656,6 +1656,18 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({
}); });
var KanbanFieldMany2ManyTags = FieldMany2ManyTags.extend({ var KanbanFieldMany2ManyTags = FieldMany2ManyTags.extend({
events: _.extend({}, FieldMany2ManyTags.prototype.events, {
'click .o_tag': '_onTagClicked',
}),
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @override
* @private
*/
_render: function () { _render: function () {
var self = this; var self = this;
this.$el.empty().addClass('o_field_many2manytags o_kanban_tags'); this.$el.empty().addClass('o_field_many2manytags o_kanban_tags');
@@ -1670,6 +1682,7 @@ var KanbanFieldMany2ManyTags = FieldMany2ManyTags.extend({
$tag.hide(); $tag.hide();
} else { } else {
$tag.addClass('o_tag o_tag_color_' + m2m.data[self.colorField]); $tag.addClass('o_tag o_tag_color_' + m2m.data[self.colorField]);
$tag.data('res_id', m2m.res_id);
} }
} else { } else {
// display tags in grey by default // display tags in grey by default
@@ -1677,6 +1690,24 @@ var KanbanFieldMany2ManyTags = FieldMany2ManyTags.extend({
} }
}); });
}, },
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @param {MouseEvent} e
*/
_onTagClicked: function (e) {
var resID = $(e.currentTarget).data('res_id');
var record = _.findWhere(this.value.data, {res_id: resID});
var displayName = record.data.display_name;
this.trigger_up('add_filter', {
domain: "[['" + this.name + "','=','" + displayName + "']]",
help: displayName,
});
}
}); });
var FieldMany2ManyCheckBoxes = AbstractField.extend({ var FieldMany2ManyCheckBoxes = AbstractField.extend({
+13 -2
View File
@@ -505,8 +505,8 @@ QUnit.module('Views', {
kanban.destroy(); kanban.destroy();
}); });
QUnit.test('many2many_tags are correctly fetched and displayed', function (assert) { QUnit.test('many2many_tags in kanban views', function (assert) {
assert.expect(10); assert.expect(11);
this.data.partner.records[0].category_ids = [6, 7]; this.data.partner.records[0].category_ids = [6, 7];
this.data.partner.records[1].category_ids = [7]; this.data.partner.records[1].category_ids = [7];
@@ -528,6 +528,14 @@ QUnit.module('Views', {
assert.step(route); assert.step(route);
return this._super.apply(this, arguments); return this._super.apply(this, arguments);
}, },
intercepts: {
add_filter: function (event) {
assert.deepEqual(event.data, {
domain: "[['category_ids','=','gold']]",
help: 'gold',
}, "should trigger an 'add_filter' event with correct data");
},
},
}); });
var $first_record = kanban.$('.o_kanban_record:first()'); var $first_record = kanban.$('.o_kanban_record:first()');
@@ -550,6 +558,9 @@ QUnit.module('Views', {
assert.strictEqual(kanban.$('.o_kanban_record:first()').find('.o_field_many2manytags .o_tag').length, 2, assert.strictEqual(kanban.$('.o_kanban_record:first()').find('.o_field_many2manytags .o_tag').length, 2,
'first record should still contain only 2 tags'); 'first record should still contain only 2 tags');
// click on a tag to trigger a search by tag
kanban.$('.o_tag:contains(gold):first').click();
kanban.destroy(); kanban.destroy();
}); });