Handle the edition of recurring event occurrences

pull/91/head
Francis Lachapelle 2015-07-27 16:02:05 -04:00
parent 049c1385d6
commit 86a0032cc1
9 changed files with 66 additions and 16 deletions

View File

@ -521,6 +521,8 @@ vtodo_class2 = "(Confidential task)";
"editRepeatingItem" = "The item you are editing is a repeating item. Do you want to edit all occurences of it or only this single instance?";
"button_thisOccurrenceOnly" = "This occurence only";
"button_allOccurrences" = "All occurences";
"Edit This Occurrence" = "Edit This Occurrence";
"Edit All Occurrences" = "Edit All Occurrences";
/* Properties dialog */
"Name:" = "Name:";

View File

@ -551,6 +551,7 @@
* @apiSuccess {_} . _From [UIxAppointmentEditor viewAction]_
*
* @apiSuccess (Success 200) {String} id Event ID
* @apiSuccess (Success 200) {String} [occurrenceId] Occurrence ID
* @apiSuccess (Success 200) {String} pid Calendar ID (event's folder)
* @apiSuccess (Success 200) {String} calendar Human readable name of calendar
* @apiSuccess (Success 200) {String} startDate Start date (ISO8601)
@ -683,7 +684,6 @@
}
data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[co nameInContainer], @"id",
[componentCalendar nameInContainer], @"pid",
[componentCalendar displayName], @"calendar",
[NSNumber numberWithBool: [self isReadOnly]], @"isReadOnly",
@ -692,6 +692,16 @@
[self alarm], @"alarm",
nil];
if ([self isChildOccurrence])
{
[data setObject: [[co container] nameInContainer] forKey: @"id"];
[data setObject: [co nameInContainer] forKey: @"occurrenceId"];
}
else
{
[data setObject: [co nameInContainer] forKey: @"id"];
}
attachUrls = [self attachUrls];
if ([attachUrls count]) [data setObject: attachUrls forKey: @"attachUrls"];

View File

