sogo/UI/WebServerResources/js/Scheduler.services.js.map
Francis Lachapelle 369060a52f (js/css) Update generated files
With Angular Material 0.11.3
2015-10-13 16:05:39 -04:00

1 line
70 KiB
Plaintext

{"version":3,"file":"Scheduler.services.js","sources":["Scheduler/Calendar.service.js","Scheduler/Component.service.js"],"names":["Calendar","futureCalendarData","this","init","name","id","newCalendarData","$$resource","create","angular","extend","$acl","$$Acl","$factory","$q","$timeout","$log","Settings","Resource","Component","Acl","activeUser","$Component","module","e","factory","$add","calendar","list","sibling","i","isWebCalendar","$webcalendars","isSubscription","$subscriptions","$calendars","_","find","o","localeCompare","indexOf","pluck","splice","$findAll","data","_this","forEach","push","union","$get","$getIndex","$subscribe","uid","path","userResource","fetch","then","calendarData","$addWebCalendar","url","d","defer","urls","webCalendarURL","reject","post","isEditable","isRemote","owner","login","debug","JSON","stringify","undefined","resolve","promise","$deleteComponents","components","calendars","component","isDefined","c_folder","c_name","uids","$events","difference","$tasks","prototype","isOwned","isSuperUser","isUndefined","$shadowData","$omit","getClassName","base","$rename","when","$save","$delete","remove","$reset","value","key","save","error","$setActivation","active","$getComponent","componentId","recurrenceId","$find","futureComponentData","pid","newComponentData","newguid","$unwrap","isNew","Preferences","Gravatar","$Preferences","$gravatar","baseURL","timeFormat","$query","search","$queryEvents","sort","asc","filterpopup","$queryTasks","$refreshTimeout","ready","settings","EventsFilterState","TasksFilterState","EventsSortingState","parseInt","TasksSortingState","show_completed","ShowCompletedTasks","$categories","defaults","SOGoCalendarCategoriesColors","SOGoTimeFormat","$selectedCount","count","filter","event","selected","length","task","$startRefreshTimeout","type","cancel","refreshViewCheck","SOGoRefreshViewCheck","f","bind","$filter","timeInterval","options","now","Date","day","getDate","month","getMonth","year","getFullYear","queryKey","capitalize","params","otherType","dirty","each","keys","$unwrapCollection","calendarId","occurrenceId","join","filterCategories","query","re","RegExp","category","saveSelectedList","componentType","$eventsBlocksForView","view","date","viewAction","startDate","endDate","beginOfWeek","setTime","getTime","addDays","setDate","setMonth","endOfWeek","$eventsBlocks","dates","deferred","toLowerCase","sd","getDayString","ed","views","reduceComponent","associateComponent","objects","eventData","componentData","object","eventsFields","start","c_startdate","hour","getHourString","block","nbr","$views","viewData","blocks","allDayBlocks","reduce","events","flatten","calendarName","fields","invoke","categories","repeat","alarm","action","quantity","unit","reference","relation","status","classification","delta","substring","setMinutes","Math","round","getMinutes","end","addMinutes","dueDate","due","$isRecurrent","days","byDayMask","occurrence","frequency","byday","toString","interval","monthdays","months","until","asDate","$hasCustomRepeat","hasCustomRepeat","units","M","H","D","W","match","exec","SOGoCalendarDefaultReminder","$hasAlarm","destinationCalendar","organizer","email","$image","freebusy","updateFreeBusyCoverage","attendees","attendee","image","updateFreeBusy","b","isReadOnly","isEditableOccurrence","isInvitation","userHasRSVP","isInvitationOccurrence","enablePercentComplete","coversFreeBusy","quarter","roundedStart","roundedEnd","startQuarter","endQuarter","daysUpTo","index","hourKey","currentDay","dayKey","getHours","beginOfDay","sday","eday","map","addAttendee","card","c_cn","$preferredEmail","role","c_uid","hasAttendee","emails","deleteAttendee","findIndex","currentAttendee","canRemindAttendeesByEmail","addAttachUrl","attachUrl","attachUrls","deleteAttachUrl","$addDueDate","toISOString","$deleteDueDate","$addStartDate","$deleteStartDate","$reply","reply","delegatedTo","occurrenceOnly","$futureComponentData","isError","formatTime","hours","minutes","formatDate","getYear","copy","startTime","endTime","dueTime","stringWithSeparator"],"mappings":"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","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Calendar\n * @constructor\n * @param {object} futureCalendarData - either an object literal or a promise\n */\n function Calendar(futureCalendarData) {\n // Data is immediately available\n this.init(futureCalendarData);\n if (this.name && !this.id) {\n // Create a new calendar on the server\n var newCalendarData = Calendar.$$resource.create('createFolder', this.name);\n angular.extend(this, newCalendarData);\n }\n if (this.id) {\n this.$acl = new Calendar.$$Acl('Calendar/' + this.id);\n }\n }\n\n /**\n * @memberof Calendar\n * @desc The factory we'll use to register with Angular\n * @returns the Calendar constructor\n */\n Calendar.$factory = ['$q', '$timeout', '$log', 'sgSettings', 'Resource', 'Component', 'Acl', function($q, $timeout, $log, Settings, Resource, Component, Acl) {\n angular.extend(Calendar, {\n $q: $q,\n $timeout: $timeout,\n $log: $log,\n $$resource: new Resource(Settings.activeUser('folderURL') + 'Calendar', Settings.activeUser()),\n $Component: Component,\n $$Acl: Acl,\n activeUser: Settings.activeUser()\n });\n\n return Calendar; // return constructor\n }];\n\n /**\n * @module SOGo.SchedulerUI\n * @desc Factory registration of Calendar in Angular module.\n */\n try {\n angular.module('SOGo.SchedulerUI');\n }\n catch(e) {\n angular.module('SOGo.SchedulerUI', ['SOGo.Common']);\n }\n angular.module('SOGo.SchedulerUI')\n .factory('Calendar', Calendar.$factory);\n\n /**\n * @memberof Calendar\n * @desc Add a new calendar to the static list of calendars\n * @param {Calendar} calendar - an Calendar object instance\n */\n Calendar.$add = function(calendar) {\n // Insert new calendar at proper index\n var list, sibling, i;\n\n if (calendar.isWebCalendar)\n list = this.$webcalendars;\n else if (calendar.isSubscription)\n list = this.$subscriptions;\n else\n list = this.$calendars;\n\n sibling = _.find(list, function(o) {\n return (o.id != 'personal' &&\n o.name.localeCompare(calendar.name) === 1);\n });\n i = sibling ? _.indexOf(_.pluck(list, 'id'), sibling.id) : 1;\n list.splice(i, 0, calendar);\n };\n\n /**\n * @memberof Calendar\n * @desc Set or get the list of calendars. Will instanciate a new Calendar object for each item.\n * @param {object[]} [data] - the metadata of the calendars\n * @returns the list of calendars\n */\n Calendar.$findAll = function(data) {\n var _this = this;\n if (data) {\n this.$calendars = [];\n this.$subscriptions = [];\n this.$webcalendars = [];\n // Instanciate Calendar objects\n angular.forEach(data, function(o, i) {\n var calendar = new Calendar(o);\n if (calendar.isWebCalendar)\n _this.$webcalendars.push(calendar);\n else if (calendar.isSubscription)\n _this.$subscriptions.push(calendar);\n else\n _this.$calendars.push(calendar);\n });\n }\n return _.union(this.$calendars, this.$subscriptions, this.$webcalendars);\n };\n\n /**\n * @memberof Calendar\n * @desc Find a calendar among local instances (personal calendars, subscriptions and Web calendars).\n * @param {string} id - the calendar ID\n * @returns an object literal of the matching Calendar instance\n */\n Calendar.$get = function(id) {\n var calendar;\n\n calendar = _.find(Calendar.$calendars, function(o) { return o.id == id; });\n if (!calendar)\n calendar = _.find(Calendar.$subscriptions, function(o) { return o.id == id; });\n if (!calendar)\n calendar = _.find(Calendar.$webcalendars, function(o) { return o.id == id; });\n\n return calendar;\n };\n\n /**\n * @memberof Calendar\n * @desc Find a calendar among local instances (personal calendars, subscriptions and Web calendars).\n * @param {string} id - the calendar ID\n * @returns an object literal of the matching Calendar instance\n */\n Calendar.$getIndex = function(id) {\n var i;\n\n i = _.indexOf(_.pluck(Calendar.$calendars, 'id'), id);\n if (i < 0)\n i = _.indexOf(_.pluck(Calendar.$subscriptions, 'id'), id);\n if (i < 0)\n i = _.indexOf(_.pluck(Calendar.$webcalendars, 'id'), id);\n\n return i;\n };\n\n /**\n * @memberOf Calendar\n * @desc Subscribe to another user's calendar and add it to the list of calendars.\n * @param {string} uid - user id\n * @param {string} path - path of folder for specified user\n * @returns a promise of the HTTP query result\n */\n Calendar.$subscribe = function(uid, path) {\n var _this = this;\n return Calendar.$$resource.userResource(uid).fetch(path, 'subscribe').then(function(calendarData) {\n var calendar = new Calendar(calendarData);\n if (!_.find(_this.$subscriptions, function(o) {\n return o.id == calendarData.id;\n })) {\n Calendar.$add(calendar);\n }\n return calendar;\n });\n };\n\n /**\n * @memberOf Calendar\n * @desc Subscribe to a remote Web calendar\n * @param {string} url - URL of .ics file\n * @returns a promise of the HTTP query result\n */\n Calendar.$addWebCalendar = function(url) {\n var _this = this,\n d = Calendar.$q.defer();\n\n if (_.find(_this.$webcalendars, function(o) {\n return o.urls.webCalendarURL == url;\n })) {\n // Already subscribed\n d.reject();\n }\n else {\n Calendar.$$resource.post(null, 'addWebCalendar', { url: url }).then(function(calendarData) {\n angular.extend(calendarData, {\n isWebCalendar: true,\n isEditable: true,\n isRemote: false,\n owner: Calendar.activeUser.login,\n urls: { webCalendarURL: url }\n });\n var calendar = new Calendar(calendarData);\n Calendar.$add(calendar);\n Calendar.$$resource.fetch(calendar.id, 'reload').then(function(data) {\n // TODO: show a toast of the reload status\n Calendar.$log.debug(JSON.stringify(data, undefined, 2));\n });\n d.resolve();\n }, function() {\n d.reject();\n });\n }\n\n return d.promise;\n };\n\n /**\n * @function $deleteComponents\n * @memberof Calendar\n * @desc Delete multiple components from calendar.\n * @return a promise of the HTTP operation\n */\n Calendar.$deleteComponents = function(components) {\n\n // We create a c_folder -> event hash\n var calendars = {}, _this = this;\n\n _.forEach(components, function(component) {\n if (!angular.isDefined(calendars[component.c_folder]))\n calendars[component.c_folder] = [];\n\n calendars[component.c_folder].push(component.c_name);\n });\n\n _.forEach(calendars, function(uids, c_folder) {\n Calendar.$$resource.post(c_folder, 'batchDelete', {uids: uids});\n });\n\n // We slice both arrays - might be useful if in the future, we can delete\n // events and tasks at the same time.\n _this.$Component.$events = _.difference(_this.$Component.$events, components);\n _this.$Component.$tasks = _.difference(_this.$Component.$tasks, components);\n };\n\n /**\n * @function init\n * @memberof Calendar.prototype\n * @desc Extend instance with new data and compute additional attributes.\n * @param {object} data - attributes of calendar\n */\n Calendar.prototype.init = function(data) {\n angular.extend(this, data);\n // Add 'isOwned' and 'isSubscription' attributes based on active user (TODO: add it server-side?)\n this.isOwned = Calendar.activeUser.isSuperUser || this.owner == Calendar.activeUser.login;\n this.isSubscription = !this.isRemote && this.owner != Calendar.activeUser.login;\n if (angular.isUndefined(this.$shadowData)) {\n // Make a copy of the data for an eventual reset\n this.$shadowData = this.$omit();\n }\n };\n\n /**\n * @function getClassName\n * @memberof Calendar.prototype\n * @desc Return the calendar CSS class name based on its ID.\n * @returns a string representing the foreground CSS class name\n */\n Calendar.prototype.getClassName = function(base) {\n if (angular.isUndefined(base))\n base = 'fg';\n return base + '-folder' + this.id;\n };\n\n /**\n * @function $rename\n * @memberof Calendar.prototype\n * @desc Rename the calendar and keep the list sorted\n * @param {string} name - the new name\n * @returns a promise of the HTTP operation\n */\n Calendar.prototype.$rename = function() {\n var _this = this,\n i,\n calendars;\n\n if (this.name == this.$shadowData.name) {\n // Name hasn't changed\n return Calendar.$q.when();\n }\n\n if (this.isWebCalendar)\n calendars = Calendar.$webcalendars;\n else if (this.isSubscription)\n calendars = Calendar.$subscriptions;\n else\n calendars = Calendar.$calendars;\n\n i = _.indexOf(_.pluck(calendars, 'id'), this.id);\n if (i > -1) {\n return this.$save().then(function() {\n calendars.splice(i, 1);\n Calendar.$add(_this);\n });\n }\n else {\n return Calendar.$q.reject();\n }\n };\n\n /**\n * @function $delete\n * @memberof Calendar.prototype\n * @desc Delete the calendar from the server and the static list of calendars.\n * @returns a promise of the HTTP operation\n */\n Calendar.prototype.$delete = function() {\n var _this = this,\n list,\n promise;\n\n if (this.isSubscription) {\n promise = Calendar.$$resource.fetch(this.id, 'unsubscribe');\n list = Calendar.$subscriptions;\n }\n else {\n promise = Calendar.$$resource.remove(this.id);\n if (this.isWebCalendar)\n list = Calendar.$webcalendars;\n else\n list = Calendar.$calendars;\n }\n\n return promise.then(function() {\n var i = _.indexOf(_.pluck(list, 'id'), _this.id);\n list.splice(i, 1);\n });\n };\n\n /**\n * @function $reset\n * @memberof Mailbox.prototype\n * @desc Reset the original state the mailbox's data.\n */\n Calendar.prototype.$reset = function() {\n var _this = this;\n angular.forEach(this, function(value, key) {\n if (key != 'constructor' && key[0] != '$') {\n delete _this[key];\n }\n });\n angular.extend(this, this.$shadowData);\n this.$shadowData = this.$omit();\n };\n\n /**\n * @function $save\n * @memberof Calendar.prototype\n * @desc Save the calendar properties to the server.\n * @returns a promise of the HTTP operation\n */\n Calendar.prototype.$save = function() {\n var _this = this;\n\n return Calendar.$$resource.save(this.id, this.$omit()).then(function(data) {\n // Make a copy of the data for an eventual reset\n _this.$shadowData = _this.$omit();\n return data;\n }, function(data) {\n Calendar.$log.error(JSON.stringify(data, undefined, 2));\n // Restore previous version\n _this.$reset();\n return data;\n });\n };\n\n /**\n * @function $setActivation\n * @memberof Calendar.prototype\n * @desc Either activate or deactivate the calendar.\n * @returns a promise of the HTTP operation\n */\n Calendar.prototype.$setActivation = function() {\n return Calendar.$$resource.fetch(this.id, (this.active?'':'de') + 'activateFolder');\n };\n\n /**\n * @function $getComponent\n * @memberof Calendar.prototype\n * @desc Fetch a component attributes from the server.\n * @returns a promise of the HTTP operation\n */\n Calendar.prototype.$getComponent = function(componentId, recurrenceId) {\n return Calendar.$Component.$find(this.id, componentId, recurrenceId);\n };\n\n /**\n * @function $omit\n * @memberof Calendar.prototype\n * @desc Return a sanitized object used to send to the server.\n * @return an object literal copy of the Calendar instance\n */\n Calendar.prototype.$omit = function() {\n var calendar = {};\n angular.forEach(this, function(value, key) {\n if (key != 'constructor' &&\n key[0] != '$') {\n calendar[key] = value;\n }\n });\n return calendar;\n };\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Component\n * @constructor\n * @param {object} futureComponentData - either an object literal or a promise\n */\n function Component(futureComponentData) {\n // Data is immediately available\n if (typeof futureComponentData.then !== 'function') {\n this.init(futureComponentData);\n if (this.pid && !this.id) {\n // Prepare for the creation of a new component;\n // Get UID from the server.\n var newComponentData = Component.$$resource.newguid(this.pid);\n this.$unwrap(newComponentData);\n this.isNew = true;\n }\n }\n else {\n // The promise will be unwrapped first\n this.$unwrap(futureComponentData);\n }\n }\n\n /**\n * @memberof Component\n * @desc The factory we'll use to register with Angular\n * @returns the Component constructor\n */\n Component.$factory = ['$q', '$timeout', '$log', 'sgSettings', 'Preferences', 'Gravatar', 'Resource', function($q, $timeout, $log, Settings, Preferences, Gravatar, Resource) {\n angular.extend(Component, {\n $q: $q,\n $timeout: $timeout,\n $log: $log,\n $Preferences: Preferences,\n $gravatar: Gravatar,\n $$resource: new Resource(Settings.baseURL(), Settings.activeUser()),\n timeFormat: \"%H:%M\",\n // Filter parameters common to events and tasks\n $query: { value: '', search: 'title_Category_Location' },\n // Filter paramaters specific to events\n $queryEvents: { sort: 'start', asc: 1, filterpopup: 'view_next7' },\n // Filter parameters specific to tasks\n $queryTasks: { sort: 'status', asc: 1, filterpopup: 'view_incomplete' },\n $refreshTimeout: null\n });\n Preferences.ready().then(function() {\n // Initialize filter parameters from user's settings\n if (Preferences.settings.Calendar.EventsFilterState)\n Component.$queryEvents.filterpopup = Preferences.settings.Calendar.EventsFilterState;\n if (Preferences.settings.Calendar.TasksFilterState)\n Component.$queryTasks.filterpopup = Preferences.settings.Calendar.TasksFilterState;\n if (Preferences.settings.Calendar.EventsSortingState) {\n Component.$queryEvents.sort = Preferences.settings.Calendar.EventsSortingState[0];\n Component.$queryEvents.asc = parseInt(Preferences.settings.Calendar.EventsSortingState[1]);\n }\n if (Preferences.settings.Calendar.TasksSortingState) {\n Component.$queryTasks.sort = Preferences.settings.Calendar.TasksSortingState[0];\n Component.$queryTasks.asc = parseInt(Preferences.settings.Calendar.TasksSortingState[1]);\n }\n Component.$queryTasks.show_completed = parseInt(Preferences.settings.ShowCompletedTasks);\n // Initialize categories from user's defaults\n Component.$categories = Preferences.defaults.SOGoCalendarCategoriesColors;\n // Initialize time format from user's defaults\n if (Preferences.defaults.SOGoTimeFormat) {\n Component.timeFormat = Preferences.defaults.SOGoTimeFormat;\n }\n });\n\n return Component; // return constructor\n }];\n\n /**\n * @module SOGo.SchedulerUI\n * @desc Factory registration of Component in Angular module.\n */\n try {\n angular.module('SOGo.SchedulerUI');\n }\n catch(e) {\n angular.module('SOGo.SchedulerUI', ['SOGo.Common']);\n }\n angular.module('SOGo.SchedulerUI')\n .factory('Component', Component.$factory);\n\n /**\n * @function $selectedCount\n * @memberof Component\n * @desc Return the number of events or tasks selected by the user.\n * @returns the number of selected events or tasks\n */\n Component.$selectedCount = function() {\n var count;\n\n count = 0;\n if (Component.$events) {\n count = (_.filter(Component.$events, function(event) { return event.selected; })).length;\n }\n if (Component.$tasks) {\n count = (_.filter(Component.$tasks, function(task) { return task.selected; })).length;\n }\n return count;\n };\n\n /**\n * @function $startRefreshTimeout\n * @memberof Component\n * @desc Starts the refresh timeout for the current selected component type, for all calendars\n */\n Component.$startRefreshTimeout = function(type) {\n var _this = this;\n\n if (Component.$refreshTimeout)\n Component.$timeout.cancel(Component.$refreshTimeout);\n\n Component.$Preferences.ready().then(function() {\n // Restart the refresh timer, if needed\n var refreshViewCheck = Component.$Preferences.defaults.SOGoRefreshViewCheck;\n if (refreshViewCheck && refreshViewCheck != 'manually') {\n var f = angular.bind(_this, Component.$filter, type);\n Component.$refreshTimeout = Component.$timeout(f, refreshViewCheck.timeInterval()*1000);\n }\n });\n };\n\n /**\n * @function $filter\n * @memberof Component\n * @desc Search for components matching some criterias\n * @param {string} type - either 'events' or 'tasks'\n * @param {object} [options] - additional options to the query\n * @returns a collection of Components instances\n */\n Component.$filter = function(type, options) {\n var _this = this,\n now = new Date(),\n day = now.getDate(),\n month = now.getMonth() + 1,\n year = now.getFullYear(),\n queryKey = '$query' + type.capitalize(),\n params = {\n day: '' + year + (month < 10?'0':'') + month + (day < 10?'0':'') + day,\n };\n\n Component.$startRefreshTimeout(type);\n\n return this.$Preferences.ready().then(function() {\n var futureComponentData,\n dirty = false,\n otherType;\n\n angular.extend(_this.$query, params);\n\n if (options) {\n _.each(_.keys(options), function(key) {\n // Query parameters common to events and tasks are compared\n dirty |= (_this.$query[key] && options[key] != Component.$query[key]);\n if (key == 'reload' && options[key])\n dirty = true;\n // Update either the common parameters or the type-specific parameters\n else if (angular.isDefined(_this.$query[key]))\n _this.$query[key] = options[key];\n else\n _this[queryKey][key] = options[key];\n });\n }\n\n // Perform query with both common and type-specific parameters\n futureComponentData = _this.$$resource.fetch(null, type + 'list',\n angular.extend(_this[queryKey], _this.$query));\n\n // Invalidate cached results of other type if $query has changed\n otherType = (type == 'tasks')? '$events' : '$tasks';\n if (dirty) {\n delete Component[otherType];\n Component.$log.debug('force reload of ' + otherType);\n }\n\n return _this.$unwrapCollection(type, futureComponentData);\n });\n };\n\n /**\n * @function $find\n * @desc Fetch a component from a specific calendar.\n * @param {string} calendarId - the calendar ID\n * @param {string} componentId - the component ID\n * @param {string} [occurrenceId] - the component ID\n * @see {@link Calendar.$getComponent}\n */\n Component.$find = function(calendarId, componentId, occurrenceId) {\n var futureComponentData, path = [calendarId, componentId];\n\n if (occurrenceId)\n path.push(occurrenceId);\n\n futureComponentData = this.$$resource.fetch(path.join('/'), 'view');\n\n return new Component(futureComponentData);\n };\n\n /**\n * @function filterCategories\n * @desc Search for categories matching some criterias\n * @param {string} search - the search string to match\n * @returns a collection of strings\n */\n Component.filterCategories = function(query) {\n var re = new RegExp(query, 'i');\n return _.filter(_.keys(Component.$categories), function(category) {\n return category.search(re) != -1;\n });\n };\n\n /**\n * @function saveSelectedList\n * @desc Save to the user's settings the currently selected list.\n * @param {string} componentType - either \"events\" or \"tasks\"\n * @returns a promise of the HTTP operation\n */\n Component.saveSelectedList = function(componentType) {\n return this.$$resource.post(null, 'saveSelectedList', { list: componentType + 'ListView' });\n };\n\n /**\n * @function $eventsBlocksForView\n * @desc Events blocks for a specific week\n * @param {string} view - Either 'day' or 'week'\n * @param {Date} type - Date of any day of the desired period\n * @returns a promise of a collection of objects describing the events blocks\n */\n Component.$eventsBlocksForView = function(view, date) {\n var viewAction, startDate, endDate, params;\n\n if (view == 'day') {\n viewAction = 'dayView';\n startDate = endDate = date;\n }\n else if (view == 'multicolumnday') {\n viewAction = 'multicolumndayView';\n startDate = endDate = date;\n }\n else if (view == 'week') {\n viewAction = 'weekView';\n startDate = date.beginOfWeek();\n endDate = new Date();\n endDate.setTime(startDate.getTime());\n endDate.addDays(6);\n }\n else if (view == 'month') {\n viewAction = 'monthView';\n startDate = date;\n startDate.setDate(1);\n startDate = startDate.beginOfWeek();\n endDate = new Date();\n endDate.setTime(startDate.getTime());\n endDate.setMonth(endDate.getMonth() + 1);\n endDate.addDays(-1);\n endDate = endDate.endOfWeek();\n }\n return this.$eventsBlocks(viewAction, startDate, endDate);\n };\n\n /**\n * @function $eventsBlocks\n * @desc Events blocks for a specific view and period\n * @param {string} view - Either 'day', 'multicolumnday', 'week' or 'month'\n * @param {Date} startDate - period's start date\n * @param {Date} endDate - period's end date\n * @returns a promise of a collection of objects describing the events blocks\n */\n Component.$eventsBlocks = function(view, startDate, endDate) {\n var params, futureComponentData, i, dates = [],\n deferred = Component.$q.defer();\n\n params = { view: view.toLowerCase(), sd: startDate.getDayString(), ed: endDate.getDayString() };\n Component.$log.debug('eventsblocks ' + JSON.stringify(params, undefined, 2));\n futureComponentData = this.$$resource.fetch(null, 'eventsblocks', params);\n futureComponentData.then(function(views) {\n var reduceComponent, associateComponent;\n\n reduceComponent = function(objects, eventData, i) {\n var componentData = _.object(this.eventsFields, eventData),\n start = new Date(componentData.c_startdate * 1000);\n componentData.hour = start.getHourString();\n objects.push(new Component(componentData));\n return objects;\n };\n\n associateComponent = function(block) {\n block.component = this[block.nbr];\n };\n\n Component.$views = [];\n Component.$timeout(function() {\n _.forEach(views, function(data) {\n var components = [], blocks = {}, allDayBlocks = {}, viewData;\n\n // Instantiate Component objects\n _.reduce(data.events, reduceComponent, components, data);\n\n // Associate Component objects to blocks positions\n _.forEach(_.flatten(data.blocks), associateComponent, components);\n\n // Associate Component objects to all-day blocks positions\n _.each(_.flatten(data.allDayBlocks), associateComponent, components);\n\n // Build array of dates\n if (dates.length === 0)\n for (i = 0; i < data.blocks.length; i++) {\n dates.push(startDate.getDayString());\n startDate.addDays(1);\n }\n\n // Convert array of blocks to object with days as keys\n for (i = 0; i < data.blocks.length; i++) {\n blocks[dates[i]] = data.blocks[i];\n }\n\n // Convert array of all-day blocks to object with days as keys\n for (i = 0; i < data.allDayBlocks.length; i++) {\n allDayBlocks[dates[i]] = data.allDayBlocks[i];\n }\n\n Component.$log.debug('blocks ready (' + _.flatten(data.blocks).length + ')');\n Component.$log.debug('all day blocks ready (' + _.flatten(data.allDayBlocks).length + ')');\n\n // Save the blocks to the object model\n viewData = { blocks: blocks, allDayBlocks: allDayBlocks };\n if (data.id && data.calendarName) {\n // The multicolumnday view also includes calendar information\n viewData.id = data.id;\n viewData.calendarName = data.calendarName;\n }\n Component.$views.push(viewData);\n });\n\n deferred.resolve(Component.$views);\n });\n }, deferred.reject);\n\n return deferred.promise;\n };\n\n /**\n * @function $unwrapCollection\n * @desc Unwrap a promise and instanciate new Component objects using received data.\n * @param {string} type - either 'events' or 'tasks'\n * @param {promise} futureComponentData - a promise of the components' metadata\n * @returns a promise of the HTTP operation\n */\n Component.$unwrapCollection = function(type, futureComponentData) {\n var _this = this,\n components = [];\n\n return futureComponentData.then(function(data) {\n return Component.$timeout(function() {\n var fields = _.invoke(data.fields, 'toLowerCase');\n\n // Instanciate Component objects\n _.reduce(data[type], function(components, componentData, i) {\n var data = _.object(fields, componentData);\n components.push(new Component(data));\n return components;\n }, components);\n\n Component.$log.debug('list of ' + type + ' ready (' + components.length + ')');\n\n // Save the list of components to the object model\n Component['$' + type] = components;\n\n return components;\n });\n });\n };\n\n /**\n * @function init\n * @memberof Component.prototype\n * @desc Extend instance with required attributes and new data.\n * @param {object} data - attributes of component\n */\n Component.prototype.init = function(data) {\n var _this = this;\n\n this.categories = [];\n this.repeat = {};\n this.alarm = { action: 'display', quantity: 5, unit: 'MINUTES', reference: 'BEFORE', relation: 'START' };\n this.status = 'not-specified';\n angular.extend(this, data);\n\n Component.$Preferences.ready().then(function() {\n var type = (_this.type == 'appointment')? 'Events' : 'Tasks';\n\n // Set default values from user's defaults\n _this.classification = _this.classification ||\n Component.$Preferences.defaults['SOGoCalendar' + type + 'DefaultClassification'].toLowerCase();\n });\n\n this.delta = 60;\n\n if (this.startDate)\n this.start = new Date(this.startDate.substring(0,10) + ' ' + this.startDate.substring(11,16));\n else if (this.type == 'appointment') {\n this.start = new Date();\n this.start.setMinutes(Math.round(this.start.getMinutes()/15)*15);\n }\n\n if (this.endDate)\n this.end = new Date(this.endDate.substring(0,10) + ' ' + this.endDate.substring(11,16));\n else if (this.type == 'appointment') {\n this.end = new Date();\n this.end.setMinutes(Math.round(this.end.getMinutes()/15)*15);\n this.end.addMinutes(this.delta);\n }\n\n if (this.dueDate)\n this.due = new Date(this.dueDate.substring(0,10) + ' ' + this.dueDate.substring(11,16));\n\n // Parse recurrence rule definition and initialize default values\n this.$isRecurrent = angular.isDefined(data.repeat);\n if (this.repeat.days) {\n var byDayMask = _.find(this.repeat.days, function(o) {\n return angular.isDefined(o.occurrence);\n });\n if (byDayMask)\n if (this.repeat.frequency == 'yearly')\n this.repeat.year = { byday: true };\n this.repeat.month = {\n type: 'byday',\n occurrence: byDayMask.occurrence.toString(),\n day: byDayMask.day\n };\n }\n else {\n this.repeat.days = [];\n }\n if (angular.isUndefined(this.repeat.frequency))\n this.repeat.frequency = 'never';\n if (angular.isUndefined(this.repeat.interval))\n this.repeat.interval = 1;\n if (angular.isUndefined(this.repeat.month))\n this.repeat.month = { occurrence: '1', day: 'SU', type: 'bymonthday' };\n if (angular.isUndefined(this.repeat.monthdays))\n // TODO: initialize this.repeat.monthdays with month day of start date\n this.repeat.monthdays = [];\n if (angular.isUndefined(this.repeat.months))\n // TODO: initialize this.repeat.months with month of start date\n this.repeat.months = [];\n if (angular.isUndefined(this.repeat.year))\n this.repeat.year = {};\n if (this.repeat.count)\n this.repeat.end = 'count';\n else if (this.repeat.until) {\n this.repeat.end = 'until';\n this.repeat.until = this.repeat.until.substring(0,10).asDate();\n }\n else\n this.repeat.end = 'never';\n this.$hasCustomRepeat = this.hasCustomRepeat();\n\n if (this.isNew) {\n // Set default alarm\n Component.$Preferences.ready().then(function() {\n var units = { M: 'MINUTES', H: 'HOURS', D: 'DAYS', W: 'WEEKS' };\n var match = /-PT?([0-9]+)([MHDW])/.exec(Component.$Preferences.defaults.SOGoCalendarDefaultReminder);\n if (match) {\n _this.$hasAlarm = true;\n _this.alarm.quantity = parseInt(match[1]);\n _this.alarm.unit = units[match[2]];\n }\n });\n }\n else {\n this.$hasAlarm = angular.isDefined(data.alarm);\n }\n\n // Allow the component to be moved to a different calendar\n this.destinationCalendar = this.pid;\n\n if (this.organizer && this.organizer.email) {\n this.organizer.$image = Component.$gravatar(this.organizer.email, 32);\n }\n\n // Load freebusy of attendees\n this.freebusy = this.updateFreeBusyCoverage();\n\n if (this.attendees) {\n _.each(this.attendees, function(attendee) {\n attendee.image = Component.$gravatar(attendee.email, 32);\n _this.updateFreeBusy(attendee);\n });\n }\n\n this.selected = false;\n };\n\n /**\n * @function hasCustomRepeat\n * @memberof Component.prototype\n * @desc Check if the component has a custom recurrence rule.\n * @returns true if the recurrence rule requires the full recurrence editor\n */\n Component.prototype.hasCustomRepeat = function() {\n var b = angular.isDefined(this.repeat) &&\n (this.repeat.interval > 1 ||\n this.repeat.days && this.repeat.days.length > 0 ||\n this.repeat.monthdays && this.repeat.monthdays.length > 0 ||\n this.repeat.months && this.repeat.months.length > 0);\n return b;\n };\n\n /**\n * @function isEditable\n * @memberof Component.prototype\n * @desc Check if the component is editable and not an occurrence of a recurrent component\n * @returns true or false\n */\n Component.prototype.isEditable = function() {\n return (!this.occurrenceId && !this.isReadOnly);\n };\n\n /**\n * @function isEditableOccurrence\n * @memberof Component.prototype\n * @desc Check if the component is editable and an occurrence of a recurrent component\n * @returns true or false\n */\n Component.prototype.isEditableOccurrence = function() {\n return (this.occurrenceId && !this.isReadOnly);\n };\n\n /**\n * @function isInvitation\n * @memberof Component.prototype\n * @desc Check if the component an invitation and not an occurrence of a recurrent component\n * @returns true or false\n */\n Component.prototype.isInvitation = function() {\n return (!this.occurrenceId && this.userHasRSVP);\n };\n\n /**\n * @function isInvitationOccurrence\n * @memberof Component.prototype\n * @desc Check if the component an invitation and an occurrence of a recurrent component\n * @returns true or false\n */\n Component.prototype.isInvitationOccurrence = function() {\n return (this.occurrenceId && this.userHasRSVP);\n };\n\n /**\n * @function isReadOnly\n * @memberof Component.prototype\n * @desc Check if the component is not editable and not an invitation\n * @returns true or false\n */\n Component.prototype.isReadOnly = function() {\n return (this.isReadOnly && !this.userHasRSVP);\n };\n\n /**\n * @function enablePercentComplete\n * @memberof Component.prototype\n * @desc Check if the percent completion should be enabled with respect to the\n * component's type and status.\n * @returns true if the percent completion should be displayed\n */\n Component.prototype.enablePercentComplete = function() {\n return (this.component = 'vtodo' &&\n this.status != 'not-specified' &&\n this.status != 'cancelled');\n };\n\n /**\n * @function coversFreeBusy\n * @memberof Component.prototype\n * @desc Check if a specific quarter matches the component's period\n * @returns true if the quarter covers the component's period\n */\n Component.prototype.coversFreeBusy = function(day, hour, quarter) {\n var b = (angular.isDefined(this.freebusy[day]) &&\n angular.isDefined(this.freebusy[day][hour]) &&\n this.freebusy[day][hour][quarter] == 1);\n return b;\n };\n\n /**\n * @function updateFreeBusyCoverage\n * @memberof Component.prototype\n * @desc Build a 15-minute-based representation of the component's period.\n * @returns an object literal hashed by days and hours and arrays of four 1's and 0's\n */\n Component.prototype.updateFreeBusyCoverage = function() {\n var _this = this, freebusy = {};\n\n if (this.start && this.end) {\n var roundedStart = new Date(this.start.getTime()),\n roundedEnd = new Date(this.end.getTime()),\n startQuarter = parseInt(roundedStart.getMinutes()/15 + 0.5),\n endQuarter = parseInt(roundedEnd.getMinutes()/15 + 0.5);\n roundedStart.setMinutes(15*startQuarter);\n roundedEnd.setMinutes(15*endQuarter);\n\n _.each(roundedStart.daysUpTo(roundedEnd), function(date, index) {\n var currentDay = date.getDate(),\n dayKey = date.getDayString(),\n hourKey;\n if (dayKey == _this.start.getDayString()) {\n hourKey = date.getHours().toString();\n freebusy[dayKey] = {};\n freebusy[dayKey][hourKey] = [];\n while (startQuarter > 0) {\n freebusy[dayKey][hourKey].push(0);\n startQuarter--;\n }\n }\n else {\n date = date.beginOfDay();\n freebusy[dayKey] = {};\n }\n while (date.getTime() < _this.end.getTime() &&\n date.getDate() == currentDay) {\n hourKey = date.getHours().toString();\n if (angular.isUndefined(freebusy[dayKey][hourKey]))\n freebusy[dayKey][hourKey] = [];\n freebusy[dayKey][hourKey].push(1);\n date.addMinutes(15);\n }\n });\n return freebusy;\n }\n };\n\n /**\n * @function updateFreeBusy\n * @memberof Component.prototype\n * @desc Update the freebusy information for the component's period for a specific attendee.\n * @param {Object} card - an Card object instance of the attendee\n */\n Component.prototype.updateFreeBusy = function(attendee) {\n var params, url, days;\n if (attendee.uid) {\n params =\n {\n sday: this.start.getDayString(),\n eday: this.end.getDayString()\n };\n url = ['..', '..', attendee.uid, 'freebusy.ifb'];\n days = _.map(this.start.daysUpTo(this.end), function(day) { return day.getDayString(); });\n\n if (angular.isUndefined(attendee.freebusy))\n attendee.freebusy = {};\n\n // Fetch FreeBusy information\n Component.$$resource.fetch(url.join('/'), 'ajaxRead', params).then(function(data) {\n _.each(days, function(day) {\n var hour;\n\n if (angular.isUndefined(attendee.freebusy[day]))\n attendee.freebusy[day] = {};\n\n if (angular.isUndefined(data[day]))\n data[day] = {};\n\n for (var i = 0; i <= 23; i++) {\n hour = i.toString();\n if (data[day][hour])\n attendee.freebusy[day][hour] = [\n data[day][hour][\"0\"],\n data[day][hour][\"15\"],\n data[day][hour][\"30\"],\n data[day][hour][\"45\"]\n ];\n else\n attendee.freebusy[day][hour] = [0, 0, 0, 0];\n }\n });\n });\n }\n };\n\n /**\n * @function getClassName\n * @memberof Component.prototype\n * @desc Return the component CSS class name based on its container (calendar) ID.\n * @param {string} [base] - the prefix to add to the class name (defaults to \"fg\")\n * @returns a string representing the foreground CSS class name\n */\n Component.prototype.getClassName = function(base) {\n if (angular.isUndefined(base))\n base = 'fg';\n return base + '-folder' + (this.destinationCalendar || this.c_folder);\n };\n\n /**\n * @function addAttendee\n * @memberof Component.prototype\n * @desc Add an attendee and fetch his freebusy info.\n * @param {Object} card - an Card object instance to be added to the attendees list\n */\n Component.prototype.addAttendee = function(card) {\n var attendee, url, params;\n if (card) {\n attendee = {\n name: card.c_cn,\n email: card.$preferredEmail(),\n role: 'req-participant',\n status: 'needs-action',\n uid: card.c_uid\n };\n if (!_.find(this.attendees, function(o) {\n return o.email == attendee.email;\n })) {\n attendee.image = Component.$gravatar(attendee.email, 32);\n if (this.attendees)\n this.attendees.push(attendee);\n else\n this.attendees = [attendee];\n this.updateFreeBusy(attendee);\n }\n }\n };\n\n /**\n * @function hasAttendee\n * @memberof Component.prototype\n * @desc Verify if one of the email addresses of a Card instance matches an attendee.\n * @param {Object} card - an Card object instance\n * @returns true if the Card matches an attendee\n */\n Component.prototype.hasAttendee = function(card) {\n var attendee = _.find(this.attendees, function(attendee) {\n return _.find(card.emails, function(email) {\n return email.value == attendee.email;\n });\n });\n return angular.isDefined(attendee);\n };\n\n /**\n * @function deleteAttendee\n * @memberof Component.prototype\n * @desc Remove an attendee from the component\n * @param {Object} attendee - an object literal defining an attendee\n */\n Component.prototype.deleteAttendee = function(attendee) {\n var index = _.findIndex(this.attendees, function(currentAttendee) {\n return currentAttendee.email == attendee.email;\n });\n this.attendees.splice(index, 1);\n };\n\n /**\n * @function canRemindAttendeesByEmail\n * @memberof Component.prototype\n * @desc Verify if the component's reminder must be send by email and if it has at least one attendee.\n * @returns true if attendees can receive a reminder by email\n */\n Component.prototype.canRemindAttendeesByEmail = function() {\n return this.alarm.action == 'email' &&\n !this.isReadOnly &&\n this.attendees && this.attendees.length > 0;\n };\n\n /**\n * @function addAttachUrl\n * @memberof Component.prototype\n * @desc Add a new attach URL if not already defined\n * @param {string} attachUrl - the URL\n * @returns the number of values in the list of attach URLs\n */\n Component.prototype.addAttachUrl = function(attachUrl) {\n if (angular.isUndefined(this.attachUrls)) {\n this.attachUrls = [{value: attachUrl}];\n }\n else {\n for (var i = 0; i < this.attachUrls.length; i++) {\n if (this.attachUrls[i].value == attachUrl) {\n break;\n }\n }\n if (i == this.attachUrls.length)\n this.attachUrls.push({value: attachUrl});\n }\n return this.attachUrls.length - 1;\n };\n\n /**\n * @function deleteAttachUrl\n * @memberof Component.prototype\n * @desc Remove an attach URL\n * @param {number} index - the URL index in the list of attach URLs\n */\n Component.prototype.deleteAttachUrl = function(index) {\n if (index > -1 && this.attachUrls.length > index) {\n this.attachUrls.splice(index, 1);\n }\n };\n\n /**\n * @function $addDueDate\n * @memberof Component.prototype\n * @desc Add a due date\n */\n Component.prototype.$addDueDate = function() {\n this.due = new Date();\n this.due.setMinutes(Math.round(this.due.getMinutes()/15)*15);\n this.dueDate = this.due.toISOString();\n };\n\n /**\n * @function $deleteDueDate\n * @memberof Component.prototype\n * @desc Delete a due date\n */\n Component.prototype.$deleteDueDate = function() {\n delete this.due;\n delete this.dueDate;\n };\n\n /**\n * @function $addStartDate\n * @memberof Component.prototype\n * @desc Add a start date\n */\n Component.prototype.$addStartDate = function() {\n this.start = new Date();\n this.start.setMinutes(Math.round(this.start.getMinutes()/15)*15);\n };\n\n /**\n * @function $deleteStartDate\n * @memberof Component.prototype\n * @desc Delete a start date\n */\n Component.prototype.$deleteStartDate = function() {\n delete this.start;\n delete this.startDate;\n };\n\n /**\n * @function $reset\n * @memberof Component.prototype\n * @desc Reset the original state the component's data.\n */\n Component.prototype.$reset = function() {\n var _this = this;\n angular.forEach(this, function(value, key) {\n if (key != 'constructor' && key[0] != '$') {\n delete _this[key];\n }\n });\n this.init(this.$shadowData);\n this.$shadowData = this.$omit(true);\n };\n\n /**\n * @function reply\n * @memberof Component.prototype\n * @desc Reply to an invitation.\n * @returns a promise of the HTTP operation\n */\n Component.prototype.$reply = function() {\n var _this = this, data, path = [this.pid, this.id];\n\n if (this.occurrenceId)\n path.push(this.occurrenceId);\n\n data = {\n reply: this.reply,\n delegatedTo: this.delegatedTo,\n alarm: this.$hasAlarm? this.alarm : {}\n };\n\n return Component.$$resource.save(path.join('/'), data, { action: 'rsvpAppointment' })\n .then(function(data) {\n // Make a copy of the data for an eventual reset\n _this.$shadowData = _this.$omit(true);\n return data;\n });\n };\n\n /**\n * @function $save\n * @memberof Component.prototype\n * @desc Save the component to the server.\n */\n Component.prototype.$save = function() {\n var _this = this, options, path = [this.pid, this.id];\n\n if (this.isNew)\n options = { action: 'saveAs' + this.type.capitalize() };\n\n if (this.occurrenceId)\n path.push(this.occurrenceId);\n\n return Component.$$resource.save(path.join('/'), this.$omit(), options)\n .then(function(data) {\n // Make a copy of the data for an eventual reset\n _this.$shadowData = _this.$omit(true);\n return data;\n });\n };\n\n /**\n * @function $delete\n * @memberof Component.prototype\n * @desc Delete the component from the server.\n * @param {boolean} occurrenceOnly - delete this occurrence only\n */\n Component.prototype.remove = function(occurrenceOnly) {\n var _this = this, path = [this.pid, this.id];\n\n if (occurrenceOnly && this.occurrenceId)\n path.push(this.occurrenceId);\n\n return Component.$$resource.remove(path.join('/'));\n };\n\n /**\n * @function $unwrap\n * @memberof Component.prototype\n * @desc Unwrap a promise.\n * @param {promise} futureComponentData - a promise of some of the Component's data\n */\n Component.prototype.$unwrap = function(futureComponentData) {\n var _this = this;\n\n // Expose the promise\n this.$futureComponentData = futureComponentData;\n\n // Resolve the promise\n this.$futureComponentData.then(function(data) {\n _this.init(data);\n // Make a copy of the data for an eventual reset\n _this.$shadowData = _this.$omit();\n }, function(data) {\n angular.extend(_this, data);\n _this.isError = true;\n Component.$log.error(_this.error);\n });\n };\n\n /**\n * @function $omit\n * @memberof Component.prototype\n * @desc Return a sanitized object used to send to the server.\n * @return an object literal copy of the Component instance\n */\n Component.prototype.$omit = function() {\n var component = {}, date;\n angular.forEach(this, function(value, key) {\n if (key != 'constructor' && key[0] != '$') {\n component[key] = angular.copy(value);\n }\n });\n\n // Format dates and times\n component.startDate = component.start ? formatDate(component.start) : '';\n component.startTime = component.start ? formatTime(component.start) : '';\n component.endDate = component.end ? formatDate(component.end) : '';\n component.endTime = component.end ? formatTime(component.end) : '';\n component.dueDate = component.due ? formatDate(component.due) : '';\n component.dueTime = component.due ? formatTime(component.due) : '';\n\n // Update recurrence definition depending on selections\n if (this.$hasCustomRepeat) {\n if (this.repeat.frequency == 'monthly' && this.repeat.month.type && this.repeat.month.type == 'byday' ||\n this.repeat.frequency == 'yearly' && this.repeat.year.byday) {\n // BYDAY mask for a monthly or yearly recurrence\n delete component.repeat.monthdays;\n component.repeat.days = [{ day: this.repeat.month.day, occurrence: this.repeat.month.occurrence.toString() }];\n }\n else if (this.repeat.month.type) {\n // montly recurrence by month days or yearly by month\n delete component.repeat.days;\n }\n }\n else if (this.repeat.frequency) {\n component.repeat = { frequency: this.repeat.frequency };\n }\n if (this.repeat.frequency) {\n if (this.repeat.end == 'until' && this.repeat.until)\n component.repeat.until = this.repeat.until.stringWithSeparator('-');\n else if (this.repeat.end == 'count' && this.repeat.count)\n component.repeat.count = this.repeat.count;\n else {\n delete component.repeat.until;\n delete component.repeat.count;\n }\n }\n else {\n delete component.repeat;\n }\n\n if (this.$hasAlarm) {\n if (this.alarm.action && this.alarm.action == 'email' &&\n !(this.attendees && this.attendees.length > 0)) {\n // No attendees; email reminder must be sent to organizer only\n this.alarm.attendees = 0;\n this.alarm.organizer = 1;\n }\n }\n else {\n component.alarm = {};\n }\n\n function formatTime(date) {\n var hours = date.getHours();\n if (hours < 10) hours = '0' + hours;\n\n var minutes = date.getMinutes();\n if (minutes < 10) minutes = '0' + minutes;\n return hours + ':' + minutes;\n }\n\n function formatDate(date) {\n var year = date.getYear();\n if (year < 1000) year += 1900;\n\n var month = '' + (date.getMonth() + 1);\n if (month.length == 1)\n month = '0' + month;\n\n var day = '' + date.getDate();\n if (day.length == 1)\n day = '0' + day;\n\n return year + '-' + month + '-' + day;\n }\n\n return component;\n };\n\n})();\n"]}