Handle attach URLs in appointment editor

This commit is contained in:
Francis Lachapelle
2015-07-01 14:34:35 -04:00
parent ba5f6410ed
commit 35ff82710a
10 changed files with 156 additions and 19 deletions

View File

@@ -103,9 +103,6 @@ NSNumber *iCalDistantFutureNumber = nil;
value = [self comment];
if ([value length]) [data setObject: value forKey: @"comment"];
value = [self attach];
if (value && (value = [value absoluteString]) && [value length]) [data setObject: value forKey: @"attachUrl"];
value = [self accessClass];
if ([value length]) [data setObject: [value lowercaseString] forKey: @"classification"];
@@ -365,10 +362,6 @@ NSNumber *iCalDistantFutureNumber = nil;
if ([o isKindOfClass: [NSString class]])
[self setComment: [o stringByReplacingString: @"\r\n" withString: @"\n"]];
o = [data objectForKey: @"attachUrl"];
if ([o isKindOfClass: [NSString class]])
[self setAttach: o];
o = [data objectForKey: @"classification"];
if ([o isKindOfClass: [NSString class]])
[self setAccessClass: [o uppercaseString]];

View File

@@ -258,7 +258,7 @@
"All day Event" = "All day Event";
"check for conflicts" = "Check for conflicts";
"Browse URL" = "Browse URL";
"URL" = "URL";
"newAttendee" = "Add attendee";

View File

