diff --git a/addons/mail/static/src/js/views/activity/activity_renderer.js b/addons/mail/static/src/js/views/activity/activity_renderer.js index 04c7d00530f..fc9bff93bf5 100644 --- a/addons/mail/static/src/js/views/activity/activity_renderer.js +++ b/addons/mail/static/src/js/views/activity/activity_renderer.js @@ -5,6 +5,7 @@ var AbstractRenderer = require('web.AbstractRenderer'); var ActivityRecord = require('mail.ActivityRecord'); var core = require('web.core'); var field_registry = require('web.field_registry'); +var KanbanColumnProgressBar = require('web.KanbanColumnProgressBar'); var qweb = require('web.QWeb'); var session = require('web.session'); var utils = require('web.utils'); @@ -15,6 +16,9 @@ var QWeb = core.qweb; var ActivityRenderer = AbstractRenderer.extend({ className: 'o_activity_view', + custom_events: { + 'set_progress_bar_state': '_onSetProgressBarState', + }, events: { 'click .o_send_mail_template': '_onSenMailTemplateClicked', 'click .o_activity_empty_cell': '_onEmptyCell', @@ -115,22 +119,39 @@ var ActivityRenderer = AbstractRenderer.extend({ * @returns {jQueryElement} a jquery element */ _renderHeader: function () { - var $tr = $('') - .append($('')) //empty cell for name - .append(_.map(this.state.activity_types, this._renderHeaderCell.bind(this))); - return $('').append($tr); + var self = this; + var activityTypeIds = _.unique(_.flatten(_.map(this.state.grouped_activities, function (act) { return _.keys(act); }))); + var $thead = $(QWeb.render('mail.ActivityViewHeader', { + types: this.state.activity_types, + activityTypeIDs: _.map(activityTypeIds, Number), + })); + activityTypeIds.forEach(function (typeId) { + self._renderProgressBar($thead, typeId); + }); + return $thead; }, /** * @private - * @param {Object} activity_type - * @returns {jQueryElement} a element */ - _renderHeaderCell: function (activity_type) { - return QWeb.render('mail.ActivityViewHeaderCell', { - id: activity_type[0], - name: activity_type[1], - template_list: activity_type[2] || [], + _renderProgressBar: function ($thead, typeId) { + var counts = { planned: 0, today: 0, overdue: 0 }; + _.each(this.state.grouped_activities, function (act) { + if (_.contains(_.keys(act), typeId.toString())) { + counts[act[typeId].state] += 1; + } }); + var progressBar = new KanbanColumnProgressBar(this, { + columnID: typeId, + progressBarStates: {}, + }, { + count: _.reduce(_.values(counts), function (x, y) { return x + y; }), + progressBarValues: { + field: 'activity_state', + colors: { planned: 'success', today: 'warning', overdue: 'danger' }, + counts: counts, + }, + }); + progressBar.appendTo($thead.find('th[data-activity-type-id=' + typeId + ']')); }, /** * @private @@ -155,6 +176,7 @@ var ActivityRenderer = AbstractRenderer.extend({ resId: resId, activityGroup: activity_group, activityTypeId: activity_type_id, + widget: self, })); if (activity_group.state) { var record = self.getKanbanActivityData(activity_group, resId); @@ -180,7 +202,7 @@ var ActivityRenderer = AbstractRenderer.extend({ } return $td; }); - var $tr = $('', {class: 'o_data_row'}) + var $tr = $('', {class: 'o_data_row'}).attr('data-res-id', resId) .append($nameTD) .append($cells); return $tr; @@ -223,6 +245,35 @@ var ActivityRenderer = AbstractRenderer.extend({ templateID: templateID, }); }, + /** + * Rearrange body part of table based on active filter. + * + * @private + * @param {OdooEvent} ev + */ + _onSetProgressBarState: function (ev) { + var self = this; + + this.$('th[class*="o_activity_filter_"]').attr('class', 'o_activity_type_cell'); + this.$('.o_kanban_counter_progress div').removeClass('active progress-bar-striped'); + + var data = ev.data; + var arrangedRecords = this.state.activity_res_ids; + this.activeFilter = data.values.activeFilter; + if (this.activeFilter) { + var filteredResIds = _.map(_.keys(_.pick(this.state.grouped_activities, function (act) { + return act[data.columnID] && act[data.columnID].state === self.activeFilter; + })), Number); + arrangedRecords = _.union(_.intersection(this.state.activity_res_ids, filteredResIds), this.state.activity_res_ids); + this.filteredResIDs = filteredResIds; + } + this.$('tbody').html(_.map(arrangedRecords, this._renderRow.bind(this))); + + if (this.activeFilter) { + var $header = this.$('th.o_activity_type_cell[data-activity-type-id=' + data.columnID + ']'); + $header.addClass('o_activity_filter_' + this.activeFilter); + } + }, }); return ActivityRenderer; diff --git a/addons/mail/static/src/scss/activity_view.scss b/addons/mail/static/src/scss/activity_view.scss index a6cdc0f7c10..91765cfdd8a 100644 --- a/addons/mail/static/src/scss/activity_view.scss +++ b/addons/mail/static/src/scss/activity_view.scss @@ -89,6 +89,15 @@ display: block; } } + .o_activity_filter_planned { + background-color: mix(theme-color('success'), $o-webclient-background-color, 5%); + } + .o_activity_filter_today { + background-color: mix(theme-color('warning'), $o-webclient-background-color, 5%); + } + .o_activity_filter_overdue { + background-color: mix(theme-color('danger'), $o-webclient-background-color, 5%); + } .o_record_selector { color: $o-enterprise-primary-color; } @@ -107,5 +116,14 @@ color: theme-color('success'); } } + .o_kanban_counter { + margin: 5px 0 0 0; + > .o_kanban_counter_progress { + width: 100%; + > div.active { + border: 1px solid; + } + } + } } } diff --git a/addons/mail/static/src/xml/activity_view.xml b/addons/mail/static/src/xml/activity_view.xml index 2abada1486a..2db197373b7 100644 --- a/addons/mail/static/src/xml/activity_view.xml +++ b/addons/mail/static/src/xml/activity_view.xml @@ -1,23 +1,31 @@ - - - - - -