summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/js/views/activity/activity_renderer.js
diff options
context:
space:
mode:
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.js210
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);
+
+});