Load calendars via DAV
This commit is contained in:
parent
d2683926a4
commit
95979ec58c
3 changed files with 498 additions and 7 deletions
|
@ -29,6 +29,15 @@ angular.module('Tasks').factory 'ListsModel',
|
|||
@_tmpIdCache = {}
|
||||
super()
|
||||
|
||||
insert: (url, props) ->
|
||||
calendar =
|
||||
id: '1'
|
||||
displayname: props['{DAV:}displayname'] || 'Unnamed'
|
||||
color: props['{http://apple.com/ns/ical/}calendar-color'] || '#1d2d44'
|
||||
order: parseInt(props['{http://apple.com/ns/ical/}calendar-order']) || 0
|
||||
console.log(calendar)
|
||||
@add(calendar)
|
||||
|
||||
add: (list, clearCache=true) ->
|
||||
|
||||
tmplist = @_tmpIdCache[list.tmpID]
|
||||
|
|
|
@ -21,12 +21,12 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
###
|
||||
|
||||
angular.module('Tasks').factory 'Persistence',
|
||||
['Request', 'Loading', '$rootScope', '$q',
|
||||
(Request, Loading, $rootScope, $q) ->
|
||||
['Request', 'Loading', '$rootScope', '$q', 'CalendarService'
|
||||
(Request, Loading, $rootScope, $q, CalendarService) ->
|
||||
|
||||
class Persistence
|
||||
|
||||
constructor: (@_request, @_Loading, @_$rootScope) ->
|
||||
constructor: (@_request, @_Loading, @_$rootScope, @_CalendarService) ->
|
||||
|
||||
init: ->
|
||||
@deferred = $q.defer()
|
||||
|
@ -37,6 +37,7 @@ angular.module('Tasks').factory 'Persistence',
|
|||
@getCollections()
|
||||
@getSettings()
|
||||
@getLists()
|
||||
@_CalendarService.getAll()
|
||||
@getTasks('init', 'all', successCallback)
|
||||
|
||||
@deferred.promise
|
||||
|
@ -388,6 +389,6 @@ angular.module('Tasks').factory 'Persistence',
|
|||
|
||||
@_request.post '/apps/tasks/tasks/{taskID}/category/remove', params
|
||||
|
||||
return new Persistence(Request, Loading, $rootScope)
|
||||
return new Persistence(Request, Loading, $rootScope, CalendarService)
|
||||
|
||||
]
|
||||
|
|
487
js/public/app.js
487
js/public/app.js
|
@ -2033,6 +2033,473 @@
|
|||
|
||||
}).call(this);
|
||||
|
||||
angular.module('Tasks').service('CalendarService', ['DavClient', 'ListsModel', function(DavClient, ListsModel){
|
||||
'use strict';
|
||||
|
||||
var _this = this;
|
||||
|
||||
this._CALENDAR_HOME = null;
|
||||
|
||||
this._currentUserPrincipal = null;
|
||||
|
||||
this._takenUrls = [];
|
||||
|
||||
this._PROPERTIES = [
|
||||
'{' + DavClient.NS_DAV + '}displayname',
|
||||
'{' + DavClient.NS_DAV + '}id',
|
||||
'{' + DavClient.NS_IETF + '}id',
|
||||
'{' + DavClient.NS_APPLE + '}id',
|
||||
'{' + DavClient.NS_IETF + '}calendar-description',
|
||||
'{' + DavClient.NS_IETF + '}calendar-timezone',
|
||||
'{' + DavClient.NS_APPLE + '}calendar-order',
|
||||
'{' + DavClient.NS_APPLE + '}calendar-color',
|
||||
'{' + DavClient.NS_IETF + '}supported-calendar-component-set',
|
||||
'{' + DavClient.NS_OWNCLOUD + '}calendar-enabled',
|
||||
'{' + DavClient.NS_DAV + '}acl',
|
||||
'{' + DavClient.NS_DAV + '}owner',
|
||||
'{' + DavClient.NS_OWNCLOUD + '}invite'
|
||||
];
|
||||
|
||||
function discoverHome(callback) {
|
||||
return DavClient.propFind(DavClient.buildUrl(OC.linkToRemoteBase('dav')), ['{' + DavClient.NS_DAV + '}current-user-principal'], 0).then(function(response) {
|
||||
if (!DavClient.wasRequestSuccessful(response.status)) {
|
||||
throw "CalDAV client could not be initialized - Querying current-user-principal failed";
|
||||
}
|
||||
|
||||
if (response.body.propStat.length < 1) {
|
||||
return;
|
||||
}
|
||||
var props = response.body.propStat[0].properties;
|
||||
_this._currentUserPrincipal = props['{' + DavClient.NS_DAV + '}current-user-principal'][0].textContent;
|
||||
|
||||
return DavClient.propFind(DavClient.buildUrl(_this._currentUserPrincipal), ['{' + DavClient.NS_IETF + '}calendar-home-set'], 0).then(function (response) {
|
||||
if (!DavClient.wasRequestSuccessful(response.status)) {
|
||||
throw "CalDAV client could not be initialized - Querying calendar-home-set failed";
|
||||
}
|
||||
|
||||
if (response.body.propStat.length < 1) {
|
||||
return;
|
||||
}
|
||||
var props = response.body.propStat[0].properties;
|
||||
_this._CALENDAR_HOME = props['{' + DavClient.NS_IETF + '}calendar-home-set'][0].textContent;
|
||||
|
||||
return callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getResponseCodeFromHTTPResponse(t) {
|
||||
return parseInt(t.split(' ')[1]);
|
||||
}
|
||||
|
||||
this.getAll = function() {
|
||||
if (this._CALENDAR_HOME === null) {
|
||||
return discoverHome(function() {
|
||||
return _this.getAll();
|
||||
});
|
||||
}
|
||||
|
||||
return DavClient.propFind(DavClient.buildUrl(this._CALENDAR_HOME), this._PROPERTIES, 1).then(function(response) {
|
||||
var calendars = [];
|
||||
|
||||
if (!DavClient.wasRequestSuccessful(response.status)) {
|
||||
throw "CalDAV client could not be initialized - Querying calendars failed";
|
||||
}
|
||||
|
||||
for (var i = 0; i < response.body.length; i++) {
|
||||
var body = response.body[i];
|
||||
if (body.propStat.length < 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_this._takenUrls.push(body.href);
|
||||
|
||||
var responseCode = getResponseCodeFromHTTPResponse(body.propStat[0].status);
|
||||
if (!DavClient.wasRequestSuccessful(responseCode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var doesSupportVEvent = false;
|
||||
var components = body.propStat[0].properties['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'];
|
||||
if (components) {
|
||||
for (var j=0; j < components.length; j++) {
|
||||
var name = components[j].attributes.getNamedItem('name').textContent.toLowerCase();
|
||||
if (name === 'vevent') {
|
||||
doesSupportVEvent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!doesSupportVEvent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_this._getACLFromResponse(body);
|
||||
|
||||
ListsModel.insert(body.href, body.propStat[0].properties);
|
||||
// calendars.push(calendar);
|
||||
}
|
||||
|
||||
return calendars;
|
||||
});
|
||||
};
|
||||
|
||||
this.get = function(url) {
|
||||
if (this._CALENDAR_HOME === null) {
|
||||
return discoverHome(function() {
|
||||
return _this.get(url);
|
||||
});
|
||||
}
|
||||
|
||||
return DavClient.propFind(DavClient.buildUrl(url), this._PROPERTIES, 0).then(function(response) {
|
||||
var body = response.body;
|
||||
if (body.propStat.length < 1) {
|
||||
//TODO - something went wrong
|
||||
return;
|
||||
}
|
||||
|
||||
var responseCode = getResponseCodeFromHTTPResponse(body.propStat[0].status);
|
||||
if (!DavClient.wasRequestSuccessful(responseCode)) {
|
||||
//TODO - something went wrong
|
||||
return;
|
||||
}
|
||||
|
||||
_this._getACLFromResponse(body);
|
||||
|
||||
return '';//new Calendar(body.href, body.propStat[0].properties);
|
||||
});
|
||||
};
|
||||
|
||||
this.create = function(name, color, components) {
|
||||
if (this._CALENDAR_HOME === null) {
|
||||
return discoverHome(function() {
|
||||
return _this.create(name, color);
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof components === 'undefined') {
|
||||
components = ['vevent'];
|
||||
}
|
||||
|
||||
var xmlDoc = document.implementation.createDocument('', '', null);
|
||||
var cMkcalendar = xmlDoc.createElement('c:mkcalendar');
|
||||
cMkcalendar.setAttribute('xmlns:c', 'urn:ietf:params:xml:ns:caldav');
|
||||
cMkcalendar.setAttribute('xmlns:d', 'DAV:');
|
||||
cMkcalendar.setAttribute('xmlns:a', 'http://apple.com/ns/ical/');
|
||||
cMkcalendar.setAttribute('xmlns:o', 'http://owncloud.org/ns');
|
||||
xmlDoc.appendChild(cMkcalendar);
|
||||
|
||||
var dSet = xmlDoc.createElement('d:set');
|
||||
cMkcalendar.appendChild(dSet);
|
||||
|
||||
var dProp = xmlDoc.createElement('d:prop');
|
||||
dSet.appendChild(dProp);
|
||||
|
||||
dProp.appendChild(this._createXMLForProperty(xmlDoc, 'displayname', name));
|
||||
dProp.appendChild(this._createXMLForProperty(xmlDoc, 'enabled', true));
|
||||
dProp.appendChild(this._createXMLForProperty(xmlDoc, 'color', color));
|
||||
dProp.appendChild(this._createXMLForProperty(xmlDoc, 'components', components));
|
||||
|
||||
var body = cMkcalendar.outerHTML;
|
||||
|
||||
var uri = this._suggestUri(name);
|
||||
var url = this._CALENDAR_HOME + uri + '/';
|
||||
var headers = {
|
||||
'Content-Type' : 'application/xml; charset=utf-8'
|
||||
};
|
||||
|
||||
return DavClient.request('MKCALENDAR', url, headers, body).then(function(response) {
|
||||
if (response.status === 201) {
|
||||
_this._takenUrls.push(url);
|
||||
return _this.get(url).then(function(calendar) {
|
||||
calendar.enabled = true;
|
||||
return _this.update(calendar);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.update = function(calendar) {
|
||||
var xmlDoc = document.implementation.createDocument('', '', null);
|
||||
var dPropUpdate = xmlDoc.createElement('d:propertyupdate');
|
||||
dPropUpdate.setAttribute('xmlns:c', 'urn:ietf:params:xml:ns:caldav');
|
||||
dPropUpdate.setAttribute('xmlns:d', 'DAV:');
|
||||
dPropUpdate.setAttribute('xmlns:a', 'http://apple.com/ns/ical/');
|
||||
dPropUpdate.setAttribute('xmlns:o', 'http://owncloud.org/ns');
|
||||
xmlDoc.appendChild(dPropUpdate);
|
||||
|
||||
var dSet = xmlDoc.createElement('d:set');
|
||||
dPropUpdate.appendChild(dSet);
|
||||
|
||||
var dProp = xmlDoc.createElement('d:prop');
|
||||
dSet.appendChild(dProp);
|
||||
|
||||
var updatedProperties = calendar.updatedProperties;
|
||||
calendar.resetUpdatedProperties();
|
||||
for (var i=0; i < updatedProperties.length; i++) {
|
||||
dProp.appendChild(this._createXMLForProperty(
|
||||
xmlDoc,
|
||||
updatedProperties[i],
|
||||
calendar[updatedProperties[i]]
|
||||
));
|
||||
}
|
||||
|
||||
var url = calendar.url;
|
||||
var body = dPropUpdate.outerHTML;
|
||||
var headers = {
|
||||
'Content-Type' : 'application/xml; charset=utf-8'
|
||||
};
|
||||
|
||||
return DavClient.request('PROPPATCH', url, headers, body).then(function(response) {
|
||||
var responseBody = DavClient.parseMultiStatus(response.body);
|
||||
console.log(responseBody);
|
||||
return calendar;
|
||||
});
|
||||
};
|
||||
|
||||
this.delete = function(calendar) {
|
||||
return DavClient.request('DELETE', calendar.url, {}, '').then(function(response) {
|
||||
if (response.status === 204) {
|
||||
return true;
|
||||
} else {
|
||||
// TODO - handle error case
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.share = function(calendar, shareType, shareWith, writable, existingShare) {
|
||||
var xmlDoc = document.implementation.createDocument('', '', null);
|
||||
var oShare = xmlDoc.createElement('o:share');
|
||||
oShare.setAttribute('xmlns:d', 'DAV:');
|
||||
oShare.setAttribute('xmlns:o', 'http://owncloud.org/ns');
|
||||
xmlDoc.appendChild(oShare);
|
||||
|
||||
var oSet = xmlDoc.createElement('o:set');
|
||||
oShare.appendChild(oSet);
|
||||
|
||||
var dHref = xmlDoc.createElement('d:href');
|
||||
if (shareType === OC.Share.SHARE_TYPE_USER) {
|
||||
dHref.textContent = 'principal:principals/users/';
|
||||
} else if (shareType === OC.Share.SHARE_TYPE_GROUP) {
|
||||
dHref.textContent = 'principal:principals/groups/';
|
||||
}
|
||||
dHref.textContent += shareWith;
|
||||
oSet.appendChild(dHref);
|
||||
|
||||
var oSummary = xmlDoc.createElement('o:summary');
|
||||
oSummary.textContent = t('calendar', '{calendar} shared by {owner}', {
|
||||
calendar: calendar.displayname,
|
||||
owner: calendar.owner
|
||||
});
|
||||
oSet.appendChild(oSummary);
|
||||
|
||||
if (writable) {
|
||||
var oRW = xmlDoc.createElement('o:read-write');
|
||||
oSet.appendChild(oRW);
|
||||
}
|
||||
|
||||
var headers = {
|
||||
'Content-Type' : 'application/xml; charset=utf-8',
|
||||
requesttoken: oc_requesttoken
|
||||
};
|
||||
var body = oShare.outerHTML;
|
||||
return DavClient.request('POST', calendar.url, headers, body).then(function(response) {
|
||||
if (response.status === 200) {
|
||||
if (!existingShare) {
|
||||
if (shareType === OC.Share.SHARE_TYPE_USER) {
|
||||
calendar.sharedWith.users.push({
|
||||
id: shareWith,
|
||||
displayname: shareWith,
|
||||
writable: writable
|
||||
});
|
||||
} else if (shareType === OC.Share.SHARE_TYPE_GROUP) {
|
||||
calendar.sharedWith.groups.push({
|
||||
id: shareWith,
|
||||
displayname: shareWith,
|
||||
writable: writable
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.unshare = function(calendar, shareType, shareWith) {
|
||||
var xmlDoc = document.implementation.createDocument('', '', null);
|
||||
var oShare = xmlDoc.createElement('o:share');
|
||||
oShare.setAttribute('xmlns:d', 'DAV:');
|
||||
oShare.setAttribute('xmlns:o', 'http://owncloud.org/ns');
|
||||
xmlDoc.appendChild(oShare);
|
||||
|
||||
var oRemove = xmlDoc.createElement('o:remove');
|
||||
oShare.appendChild(oRemove);
|
||||
|
||||
var dHref = xmlDoc.createElement('d:href');
|
||||
if (shareType === OC.Share.SHARE_TYPE_USER) {
|
||||
dHref.textContent = 'principal:principals/users/';
|
||||
} else if (shareType === OC.Share.SHARE_TYPE_GROUP) {
|
||||
dHref.textContent = 'principal:principals/groups/';
|
||||
}
|
||||
dHref.textContent += shareWith;
|
||||
oRemove.appendChild(dHref);
|
||||
|
||||
var headers = {
|
||||
'Content-Type' : 'application/xml; charset=utf-8',
|
||||
requesttoken: oc_requesttoken
|
||||
};
|
||||
var body = oShare.outerHTML;
|
||||
return DavClient.request('POST', calendar.url, headers, body).then(function(response) {
|
||||
if (response.status === 200) {
|
||||
if (shareType === OC.Share.SHARE_TYPE_USER) {
|
||||
calendar.sharedWith.users = calendar.sharedWith.users.filter(function(user) {
|
||||
return user.id !== shareWith;
|
||||
});
|
||||
} else if (shareType === OC.Share.SHARE_TYPE_GROUP) {
|
||||
calendar.sharedWith.groups = calendar.sharedWith.groups.filter(function(groups) {
|
||||
return groups.id !== shareWith;
|
||||
});
|
||||
}
|
||||
//todo - remove entry from calendar object
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this._createXMLForProperty = function(xmlDoc, propName, value) {
|
||||
switch(propName) {
|
||||
case 'enabled':
|
||||
var oEnabled = xmlDoc.createElement('o:calendar-enabled');
|
||||
oEnabled.textContent = value ? '1' : '0';
|
||||
return oEnabled;
|
||||
|
||||
case 'displayname':
|
||||
var dDisplayname = xmlDoc.createElement('d:displayname');
|
||||
dDisplayname.textContent = value;
|
||||
return dDisplayname;
|
||||
|
||||
case 'order':
|
||||
var aOrder = xmlDoc.createElement('a:calendar-color');
|
||||
aOrder.textContent = value;
|
||||
return aOrder;
|
||||
|
||||
case 'color':
|
||||
var aColor = xmlDoc.createElement('a:calendar-color');
|
||||
aColor.textContent = value;
|
||||
return aColor;
|
||||
|
||||
case 'components':
|
||||
var cComponents = xmlDoc.createElement('c:supported-calendar-component-set');
|
||||
for (var i=0; i < value.length; i++) {
|
||||
var cComp = xmlDoc.createElement('c:comp');
|
||||
cComp.setAttribute('name', value[i].toUpperCase());
|
||||
cComponents.appendChild(cComp);
|
||||
}
|
||||
return cComponents;
|
||||
}
|
||||
};
|
||||
|
||||
this._getACLFromResponse = function(body) {
|
||||
var canWrite = false;
|
||||
var acl = body.propStat[0].properties['{' + DavClient.NS_DAV + '}acl'];
|
||||
if (acl) {
|
||||
for (var k=0; k < acl.length; k++) {
|
||||
var href = acl[k].getElementsByTagNameNS('DAV:', 'href');
|
||||
if (href.length === 0) {
|
||||
continue;
|
||||
}
|
||||
href = href[0].textContent;
|
||||
if (href !== _this._currentUserPrincipal) {
|
||||
continue;
|
||||
}
|
||||
var writeNode = acl[k].getElementsByTagNameNS('DAV:', 'write');
|
||||
if (writeNode.length > 0) {
|
||||
canWrite = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
body.propStat[0].properties.canWrite = canWrite;
|
||||
};
|
||||
|
||||
this._isUriAlreadyTaken = function(uri) {
|
||||
return (this._takenUrls.indexOf(this._CALENDAR_HOME + uri + '/') !== -1);
|
||||
};
|
||||
|
||||
this._suggestUri = function(displayname) {
|
||||
var uri = displayname.toString().toLowerCase()
|
||||
.replace(/\s+/g, '-') // Replace spaces with -
|
||||
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
|
||||
.replace(/\-\-+/g, '-') // Replace multiple - with single -
|
||||
.replace(/^-+/, '') // Trim - from start of text
|
||||
.replace(/-+$/, ''); // Trim - from end of text
|
||||
|
||||
if (!this._isUriAlreadyTaken(uri)) {
|
||||
return uri;
|
||||
}
|
||||
|
||||
if (uri.indexOf('-') === -1) {
|
||||
uri = uri + '-1';
|
||||
if (!this._isUriAlreadyTaken(uri)) {
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
while (this._isUriAlreadyTaken(uri)) {
|
||||
var positionLastDash = uri.lastIndexOf('-');
|
||||
var firstPart = uri.substr(0, positionLastDash);
|
||||
var lastPart = uri.substr(positionLastDash + 1);
|
||||
|
||||
if (lastPart.match(/^\d+$/)) {
|
||||
lastPart = parseInt(lastPart);
|
||||
lastPart++;
|
||||
|
||||
uri = firstPart + '-' + lastPart;
|
||||
} else if (lastPart === '') {
|
||||
uri = uri + '1';
|
||||
} else {
|
||||
uri = uri = '-1';
|
||||
}
|
||||
}
|
||||
|
||||
return uri;
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
angular.module('Tasks').service('DavClient', function() {
|
||||
'use strict';
|
||||
|
||||
var client = new dav.Client({
|
||||
baseUrl: OC.linkToRemote('dav/calendars'),
|
||||
xmlNamespaces: {
|
||||
'DAV:': 'd',
|
||||
'urn:ietf:params:xml:ns:caldav': 'c',
|
||||
'http://apple.com/ns/ical/': 'aapl',
|
||||
'http://owncloud.org/ns': 'oc',
|
||||
'http://calendarserver.org/ns/': 'cs'
|
||||
}
|
||||
});
|
||||
|
||||
angular.extend(client, {
|
||||
NS_DAV: 'DAV:',
|
||||
NS_IETF: 'urn:ietf:params:xml:ns:caldav',
|
||||
NS_APPLE: 'http://apple.com/ns/ical/',
|
||||
NS_OWNCLOUD: 'http://owncloud.org/ns',
|
||||
NS_CALENDARSERVER: 'http://calendarserver.org/ns/',
|
||||
|
||||
buildUrl: function(path) {
|
||||
return window.location.protocol + '//' + window.location.host + path;
|
||||
},
|
||||
wasRequestSuccessful: function(status) {
|
||||
return (status >= 200 && status <= 299);
|
||||
}
|
||||
});
|
||||
|
||||
return client;
|
||||
});
|
||||
|
||||
(function() {
|
||||
angular.module('Tasks').factory('Loading', [
|
||||
function() {
|
||||
|
@ -2249,6 +2716,18 @@
|
|||
ListsModel.__super__.constructor.call(this);
|
||||
}
|
||||
|
||||
ListsModel.prototype.insert = function(url, props) {
|
||||
var calendar;
|
||||
calendar = {
|
||||
id: '1',
|
||||
displayname: props['{DAV:}displayname'] || 'Unnamed',
|
||||
color: props['{http://apple.com/ns/ical/}calendar-color'] || '#1d2d44',
|
||||
order: parseInt(props['{http://apple.com/ns/ical/}calendar-order']) || 0
|
||||
};
|
||||
console.log(calendar);
|
||||
return this.add(calendar);
|
||||
};
|
||||
|
||||
ListsModel.prototype.add = function(list, clearCache) {
|
||||
var tmplist, updateById, updateByTmpId;
|
||||
if (clearCache == null) {
|
||||
|
@ -2938,13 +3417,14 @@
|
|||
|
||||
(function() {
|
||||
angular.module('Tasks').factory('Persistence', [
|
||||
'Request', 'Loading', '$rootScope', '$q', function(Request, Loading, $rootScope, $q) {
|
||||
'Request', 'Loading', '$rootScope', '$q', 'CalendarService', function(Request, Loading, $rootScope, $q, CalendarService) {
|
||||
var Persistence;
|
||||
Persistence = (function() {
|
||||
function Persistence(_request, _Loading, _$rootScope) {
|
||||
function Persistence(_request, _Loading, _$rootScope, _CalendarService) {
|
||||
this._request = _request;
|
||||
this._Loading = _Loading;
|
||||
this._$rootScope = _$rootScope;
|
||||
this._CalendarService = _CalendarService;
|
||||
}
|
||||
|
||||
Persistence.prototype.init = function() {
|
||||
|
@ -2957,6 +3437,7 @@
|
|||
this.getCollections();
|
||||
this.getSettings();
|
||||
this.getLists();
|
||||
this._CalendarService.getAll();
|
||||
this.getTasks('init', 'all', successCallback);
|
||||
return this.deferred.promise;
|
||||
};
|
||||
|
@ -3465,7 +3946,7 @@
|
|||
return Persistence;
|
||||
|
||||
})();
|
||||
return new Persistence(Request, Loading, $rootScope);
|
||||
return new Persistence(Request, Loading, $rootScope, CalendarService);
|
||||
}
|
||||
]);
|
||||
|
||||
|
|
Loading…
Reference in a new issue