@@ -548,6 +548,8 @@
* @apiParam {Number} [resetAlarm] Mark alarm as triggered if set to 1
* @apiParam {Number} [snoozeAlarm] Snooze the alarm for this number of minutes
*
* @apiSuccess {_} . _From [UIxAppointmentEditor viewAction]_
*
* @apiSuccess (Success 200) {String} id Event ID
* @apiSuccess (Success 200) {String} pid Calendar ID (event's folder)
* @apiSuccess (Success 200) {String} calendar Human readable name of calendar
@@ -558,8 +560,10 @@
* @apiSuccess (Success 200) {String} localizedEndDate Formatted end date
* @apiSuccess (Success 200) {String} [localizedEndTime] Formatted end time
* @apiSuccess (Success 200) {Number} isReadOnly 1 if event is read-only
* @apiSuccess (Success 200) {Object[]} [attachUrls] Attached URLs
* @apiSuccess (Success 200) {String} attachUrls.value URL
*
* @apiSuccess {_} . _From [UIxComponentEditor loadAlarm]_
* @apiSuccess {_} .. _From [UIxComponentEditor alarm]_
*
* @apiSuccess (Success 200) {Object[]} [alarm] Alarm definition
* @apiSuccess (Success 200) {String} alarm.action Either display or email
@@ -572,12 +576,12 @@
* @apiSuccess (Success 200) {String} alarm.attendees.email Attendee's email address
* @apiSuccess (Success 200) {String} [alarm.attendees.uid] System user ID
*
* @apiSuccess {_} .. _From [iCalEvent+SOGo attributes]_
* @apiSuccess {_} ... _From [iCalEvent+SOGo attributes]_
*
* @apiSuccess (Success 200) {Number} isAllDay 1 if event is all-day
* @apiSuccess (Success 200) {Number} isTransparent 1 if the event is not opaque
*
* @apiSuccess {_} ... _From [iCalEntityObject+SOGo attributes]_
* @apiSuccess {_} .... _From [iCalEntityObject+SOGo attributes]_
*
* @apiSuccess (Success 200) {Number} sendAppointmentNotifications 1 if notifications must be sent
* @apiSuccess (Success 200) {String} component "vevent"
@@ -585,7 +589,6 @@
* @apiSuccess (Success 200) {String} [location] Location
* @apiSuccess (Success 200) {String} [comment] Comment
* @apiSuccess (Success 200) {String} [status] Status (tentative, confirmed, or cancelled)
* @apiSuccess (Success 200) {String} [attachUrl] Attached URL
* @apiSuccess (Success 200) {String} [createdBy] Value of custom header X-SOGo-Component-Created-By or organizer's "SENT-BY"
* @apiSuccess (Success 200) {Number} priority Priority (0-9)
* @apiSuccess (Success 200) {NSString} [classification] Either public, confidential or private
@@ -604,7 +607,7 @@
* @apiSuccess (Success 200) {String} [attendees.delegatedTo] User that the original request was delegated to
* @apiSuccess (Success 200) {String} [attendees.delegatedFrom] User the request was delegated from
*
* @apiSuccess {_} .... _From [iCalRepeatableEntityObject+SOGo attributes]_
* @apiSuccess {_} ..... _From [iCalRepeatableEntityObject+SOGo attributes]_
*
* @apiSuccess (Success 200) {Object} [repeat] Recurrence rule definition
* @apiSuccess (Success 200) {String} repeat.frequency Either daily, (every weekday), weekly, (bi-weekly), monthly, or yearly
@@ -620,6 +623,7 @@
- (id <WOActionResults>) viewAction
{
BOOL isAllDay;
NSArray *attachUrls;
NSMutableDictionary *data;
NSCalendarDate *eventStartDate, *eventEndDate;
NSTimeZone *timeZone;
@@ -685,9 +689,12 @@
[NSNumber numberWithBool: [self isReadOnly]], @"isReadOnly",
[dateFormatter formattedDate: eventStartDate], @"localizedStartDate",
[dateFormatter formattedDate: eventEndDate], @"localizedEndDate",
[self loadAlarm], @"alarm",
[self alarm], @"alarm",
nil];
attachUrls = [self attachUrls];
if ([attachUrls count]) [data setObject: attachUrls forKey: @"attachUrls"];
if (!isAllDay)
{
[data setObject: [dateFormatter formattedTime: eventStartDate] forKey: @"localizedStartTime"];

View File

@@ -36,7 +36,8 @@
- (BOOL) isReadOnly;
- (void) setAttributes: (NSDictionary *) attributes;
- (NSDictionary *) loadAlarm;
- (NSDictionary *) alarm;
- (NSArray *) attachUrls;
+ (NSArray *) reminderValues;
@end

View File

@@ -545,7 +545,7 @@ static NSArray *reminderValues = nil;
}
}
- (NSDictionary *) loadAlarm
- (NSDictionary *) alarm
{
NSArray *attendees;
NSMutableDictionary *alarmData;
@@ -595,13 +595,41 @@ static NSArray *reminderValues = nil;
return alarmData;
}
- (NSArray *) attachUrls
{
NSMutableArray *attachUrls;
NSArray *values;
NSString *attachUrl;
NSUInteger count, max;
values = [component attach];
max = [values count];
if (max > 0)
{
attachUrls = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
attachUrl = [values objectAtIndex: count];
if ([attachUrl length] > 0)
[attachUrls addObject: [NSDictionary dictionaryWithObject: attachUrl forKey: @"value"]];
}
}
else
attachUrls = nil;
return attachUrls;
}
- (void) setAttributes: (NSDictionary *) data
{
NSArray *values;
NSCalendarDate *now;
NSMutableArray *attachUrls;
NSMutableDictionary *dataWithOwner;
NSString *owner;
NSUInteger i;
SOGoAppointmentFolders *folders;
id destinationCalendar;
id destinationCalendar, o;
now = [NSCalendarDate calendarDate];
owner = [componentCalendar ownerInContext: context];
@@ -624,6 +652,27 @@ static NSArray *reminderValues = nil;
[self _handleOrganizer];
if ([[data objectForKey: @"attachUrls"] isKindOfClass: [NSArray class]])
{
values = [component childrenWithTag: @"attach"];
[component removeChildren: values];
values = [data objectForKey: @"attachUrls"];
attachUrls = [NSMutableArray arrayWithCapacity: [values count]];
for (i = 0; i < [values count]; i++)
{
o = [values objectAtIndex: i];
if ([o isKindOfClass: [NSDictionary class]])
{
[attachUrls addObject: [o objectForKey: @"value"]];
}
}
}
else
{
attachUrls = nil;
}
[component setAttach: attachUrls];
if ([[self clientObject] isNew])
{
[component setCreated: now];

View File

@@ -409,7 +409,7 @@
* @apiSuccess (Success 200) {String} completedDate Completed date (ISO8601)
* @apiSuccess (Success 200) {Number} percentComplete Percent completion
*
* @apiSuccess {_} .. _From [UIxComponentEdtiror loadAlarm]_
* @apiSuccess {_} .. _From [UIxComponentEdtiror alarm]_
*
* @apiSuccess (Success 200) {Object[]} [alarm] Alarm definition
* @apiSuccess (Success 200) {String} alarm.action Either display or email
@@ -530,7 +530,7 @@
[thisFolder nameInContainer], @"pid",
[thisFolder displayName], @"calendar",
[NSNumber numberWithBool: [self isReadOnly]], @"isReadOnly",
[self loadAlarm], @"alarm",
[self alarm], @"alarm",
nil];
if (startDate)

View File

@@ -104,6 +104,29 @@
<input type="text" ng-model="editor.component.endDate"/>
</md-input-container>
</div>
<!-- attach urls -->
<div class="attr" ng-repeat="attach in editor.component.attachUrls">
<div layout="row" layout-align="center end">
<md-input-container>
<label>
<var:string label:value="URL"/>
</label>
<input type="text" ng-model="attach.value"
sg-focus-on="attachUrl_{{$index}}"/>
</md-input-container>
<md-button class="iconButton" type="button" ng-click="editor.component.deleteAttachUrl($index)">
<i class="md-icon-remove-circle"><!-- remove --></i>
</md-button>
</div>
</div>
<div class="md-layout-margin" layout="row" layout-align="start center">
<md-button class="iconButton" type="button" ng-click="editor.addAttachUrl($event)">
<i class="md-icon-add"><!-- plus icon button--></i>
</md-button>
<label class="button-label">
<var:string label:value="Attach"/>
</label>
</div>
<!-- comment -->
<md-input-container>
<label><var:string label:value="Description"/></label>

View File

@@ -111,6 +111,29 @@
label:aria-label="% complete"><!-- slider --></md-slider>
<div flex="30"><var:string label:value="% complete"/></div>
</div>
<!-- attach urls -->
<div class="attr" ng-repeat="attach in editor.component.attachUrls">
<div layout="row" layout-align="center end">
<md-input-container>
<label>
<var:string label:value="URL"/>
</label>
<input type="text" ng-model="attach.value"
sg-focus-on="attachUrl_{{$index}}"/>
</md-input-container>
<md-button class="iconButton" type="button" ng-click="editor.component.deleteAttachUrl($index)">
<i class="md-icon-remove-circle"><!-- remove --></i>
</md-button>
</div>
</div>
<div class="md-layout-margin" layout="row" layout-align="start center">
<md-button class="iconButton" type="button" ng-click="editor.addAttachUrl($event)">
<i class="md-icon-add"><!-- plus icon button--></i>
</md-button>
<label class="button-label">
<var:string label:value="Attach"/>
</label>
</div>
<!-- comment -->
<md-input-container>
<label><var:string label:value="Description"/></label>

View File

@@ -514,6 +514,41 @@
this.attendees && this.attendees.length > 0;
};
/**
* @function addAttachUrl
* @memberof Component.prototype
* @desc Add a new attach URL if not already defined
* @param {string} attachUrl - the URL
* @returns the number of values in the list of attach URLs
*/
Component.prototype.addAttachUrl = function(attachUrl) {
if (angular.isUndefined(this.attachUrls)) {
this.attachUrls = [{value: attachUrl}];
}
else {
for (var i = 0; i < this.attachUrls.length; i++) {
if (this.attachUrls[i].value == attachUrl) {
break;
}
}
if (i == this.attachUrls.length)
this.attachUrls.push({value: attachUrl});
}
return this.attachUrls.length - 1;
};
/**
* @function deleteAttachUrl
* @memberof Component.prototype
* @desc Remove an attach URL
* @param {number} index - the URL index in the list of attach URLs
*/
Component.prototype.deleteAttachUrl = function(index) {
if (index > -1 && this.attachUrls.length > index) {
this.attachUrls.splice(index, 1);
}
};
/**
* @function $reset
* @memberof Component.prototype

View File

@@ -20,6 +20,7 @@
vm.cardFilter = cardFilter;
vm.cardResults = [];
vm.addAttendee = addAttendee;
vm.addAttachUrl = addAttachUrl;
vm.cancel = cancel;
vm.save = save;
vm.attendeesEditor = {
@@ -67,6 +68,11 @@
}
});
function addAttachUrl() {
var i = vm.component.addAttachUrl('');
focus('attachUrl_' + i);
};
function toggleRecurrenceEditor() {
vm.showRecurrenceEditor = !vm.showRecurrenceEditor;
vm.component.$hasCustomRepeat = vm.showRecurrenceEditor;