import declare from 'dojo/_base/declare';
import lang from 'dojo/_base/lang';
import connect from 'dojo/_base/connect';
import _RightDrawerListMixin from '../_RightDrawerListMixin';
import List from 'argos/List';
import convert from 'argos/Convert';
import action from '../../Action';
import format from '../../Format';
import environment from '../../Environment';
import ErrorManager from 'argos/ErrorManager';
import MODEL_NAMES from '../../Models/Names';
import MODEL_TYPES from 'argos/Models/Types';
import getResource from 'argos/I18n';
import * as activityTypeIcons from '../../Models/Activity/ActivityTypeIcon';
import { getPicklistByActivityType } from '../../Models/Activity/ActivityTypePicklists';
import string from 'dojo/string';
const resource = getResource('activityList');
const hashTagResource = getResource('activityListHashTags');
/**
* @class crm.Views.Activity.List
*
* @extends argos.List
* @mixins crm.Views._RightDrawerListMixin
*
* @requires argos.List
* @requires argos.Utility
* @requires argos.Convert
* @requires argos.ErrorManager
* @requires crm.Action
* @requires crm.Environment
* @requires crm.Format
* @requires crm.Views._RightDrawerListMixin
*
*/
const __class = declare('crm.Views.Activity.List', [List, _RightDrawerListMixin], {
// Localization
allDayText: resource.allDayText,
completeActivityText: resource.completeActivityText,
callText: resource.callText,
calledText: resource.calledText,
addAttachmentActionText: resource.addAttachmentActionText,
overdueText: resource.overdueText,
alarmText: resource.alarmText,
touchedText: resource.touchedText,
importantText: resource.importantText,
recurringText: resource.recurringText,
titleText: resource.titleText,
hashTagQueriesText: {
alarm: hashTagResource.alarmText,
recurring: hashTagResource.recurringText,
timeless: hashTagResource.timelessText,
today: hashTagResource.todayText,
'this-week': hashTagResource.thisWeekText,
yesterday: hashTagResource.yesterdayText,
},
// Card View
itemIcon: activityTypeIcons.default.atAppointment,
format,
getPicklistByActivityType,
// Templates
// Card View
rowTemplate: new Simplate([
`<div as data-action="activateEntry" data-key="{%= $$.getItemActionKey($) %}" data-descriptor="{%: $$.getItemDescriptor($) %}" data-activity-type="{%: $.Type %}">
<div class="widget">
<div class="widget-header">
{%! $$.itemIconTemplate %}<h2 class="widget-title">{%: $$.getItemDescriptor($) %}</h2>
<button class="btn-actions" type="button" data-action="selectEntry" data-key="{%= $$.getItemActionKey($) %}">
<span class="audible">Actions</span>
<svg class="icon" focusable="false" aria-hidden="true" role="presentation">
<use xlink:href="#icon-more"></use>
</svg>
</button>
{%! $$.listActionTemplate %}
</div>
<div class="card-content">
{%! $$.itemRowContentTemplate %}
</div>
</div>
</div>`,
]),
activityTimeTemplate: new Simplate([
'{% if ($$.isTimelessToday($)) { %}',
'{%: $$.allDayText %}',
'{% } else { %}',
'{%: $$.format.relativeDate($.StartDate, argos.Convert.toBoolean($.Timeless)) %}', // TODO: Avoid global
'{% } %}',
]),
itemTemplate: new Simplate([
'<p class="listview-heading">',
'<span class="p-description">{%: $$.format.picklist($$.app.picklistService, null, null, $$.getPicklistByActivityType($.Type, "Description"))($.Description) %}</span>',
'</p>',
'<p class="micro-text">',
'{%! $$.activityTimeTemplate %}',
'</p>',
'<p class="micro-text">{%! $$.nameTemplate %}</p>',
]),
nameTemplate: new Simplate([
'{% if ($.ContactName) { %}',
'{%: $.ContactName %} | {%: $.AccountName %}',
'{% } else if ($.AccountName) { %}',
'{%: $.AccountName %}',
'{% } else { %}',
'{%: $.LeadName %}',
'{% } %}',
]),
// View Properties
id: 'activity_list',
security: null, // 'Entities/Activity/View',
iconClass: 'fa fa-check-square-o fa-lg',
detailView: 'activity_detail',
insertView: 'activity_types_list',
historyEditView: 'history_edit',
enableActions: true,
pageSize: 105,
resourceKind: 'activities',
modelName: MODEL_NAMES.ACTIVITY,
hashTagQueries: {
alarm: 'Alarm eq true',
recurring: 'Recurring eq true',
timeless: 'Timeless eq true',
yesterday: function computeYesterday() {
const now = moment();
const yesterdayStart = now.clone()
.subtract(1, 'days')
.startOf('day');
const yesterdayEnd = yesterdayStart.clone()
.endOf('day');
const query = `((Timeless eq false and StartDate between @${convert.toIsoStringFromDate(yesterdayStart.toDate())}@ and @${convert.toIsoStringFromDate(yesterdayEnd.toDate())}@) or (Timeless eq true and StartDate between @${yesterdayStart.format('YYYY-MM-DDT00:00:00[Z]')}@ and @${yesterdayEnd.format('YYYY-MM-DDT23:59:59[Z]')}@))`;
return query;
},
today: function computeToday() {
const now = moment();
const todayStart = now.clone()
.startOf('day');
const todayEnd = todayStart.clone()
.endOf('day');
const query = `((Timeless eq false and StartDate between @${convert.toIsoStringFromDate(todayStart.toDate())}@ and @${convert.toIsoStringFromDate(todayEnd.toDate())}@) or (Timeless eq true and StartDate between @${todayStart.format('YYYY-MM-DDT00:00:00[Z]')}@ and @${todayEnd.format('YYYY-MM-DDT23:59:59[Z]')}@))`;
return query;
},
'this-week': function computeThisWeek() {
const now = moment();
const weekStartDate = now.clone()
.startOf('week');
const weekEndDate = weekStartDate.clone()
.endOf('week');
const query = `((Timeless eq false and StartDate between @${convert.toIsoStringFromDate(weekStartDate.toDate())}@ and @${convert.toIsoStringFromDate(weekEndDate.toDate())}@) or (Timeless eq true and StartDate between @${weekStartDate.format('YYYY-MM-DDT00:00:00[Z]')}@ and @${weekEndDate.format('YYYY-MM-DDT23:59:59[Z]')}@))`;
return query;
},
},
defaultSearchTerm: function defaultSearchTerm() {
if (App.enableHashTags) {
const hashtag = this.hashTagQueriesText['this-week'];
if (typeof hashtag === 'string' && hashtag.startsWith('#')) {
return hashtag;
}
return `#${hashtag}`;
}
return '';
},
formatSearchQuery: function formatSearchQuery(searchQuery) {
return `upper(Description) like "%${this.escapeSearchQuery(searchQuery.toUpperCase())}%"`;
},
formatDateTime: function formatDateTime() {
return 'StartTime';
},
getItemActionKey: function getItemActionKey(entry) {
return entry.$key;
},
getItemDescriptor: function getItemDescriptor(entry) {
return entry.$descriptor;
},
createIndicatorLayout: function createIndicatorLayout() {
return this.itemIndicators || (this.itemIndicators = [{
id: 'alarm',
cls: 'notification',
label: this.alarmText,
onApply: function onApply(entry, parent) {
this.isEnabled = parent.hasAlarm(entry);
},
}, {
id: 'important',
cls: 'star-filled',
label: this.importantText,
onApply: function onApply(entry, parent) {
this.isEnabled = parent.isImportant(entry);
},
}, {
id: 'recurring',
cls: 'load',
label: this.recurringText,
onApply: function onApply(entry, parent) {
this.isEnabled = parent.isRecurring(entry, this);
},
}, {
id: 'overdue',
cls: 'error',
label: this.overdueText,
onApply: function onApply(entry, parent) {
this.isEnabled = parent.isOverdue(entry);
},
}, {
id: 'touched',
cls: 'flag',
label: this.touchedText,
onApply: function onApply(entry, parent) {
this.isEnabled = parent.hasBeenTouched(entry);
},
}]);
},
hasBeenTouched: function hasBeenTouched(entry) {
if (entry.ModifyDate) {
const modifiedDate = moment(convert.toDateFromString(entry.ModifyDate));
const currentDate = moment()
.endOf('day');
const weekAgo = moment()
.subtract(1, 'weeks');
return modifiedDate.isAfter(weekAgo) &&
modifiedDate.isBefore(currentDate);
}
return false;
},
isImportant: function isImportant(entry) {
return entry.Priority === 'High';
},
isOverdue: function isOverdue(entry) {
if (entry.StartDate) {
const startDate = convert.toDateFromString(entry.StartDate);
const currentDate = new Date();
const seconds = Math.round((currentDate - startDate) / 1000);
const mins = seconds / 60;
if (mins >= 1) {
return true;
}
}
return false;
},
isTimelessToday: function isTimelessToday(entry) {
if (!entry || !entry.Timeless) {
return false;
}
const start = moment(entry.StartDate);
return this._isTimelessToday(start);
},
_isTimelessToday: function _isTimelessToday(start) {
// Start is UTC, convert it to local time so we can compare it against "now"
start.subtract({
minutes: start.utcOffset(),
});
return start.isAfter(moment()
.startOf('day')) && start.isBefore(moment()
.endOf('day'));
},
isRecurring: function isRecurring(entry) {
if (entry.RecurrenceState) {
if (entry.RecurrenceState === 'rstOccurrence') {
return true;
}
}
return false;
},
hasAlarm: function hasAlarm(entry) {
if (entry.Alarm === true) {
return true;
}
return false;
},
getItemIconClass: function getItemIconClass(entry) {
const type = entry && entry.Type;
return this._getItemIconClass(type);
},
_getItemIconClass: function _getItemIconClass(type) {
return activityTypeIcons.default[type];
},
createActionLayout: function createActionLayout() {
return this.actions || (this.actions = [{
id: 'complete',
cls: 'checkbox',
label: this.completeActivityText,
enabled: function enabled(theAction, selection) {
const entry = selection && selection.data;
if (!entry) {
return false;
}
let recur = false;
if (entry.RecurrenceState === 'rstOccurrence') {
recur = true;
}
return entry.Leader.$key === App.context.user.$key && !recur;
},
fn: (function fn(theAction, selection) {
const entry = selection && selection.data && selection.data;
entry.CompletedDate = new Date();
entry.Result = 'Complete';
environment.refreshActivityLists();
this.completeActivity(entry);
})
.bindDelegate(this),
}, {
id: 'call',
cls: 'phone',
label: this.callText,
enabled: function enabled(theAction, selection) {
const entry = selection && selection.data;
return entry && entry.PhoneNumber;
},
fn: function fn(theAction, selection) {
const entry = selection && selection.data;
const phone = entry && entry.PhoneNumber;
if (phone) {
this.recordCallToHistory(function initiateCall() {
App.initiateCall(phone);
}.bindDelegate(this), entry);
}
}.bindDelegate(this),
}, {
id: 'addAttachment',
cls: 'attach',
label: this.addAttachmentActionText,
fn: action.addAttachment.bindDelegate(this),
}]);
},
recordCallToHistory: function recordCallToHistory(complete, entry) {
const tempEntry = {
$name: 'History',
Type: 'atPhoneCall',
ContactName: entry.ContactName,
ContactId: entry.ContactId,
AccountName: entry.AccountName,
AccountId: entry.AccountId,
Description: string.substitute(this.calledText, [entry.ContactName || '']),
UserId: App.context && App.context.user.$key,
UserName: App.context && App.context.user.UserName,
Duration: 15,
CompletedDate: (new Date()),
};
this.navigateToHistoryInsert('atPhoneCall', tempEntry, complete);
},
navigateToHistoryInsert: function navigateToHistoryInsert(type, entry, complete) {
action.navigateToHistoryInsert(entry, complete);
},
completeActivity: function completeActivity(entry) {
const activityModel = App.ModelManager.getModel(MODEL_NAMES.ACTIVITY, MODEL_TYPES.SDATA);
if (activityModel) {
activityModel.completeActivity(entry).then(() => {
connect.publish('/app/refresh', [{
resourceKind: 'history',
}]);
this.clear();
this.refresh();
}, (err) => {
this.onRequestFailure(err, this);
});
}
},
onRequestFailure: function onRequestFailure(response, o) {
ErrorManager.addError(response, o, {}, 'failure');
},
});
lang.setObject('Mobile.SalesLogix.Views.Activity.List', __class);
export default __class;