diff options
Diffstat (limited to 'addons/mail/static/src/js/views/activity/activity_renderer.js')
| -rw-r--r-- | addons/mail/static/src/js/views/activity/activity_renderer.js | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/addons/mail/static/src/js/views/activity/activity_renderer.js b/addons/mail/static/src/js/views/activity/activity_renderer.js new file mode 100644 index 00000000..e62d416e --- /dev/null +++ b/addons/mail/static/src/js/views/activity/activity_renderer.js @@ -0,0 +1,210 @@ +odoo.define('mail.ActivityRenderer', function (require) { +"use strict"; + +const AbstractRendererOwl = require('web.AbstractRendererOwl'); +const ActivityCell = require('mail.ActivityCell'); +const ActivityRecord = require('mail.ActivityRecord'); +const { ComponentAdapter } = require('web.OwlCompatibility'); +const core = require('web.core'); +const KanbanColumnProgressBar = require('web.KanbanColumnProgressBar'); +const patchMixin = require('web.patchMixin'); +const QWeb = require('web.QWeb'); +const session = require('web.session'); +const utils = require('web.utils'); + +const _t = core._t; + +const { useState } = owl.hooks; + +/** + * Owl Component Adapter for ActivityRecord which is KanbanRecord (Odoo Widget) + * TODO: Remove this adapter when ActivityRecord is a Component + */ +class ActivityRecordAdapter extends ComponentAdapter { + renderWidget() { + _.invoke(_.pluck(this.widget.subWidgets, '$el'), 'detach'); + this.widget._render(); + } + + updateWidget(nextProps) { + const state = nextProps.widgetArgs[0]; + this.widget._setState(state); + } +} + +/** + * Owl Component Adapter for ActivityCell which is BasicActivity (AbstractField) + * TODO: Remove this adapter when ActivityCell is a Component + */ +class ActivityCellAdapter extends ComponentAdapter { + renderWidget() { + this.widget._render(); + } + + updateWidget(nextProps) { + const record = nextProps.widgetArgs[1]; + this.widget._reset(record); + } +} + +/** + * Owl Component Adapter for KanbanColumnProgressBar (Odoo Widget) + * TODO: Remove this adapter when KanbanColumnProgressBar is a Component + */ +class KanbanColumnProgressBarAdapter extends ComponentAdapter { + renderWidget() { + this.widget._render(); + } + + updateWidget(nextProps) { + const options = nextProps.widgetArgs[0]; + const columnState = nextProps.widgetArgs[1]; + + const columnId = options.columnID; + const nextActiveFilter = options.progressBarStates[columnId].activeFilter; + this.widget.activeFilter = nextActiveFilter ? this.widget.activeFilter : false; + this.widget.columnState = columnState; + this.widget.computeCounters(); + } + + _trigger_up(ev) { + // KanbanColumnProgressBar triggers 3 events before being mounted + // but we don't need to listen to them in our case. + if (this.el) { + super._trigger_up(ev); + } + } +} + +class ActivityRenderer extends AbstractRendererOwl { + constructor(parent, props) { + super(...arguments); + this.qweb = new QWeb(this.env.isDebug(), {_s: session.origin}); + this.qweb.add_template(utils.json_node_to_xml(props.templates)); + this.activeFilter = useState({ + state: null, + activityTypeId: null, + resIds: [] + }); + this.widgetComponents = { + ActivityRecord, + ActivityCell, + KanbanColumnProgressBar, + }; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * Gets all activity resIds in the view. + * + * @returns filtered resIds first then the rest. + */ + get activityResIds() { + const copiedActivityResIds = Array.from(this.props.activity_res_ids) + return copiedActivityResIds.sort((a, b) => this.activeFilter.resIds.includes(a) ? -1 : 0); + } + + /** + * Gets all existing activity type ids. + */ + get activityTypeIds() { + const activities = Object.values(this.props.grouped_activities); + const activityIds = activities.flatMap(Object.keys); + const uniqueIds = Array.from(new Set(activityIds)); + return uniqueIds.map(Number); + } + + getProgressBarOptions(typeId) { + return { + columnID: typeId, + progressBarStates: { + [typeId]: { + activeFilter: this.activeFilter.activityTypeId === typeId, + }, + }, + }; + } + + getProgressBarColumnState(typeId) { + const counts = { planned: 0, today: 0, overdue: 0 }; + for (let activities of Object.values(this.props.grouped_activities)) { + if (typeId in activities) { + counts[activities[typeId].state] += 1; + } + } + return { + count: Object.values(counts).reduce((x, y) => x + y), + fields: { + activity_state: { + type: 'selection', + selection: [ + ['planned', _t('Planned')], + ['today', _t('Today')], + ['overdue', _t('Overdue')], + ], + }, + }, + progressBarValues: { + field: 'activity_state', + colors: { planned: 'success', today: 'warning', overdue: 'danger' }, + counts: counts, + }, + }; + } + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + /** + * @private + * @param {MouseEvent} ev + */ + _onEmptyCellClicked(ev) { + this.trigger('empty_cell_clicked', { + resId: parseInt(ev.currentTarget.dataset.resId, 10), + activityTypeId: parseInt(ev.currentTarget.dataset.activityTypeId, 10), + }); + } + /** + * @private + * @param {MouseEvent} ev + */ + _onSendMailTemplateClicked(ev) { + this.trigger('send_mail_template', { + activityTypeID: parseInt(ev.currentTarget.dataset.activityTypeId, 10), + templateID: parseInt(ev.currentTarget.dataset.templateId, 10), + }); + } + /** + * @private + * @param {CustomEvent} ev + */ + _onSetProgressBarState(ev) { + if (ev.detail.values.activeFilter) { + this.activeFilter.state = ev.detail.values.activeFilter; + this.activeFilter.activityTypeId = ev.detail.columnID; + this.activeFilter.resIds = Object.entries(this.props.grouped_activities) + .filter(([, resIds]) => ev.detail.columnID in resIds && + resIds[ev.detail.columnID].state === ev.detail.values.activeFilter) + .map(([key]) => parseInt(key)); + } else { + this.activeFilter.state = null; + this.activeFilter.activityTypeId = null; + this.activeFilter.resIds = []; + } + } +} + +ActivityRenderer.components = { + ActivityRecordAdapter, + ActivityCellAdapter, + KanbanColumnProgressBarAdapter, +}; +ActivityRenderer.template = 'mail.ActivityRenderer'; + +return patchMixin(ActivityRenderer); + +}); |