@ -696,7 +696,7 @@ static NSArray *tasksFields = nil;
* @apiSuccess (Success 200) {String} events.c_owner Event's owner
* @apiSuccess (Success 200) {Number} events.c_iscycle 1 if the event is cyclic
* @apiSuccess (Success 200) {Number} events.c_nextalarm Epoch time of next alarm
* @apiSuccess (Success 200) {String} events.c_recurrence_id Recurrence ID if event is cyclic
* @apiSuccess (Success 200) {String} [events.c_recurrence_id] Recurrence ID if event is cyclic
* @apiSuccess (Success 200) {Number} events.isException 1 if recurrence is an exception
* @apiSuccess (Success 200) {Number} events.editable 1 if active user can edit the event
* @apiSuccess (Success 200) {Number} events.erasable 1 if active user can erase the event
@ -723,6 +723,10 @@ static NSArray *tasksFields = nil;
while ((oldEvent = [events nextObject]))
{
newEvent = [NSMutableArray arrayWithArray: oldEvent];
if (![[oldEvent objectAtIndex: eventRecurrenceIdIndex] isKindOfClass: [NSNull class]])
[newEvent replaceObjectAtIndex: eventRecurrenceIdIndex
withObject: [NSString stringWithFormat: @"occurence%@",
[oldEvent objectAtIndex: eventRecurrenceIdIndex]]];
isAllDay = [[oldEvent objectAtIndex: eventIsAllDayIndex] boolValue];
interval = [[oldEvent objectAtIndex: eventStartDateIndex] intValue];
[newEvent addObject: [self _formattedDateForSeconds: interval
@ -1213,7 +1217,7 @@ _computeBlocksPosition (NSArray *blocks)
* @apiSuccess (Success 200) {String} events.c_owner Event's owner
* @apiSuccess (Success 200) {Number} events.c_iscycle 1 if the event is cyclic
* @apiSuccess (Success 200) {Number} events.c_nextalarm Epoch time of next alarm
* @apiSuccess (Success 200) {String} events.c_recurrence_id Recurrence ID if event is cyclic
* @apiSuccess (Success 200) {String} [events.c_recurrence_id] Recurrence ID if event is cyclic
* @apiSuccess (Success 200) {Number} events.isException 1 if recurrence is an exception
* @apiSuccess (Success 200) {Number} events.editable 1 if active user can edit the event
* @apiSuccess (Success 200) {Number} events.erasable 1 if active user can erase the event
@ -1383,7 +1387,7 @@ _computeBlocksPosition (NSArray *blocks)
* @apiSuccess (Success 200) {Number} tasks.erasable 1 if task is erasable by the active user
* @apiSuccess (Success 200) {String} tasks.c_priority Priority (0-9)
* @apiSuccess (Success 200) {String} tasks.c_owner Username of owner
* @apiSuccess (Success 200) {String} tasks.c_recurrence_id Recurrence ID if task is cyclic
* @apiSuccess (Success 200) {String} [tasks.c_recurrence_id] Recurrence ID if task is cyclic
* @apiSuccess (Success 200) {Number} tasks.isException 1 if task is cyclic and an exception
* @apiSuccess (Success 200) {String} tasks.status Either completed, overdue, duetoday, or duelater
* @apiSuccess (Success 200) {String} tasks.formatted_enddate Localized end date
@ -1422,10 +1426,14 @@ _computeBlocksPosition (NSArray *blocks)
while ((task = [tasks nextObject]))
{
statusCode = [[task objectAtIndex: 3] intValue];
statusCode = [[task objectAtIndex: taskStatusIndex] intValue];
if (statusCode != 1 || showCompleted)
{
filteredTask = [NSMutableArray arrayWithArray: task];
if (![[task objectAtIndex: taskRecurrenceIdIndex] isKindOfClass: [NSNull class]])
[filteredTask replaceObjectAtIndex: taskRecurrenceIdIndex
withObject: [NSString stringWithFormat: @"occurence%@",
[task objectAtIndex: taskRecurrenceIdIndex]]];
endDateStamp = [[task objectAtIndex: taskEndDateIndex] intValue];
statusFlag = [self _getStatusClassForStatusCode: statusCode
andEndDateStamp: endDateStamp];

View File

@ -34,6 +34,7 @@
}
- (BOOL) isReadOnly;
- (BOOL) isChildOccurrence;
- (void) setAttributes: (NSDictionary *) attributes;
- (NSDictionary *) alarm;

View File

@ -158,6 +158,11 @@ static NSArray *reminderValues = nil;
[componentCalendar retain];
}
- (BOOL) isChildOccurrence
{
return [[self clientObject] isKindOfClass: [SOGoComponentOccurence class]];
}
//- (NSString *) title
//{
// SOGoCalendarComponent *co;

View File

@ -110,12 +110,18 @@
<var:component className="UIxAttendeesEditor" />
</div>
</md-dialog-content>
<!-- edit -->
<div class="md-actions">
<md-button type="button" ng-click="viewer.edit()">
<!-- actions -->
<div class="md-actions">
<md-button type="button" ng-click="viewer.edit()" ng-hide="viewer.component.occurrenceId">
<var:string label:value="Edit"/>
</md-button>
</div>
<md-button type="button" ng-click="viewer.editAllOccurrences()" ng-show="viewer.component.occurrenceId">
<var:string label:value="Edit All Occurrences"/>
</md-button>
<md-button type="button" ng-click="viewer.edit()" ng-show="viewer.component.occurrenceId">
<var:string label:value="Edit This Occurrence"/>
</md-button>
</div>
</form>
</md-dialog>
</container>

View File

@ -274,8 +274,8 @@
* @desc Fetch a component attributes from the server.
* @returns a promise of the HTTP operation
*/
Calendar.prototype.$getComponent = function(componentId) {
return Calendar.$Component.$find(this.id, componentId);
Calendar.prototype.$getComponent = function(componentId, recurrenceId) {
return Calendar.$Component.$find(this.id, componentId, recurrenceId);
};
/**

View File

@ -124,10 +124,16 @@
* @desc Fetch a component from a specific calendar.
* @param {string} calendarId - the calendar ID
* @param {string} componentId - the component ID
* @param {string} [occurrenceId] - the component ID
* @see {@link Calendar.$getComponent}
*/
Component.$find = function(calendarId, componentId) {
var futureComponentData = this.$$resource.fetch([calendarId, componentId].join('/'), 'view');
Component.$find = function(calendarId, componentId, occurrenceId) {
var futureComponentData, path = [calendarId, componentId];
if (occurrenceId)
path.push(occurrenceId);
futureComponentData = this.$$resource.fetch(path.join('/'), 'view');
return new Component(futureComponentData);
};
@ -608,12 +614,15 @@
* @desc Save the component to the server.
*/
Component.prototype.$save = function() {
var _this = this, options;
var _this = this, options, path = [this.pid, this.id];
if (this.isNew)
options = { action: 'saveAs' + this.type.capitalize() };
return Component.$$resource.save([this.pid, this.id].join('/'), this.$omit(), options)
if (this.occurrenceId)
path.push(this.occurrenceId);
return Component.$$resource.save(path.join('/'), this.$omit(), options)
.then(function(data) {
// Make a copy of the data for an eventual reset
_this.$shadowData = _this.$omit(true);

View File

@ -13,10 +13,11 @@
vm.component = stateComponent;
vm.close = close;
vm.edit = edit;
vm.editAllOccurrences = editAllOccurrences;
// Load all attributes of component
if (angular.isUndefined(vm.component.$futureComponentData)) {
component = Calendar.$get(vm.component.c_folder).$getComponent(vm.component.c_name);
component = Calendar.$get(vm.component.c_folder).$getComponent(vm.component.c_name, vm.component.c_recurrence_id);
component.$futureComponentData.then(function() {
vm.component = component;
});
@ -26,6 +27,14 @@
$mdDialog.hide();
}
function editAllOccurrences() {
component = Calendar.$get(vm.component.pid).$getComponent(vm.component.id);
component.$futureComponentData.then(function() {
vm.component = component;
edit();
});
}
function edit() {
var type = (vm.component.component == 'vevent')? 'Appointment':'Task';
$mdDialog.hide().then(function() {