import declare from 'dojo/_base/declare';
import lang from 'dojo/_base/lang';
import string from 'dojo/string';
import ErrorManager from 'argos/ErrorManager';
import convert from 'argos/Convert';
import List from 'argos/List';
import _LegacySDataListMixin from 'argos/_LegacySDataListMixin';
import getResource from 'argos/I18n';
import * as activityTypeIcons from '../../Models/Activity/ActivityTypeIcon';
const resource = getResource('calendarDayView');
const dtFormatResource = getResource('calendarDayViewDateTimeFormat');
/**
* @class crm.Views.Calendar.DayView
*
* @extends argos.List
* @mixins argos.List
* @mixins argos._LegacySDataListMixin
*
* @requires argos.List
* @requires argos._LegacySDataListMixin
* @requires argos.Convert
* @requires argos.ErrorManager
*
* @requires moment
*
*/
const __class = declare('crm.Views.Calendar.DayView', [List, _LegacySDataListMixin], {
// Localization
titleText: resource.titleText,
eventDateFormatText: dtFormatResource.eventDateFormatText,
dateHeaderFormatText: dtFormatResource.dateHeaderFormatText,
startTimeFormatText: dtFormatResource.startTimeFormatText,
startTimeFormatText24: dtFormatResource.startTimeFormatText24,
todayText: resource.todayText,
dayText: resource.dayText,
weekText: resource.weekText,
monthText: resource.monthText,
allDayText: resource.allDayText,
eventHeaderText: resource.eventHeaderText,
activityHeaderText: resource.activityHeaderText,
eventMoreText: resource.eventMoreText,
toggleCollapseText: resource.toggleCollapseText,
enablePullToRefresh: false,
toggleCollapseClass: 'fa fa-chevron-down',
toggleExpandClass: 'fa fa-chevron-right',
// Templates
widgetTemplate: new Simplate([
'<div id="{%= $.id %}" title="{%= $.titleText %}" class="overthrow list {%= $.cls %}" {% if ($.resourceKind) { %}data-resource-kind="{%= $.resourceKind %}"{% } %}>',
'<div data-dojo-attach-point="searchNode"></div>',
'{%! $.navigationTemplate %}',
'<div style="clear:both"></div>',
'<div class="event-content event-hidden" data-dojo-attach-point="eventContainerNode">',
'<h2 data-action="toggleGroup"><button data-dojo-attach-point="collapseButton" class="{%= $$.toggleCollapseClass %}" aria-label="{%: $$.toggleCollapseText %}"></button>{%= $.eventHeaderText %}</h2>',
'<ul class="list-content" data-dojo-attach-point="eventContentNode"></ul>',
'{%! $.eventMoreTemplate %}',
'</div>',
'<h2>{%= $.activityHeaderText %}</h2>',
'<ul class="list-content" data-dojo-attach-point="contentNode"></ul>',
'{%! $.moreTemplate %}',
'</div>',
]),
rowTemplate: new Simplate([
'<li data-action="activateEntry" data-key="{%= $.$key %}" data-descriptor="{%: $.Description %}" data-activity-type="{%: $.Type %}">',
'<table class="calendar-entry-table"><tr>',
'<td class="entry-table-icon">',
'<button data-action="selectEntry" class="list-item-selector button {%= $$.activityTypeIcon[$.Type] %}">',
'</button>',
'</td>',
'<td class="entry-table-time">{%! $$.timeTemplate %}</td>',
'<td class="entry-table-description">{%! $$.itemTemplate %}</td>',
'</tr></table>',
'</li>',
]),
eventRowTemplate: new Simplate([
'<li data-action="activateEntry" data-key="{%= $.$key %}" data-descriptor="{%: $.$descriptor %}" data-activity-type="Event">',
'<table class="calendar-entry-table"><tr>',
'<td class="entry-table-icon">',
'<button data-action="selectEntry" class="list-item-selector button {%= $$.activityTypeIcon.event %}">',
'</button>',
'</td>',
'<td class="entry-table-description">{%! $$.eventItemTemplate %}</td>',
'</tr></table>',
'</li>',
]),
timeTemplate: new Simplate([
'{% if ($.Timeless) { %}',
'<span class="p-time">{%= $$.allDayText %}</span>',
'{% } else { %}',
'<span class="p-time">{%: crm.Format.date($.StartDate, (App.is24HourClock()) ? $$.startTimeFormatText24 : $$.startTimeFormatText) %}</span>',
'{% } %}',
]),
itemTemplate: new Simplate([
'<p class="listview-heading p-description">{%: $.Description %}</p>',
'<p class="micro-text">{%= $$.nameTemplate.apply($) %}</p>',
]),
eventItemTemplate: new Simplate([
'<p class="listview-heading p-description">{%: $.Description %} ({%: $.Type %})</p>',
'<p class="micro-text">{%! $$.eventNameTemplate %}</p>',
]),
nameTemplate: new Simplate([
'{% if ($.ContactName) { %}',
'{%: $.ContactName %} / {%: $.AccountName %}',
'{% } else if ($.AccountName) { %}',
'{%: $.AccountName %}',
'{% } else { %}',
'{%: $.LeadName %}',
'{% } %}',
]),
eventNameTemplate: new Simplate([
'{%: crm.Format.date($.StartDate, $$.eventDateFormatText) %}',
' - ',
'{%: crm.Format.date($.EndDate, $$.eventDateFormatText) %}',
]),
navigationTemplate: new Simplate([
'<div class="split-buttons">',
'<button data-tool="today" data-action="getToday" class="button">{%: $.todayText %}</button>',
'<button data-tool="selectdate" data-action="selectDate" class="button fa fa-calendar"><span></span></button>',
'<button data-tool="day" class="button current">{%: $.dayText %}</button>',
'<button data-tool="week" data-action="navigateToWeekView" class="button">{%: $.weekText %}</button>',
'<button data-tool="month" data-action="navigateToMonthView" class="button">{%: $.monthText %}</button>',
'</div>',
'<div class="nav-bar">',
'<button data-tool="next" data-action="getNextDay" class="button button-next fa fa-arrow-right fa-lg"><span></span></button>',
'<button data-tool="prev" data-action="getPrevDay" class="button button-prev fa fa-arrow-left fa-lg"><span></span></button>',
'<h4 class="date-text" data-dojo-attach-point="dateNode"></h4>',
'</div>',
]),
eventMoreTemplate: new Simplate([
'<div class="list-more" data-dojo-attach-point="eventMoreNode">',
'<button class="button" data-action="activateEventMore">',
'<span data-dojo-attach-point="eventRemainingContentNode">{%= $.eventMoreText %}</span>',
'</button>',
'</div>',
]),
attributeMap: {
listContent: {
node: 'contentNode',
type: 'innerHTML',
},
eventListContent: {
node: 'eventContentNode',
type: 'innerHTML',
},
dateContent: {
node: 'dateNode',
type: 'innerHTML',
},
eventRemainingContent: {
node: 'eventRemainingContentNode',
type: 'innerHTML',
},
remainingContent: {
node: 'remainingContentNode',
type: 'innerHTML',
},
},
// View Properties
id: 'calendar_daylist',
cls: 'activities-for-day',
iconClass: 'fa fa-calendar fa-lg',
datePickerView: 'generic_calendar',
monthView: 'calendar_monthlist',
weekView: 'calendar_weeklist',
activityDetailView: 'activity_detail',
eventDetailView: 'event_detail',
insertView: 'activity_types_list',
enableSearch: false,
currentDate: null,
contractName: 'system',
queryOrderBy: 'StartDate desc',
querySelect: [
'Description',
'StartDate',
'Type',
'AccountName',
'ContactName',
'LeadId',
'LeadName',
'UserId',
'Timeless',
'Recurring',
],
eventFeed: null,
eventPageSize: 3,
eventQuerySelect: [
'StartDate',
'EndDate',
'Description',
'Type',
],
activityTypeIcon: activityTypeIcons.default,
resourceKind: 'activities',
pageSize: 1000,
expose: false,
continuousScrolling: false,
_onRefresh: function _onRefresh(o) {
this.inherited(arguments);
if (o.resourceKind === 'activities' || o.resourceKind === 'events') {
this.refreshRequired = true;
}
},
init: function init() {
this.inherited(arguments);
this.currentDate = moment().startOf('day');
},
toggleGroup: function toggleGroup(params) {
const node = params.$source;
if (node && node.parentNode) {
$(node).toggleClass('collapsed');
$(node.parentNode).toggleClass('collapsed-event');
const button = this.collapseButton;
if (button) {
$(button).toggleClass(this.toggleCollapseClass);
$(button).toggleClass(this.toggleExpandClass);
}
}
},
refresh: function refresh() {
this.clear();
this.options = this.options || {};
this.options.where = this.formatQueryForActivities();
this.feed = null;
this.eventFeed = null;
this.set('dateContent', this.currentDate.format(this.dateHeaderFormatText));
this.requestData();
this.requestEventData();
},
requestEventData: function requestEventData() {
const request = this.createEventRequest();
request.read({
success: this.onRequestEventDataSuccess,
failure: this.onRequestEventDataFailure,
aborted: this.onRequestEventDataAborted,
scope: this,
});
},
onRequestEventDataFailure: function onRequestEventDataFailure(response, o) {
alert(string.substitute(this.requestErrorText, [response, o])); // eslint-disable-line
ErrorManager.addError(response, o, this.options, 'failure');
},
onRequestEventDataAborted: function onRequestEventDataAborted() {
this.options = false; // force a refresh
},
onRequestEventDataSuccess: function onRequestEventDataSuccess(feed) {
this.processEventFeed(feed);
},
createEventRequest: function createEventRequest() {
const eventSelect = this.eventQuerySelect;
const eventWhere = this.getEventQuery();
const request = new Sage.SData.Client.SDataResourceCollectionRequest(this.getService())
.setCount(this.eventPageSize)
.setStartIndex(1)
.setResourceKind('events')
.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Select, this.expandExpression(eventSelect).join(','))
.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Where, eventWhere);
return request;
},
getEventQuery: function getEventQuery() {
return string.substitute(
[
'UserId eq "${0}" and (',
'(StartDate gt @${1}@ or EndDate gt @${1}@) and ',
'StartDate lt @${2}@',
')',
].join(''), [
App.context.user && App.context.user.$key,
convert.toIsoStringFromDate(this.currentDate.clone().startOf('day').toDate()),
convert.toIsoStringFromDate(this.currentDate.clone().endOf('day').toDate()),
]
);
},
activateEventMore: function activateEventMore() {
const view = App.getView('event_related');
if (view) {
const where = this.getEventQuery();
view.show({
where,
});
}
},
hideEventList: function hideEventList() {
$(this.eventContainerNode).addClass('event-hidden');
},
showEventList: function showEventList() {
$(this.eventContainerNode).removeClass('event-hidden');
},
processEventFeed: function processEventFeed(feed) {
const r = feed.$resources;
const feedLength = r.length;
const o = [];
this.eventFeed = feed;
if (feedLength === 0) {
this.hideEventList();
return false;
}
this.showEventList();
for (let i = 0; i < feedLength; i++) {
const row = r[i];
row.isEvent = true;
this.entries[row.$key] = row;
o.push(this.eventRowTemplate.apply(row, this));
}
if (feed.$totalResults > feedLength) {
$(this.eventContainerNode).addClass('list-has-more');
this.set('eventRemainingContent', this.eventMoreText);
} else {
$(this.eventContainerNode).removeClass('list-has-more');
this.set('eventRemainingContent', '');
}
this.set('eventListContent', o.join(''));
},
processFeed: function processFeed(feed) {
const r = feed.$resources;
const feedLength = r.length;
const o = [];
this.feed = feed;
for (let i = 0; i < feedLength; i++) {
const row = r[i];
row.isEvent = false;
this.entries[row.$key] = row;
o.push(this.rowTemplate.apply(row, this));
}
// If we fetched a page that has no data due to un-reliable counts,
// check if we fetched anything in the previous pages before assuming there is no data.
if (feedLength === 0 && Object.keys(this.entries).length === 0) {
this.set('listContent', this.noDataTemplate.apply(this));
return false;
}
if (o.length > 0) {
this.set('listContent', '');
$(this.contentNode).append(o.join(''));
}
this.set('remainingContent', ''); // Feed does not return reliable data, don't show remaining
$(this.domNode).toggleClass('list-has-more', this.hasMoreData()); // This could be wrong, handle it on the next processFeed if so
if (this.options.allowEmptySelection) {
$(this.domNode).addClass('list-has-empty-opt');
}
this._loadPreviousSelections();
},
show: function show(options) {
if (options) {
this.processShowOptions(options);
}
const theOptions = options || {};
theOptions.where = this.formatQueryForActivities();
this.set('dateContent', this.currentDate.format(this.dateHeaderFormatText));
this.inherited(arguments, [theOptions]);
},
processShowOptions: function processShowOptions(options) {
if (options.currentDate) {
this.currentDate = moment(options.currentDate).startOf('day') || moment().startOf('day');
this.refreshRequired = true;
}
},
isLoading: function isLoading() {
return $(this.domNode).hasClass('list-loading');
},
getNextDay: function getNextDay() {
if (this.isLoading()) {
return;
}
this.currentDate.add({
days: 1,
});
this.refresh();
},
getToday: function getToday() {
if (this.isLoading()) {
return;
}
if (this.currentDate === moment().startOf('day')) {
return;
}
this.currentDate = moment().startOf('day');
this.refresh();
},
getPrevDay: function getPrevDay() {
if (this.isLoading()) {
return;
}
this.currentDate.subtract({
days: 1,
});
this.refresh();
},
formatQueryForActivities: function formatQueryForActivities() {
const queryWhere = [
'UserActivities.UserId eq "${0}" and Type ne "atLiterature" and (',
'(Timeless eq false and StartDate between @${1}@ and @${2}@) or ',
'(Timeless eq true and StartDate between @${3}@ and @${4}@))',
].join('');
const startDate = this.currentDate.clone().startOf('day').toDate();
const endDate = this.currentDate.clone().endOf('day').toDate();
return string.substitute(
queryWhere, [App.context.user && App.context.user.$key,
convert.toIsoStringFromDate(startDate),
convert.toIsoStringFromDate(endDate),
this.currentDate.format('YYYY-MM-DDT00:00:00[Z]'),
this.currentDate.format('YYYY-MM-DDT23:59:59[Z]'),
]
);
},
selectEntry: function selectEntry(params) {
const row = $(params.$source).closest('[data-key]')[0];
const key = row ? row.getAttribute('data-key') : false;
this.navigateToDetailView(key);
},
selectDate: function selectDate() {
const options = {
date: this.currentDate,
showTimePicker: false,
timeless: false,
tools: {
tbar: [{
id: 'complete',
cls: 'fa fa-check fa-fw fa-lg',
fn: this.selectDateSuccess,
scope: this,
}, {
id: 'cancel',
side: 'left',
cls: 'fa fa-ban fa-fw fa-lg',
fn: ReUI.back,
scope: ReUI,
}],
},
};
const view = App.getView(this.datePickerView);
if (view) {
view.show(options);
}
},
selectDateSuccess: function selectDateSuccess() {
const view = App.getPrimaryActiveView();
this.currentDate = moment(view.getDateTime()).startOf('day');
this.refresh();
ReUI.back();
},
navigateToWeekView: function navigateToWeekView() {
const view = App.getView(this.weekView);
const navDate = this.currentDate ? this.currentDate : moment().startOf('day');
const options = {
currentDate: navDate.valueOf(),
};
view.show(options);
},
navigateToMonthView: function navigateToMonthView() {
const view = App.getView(this.monthView);
const navDate = this.currentDate ? this.currentDate : moment().startOf('day');
const options = {
currentDate: navDate.valueOf(),
};
view.show(options);
},
navigateToInsertView: function navigateToInsertView() {
const view = App.getView(this.insertView || this.editView);
this.options.currentDate = this.currentDate.format('YYYY-MM-DD') || moment().startOf('day');
if (view) {
view.show({
negateHistory: true,
returnTo: this.id,
insert: true,
currentDate: this.options.currentDate.valueOf(),
});
}
},
navigateToDetailView: function navigateToDetailView(key, descriptor) {
const entry = this.entries[key];
const detailView = (entry.isEvent) ? this.eventDetailView : this.activityDetailView;
const view = App.getView(detailView);
const theDescriptor = (entry.isEvent) ? descriptor : entry.Description;
if (view) {
view.show({
title: theDescriptor,
key,
});
}
},
});
lang.setObject('Mobile.SalesLogix.Views.Calendar.DayView', __class);
export default __class;