parent
188dd986d2
commit
1ee7693432
3
NEWS
3
NEWS
|
@ -18,7 +18,8 @@ Bug fixes
|
||||||
- [web] fixed vCard generation for tags with no type (#3826)
|
- [web] fixed vCard generation for tags with no type (#3826)
|
||||||
- [web] only show the organizer field of an IMIP REPLY if one is defined
|
- [web] only show the organizer field of an IMIP REPLY if one is defined
|
||||||
- [web] fixed saving the note of a card (#3849)
|
- [web] fixed saving the note of a card (#3849)
|
||||||
- [web] fixed support for recurrent tasks
|
- [web] fixed support for recurrent tasks (#3864)
|
||||||
|
- [web] restored support for alarms in tasks
|
||||||
- [web] improved validation of mail account delegators
|
- [web] improved validation of mail account delegators
|
||||||
- [web] fixed auto-completion of list members (#3870)
|
- [web] fixed auto-completion of list members (#3870)
|
||||||
- [web] added missing options to subscribed addressbooks (#3850)
|
- [web] added missing options to subscribed addressbooks (#3850)
|
||||||
|
|
|
@ -1007,13 +1007,13 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||||
{
|
{
|
||||||
master = [[[component parent] events] objectAtIndex: 0];
|
master = [[[component parent] events] objectAtIndex: 0];
|
||||||
masterEndDate = [master endDate];
|
masterEndDate = [master endDate];
|
||||||
endDate = [component endDate];
|
endDate = [(iCalEvent*) component endDate];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
master = [[[component parent] todos] objectAtIndex: 0];
|
master = [[[component parent] todos] objectAtIndex: 0];
|
||||||
masterEndDate = [master due];
|
masterEndDate = [master due];
|
||||||
endDate = [component due];
|
endDate = [(iCalToDo*) component due];
|
||||||
}
|
}
|
||||||
|
|
||||||
delta = [masterEndDate timeIntervalSinceDate: [master startDate]];
|
delta = [masterEndDate timeIntervalSinceDate: [master startDate]];
|
||||||
|
@ -1027,7 +1027,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||||
if (recordIndex > -1)
|
if (recordIndex > -1)
|
||||||
{
|
{
|
||||||
if ([dateRange containsDate: [component startDate]] ||
|
if ([dateRange containsDate: [component startDate]] ||
|
||||||
[dateRange containsDate: endDate])
|
(endDate && [dateRange containsDate: endDate]))
|
||||||
{
|
{
|
||||||
// We must pass nil to :container here in order to avoid re-entrancy issues.
|
// We must pass nil to :container here in order to avoid re-entrancy issues.
|
||||||
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil]];
|
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil]];
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* iCalToDot+SOGo.m - this file is part of SOGo
|
/* iCalToDot+SOGo.m - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2014 Inverse inc.
|
* Copyright (C) 2008-2016 Inverse inc.
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#import <SoObjects/SOGo/WOContext+SOGo.h>
|
#import <SoObjects/SOGo/WOContext+SOGo.h>
|
||||||
|
|
||||||
|
#import <SOGo/CardElement+SOGo.h>
|
||||||
#import <SOGo/NSCalendarDate+SOGo.h>
|
#import <SOGo/NSCalendarDate+SOGo.h>
|
||||||
#import <SOGo/SOGoUser.h>
|
#import <SOGo/SOGoUser.h>
|
||||||
#import <SOGo/SOGoUserDefaults.h>
|
#import <SOGo/SOGoUserDefaults.h>
|
||||||
|
@ -367,7 +368,11 @@
|
||||||
|
|
||||||
- (NSTimeInterval) occurenceInterval
|
- (NSTimeInterval) occurenceInterval
|
||||||
{
|
{
|
||||||
|
if ([self due])
|
||||||
return [[self due] timeIntervalSinceDate: [self startDate]];
|
return [[self due] timeIntervalSinceDate: [self startDate]];
|
||||||
|
else
|
||||||
|
// When no due date is defined, base recurrence calculation on a 60-minute duration
|
||||||
|
return 3600;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -661,7 +661,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="sg-tile-icons">
|
<div class="sg-tile-icons">
|
||||||
<md-icon ng-show="::task.c_iscycle">repeat</md-icon>
|
<md-icon ng-show="::task.c_iscycle">repeat</md-icon>
|
||||||
<md-icon ng-show="::event.c_nextalarm">alarm</md-icon>
|
<md-icon ng-show="::task.c_nextalarm">alarm</md-icon>
|
||||||
</div>
|
</div>
|
||||||
<md-divider><!-- divider --></md-divider>
|
<md-divider><!-- divider --></md-divider>
|
||||||
</md-list-item>
|
</md-list-item>
|
||||||
|
|
|
@ -181,7 +181,69 @@
|
||||||
<div flex="50" class="sg-padded--left">{{editor.component.percentComplete}} <var:string label:value="% complete"/></div>
|
<div flex="50" class="sg-padded--left">{{editor.component.percentComplete}} <var:string label:value="% complete"/></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- repeat -->
|
||||||
|
<div class="sg-form-section"
|
||||||
|
ng-show="editor.component.start">
|
||||||
|
<div layout="row" layout-align="start center">
|
||||||
|
<md-input-container class="md-block md-flex">
|
||||||
|
<label><var:string label:value="Repeat"/></label>
|
||||||
|
<md-select ng-model="editor.component.repeat.frequency" ng-disabled="editor.component.occurrenceId">
|
||||||
|
<var:foreach list="repeatList" item="item">
|
||||||
|
<md-option var:value="item"><var:string var:value="itemRepeatText"/></md-option>
|
||||||
|
</var:foreach>
|
||||||
|
</md-select>
|
||||||
|
</md-input-container>
|
||||||
|
<md-button type="button" class="sg-icon-button"
|
||||||
|
label:aria-label="repeat_CUSTOM"
|
||||||
|
ng-disabled="editor.component.occurrenceId"
|
||||||
|
ng-show="editor.component.repeat.frequency != 'never'"
|
||||||
|
ng-click="editor.toggleRecurrenceEditor()">
|
||||||
|
<md-icon ng-class="{'md-rotate-45': editor.showRecurrenceEditor}">add</md-icon>
|
||||||
|
</md-button>
|
||||||
|
</div>
|
||||||
|
<div ng-show="editor.showRecurrenceEditor" flex-offset="5">
|
||||||
|
<var:component className="UIxRecurrenceEditor" />
|
||||||
|
</div>
|
||||||
|
<!-- end repeat -->
|
||||||
|
<div layout="row">
|
||||||
|
<md-input-container class="md-block" flex="50" flex-xs="100"
|
||||||
|
ng-show="editor.component.repeat.frequency != 'never'">
|
||||||
|
<label><var:string label:value="End Repeat"/></label>
|
||||||
|
<md-select ng-model="editor.component.repeat.end"
|
||||||
|
ng-disabled="editor.component.occurrenceId">
|
||||||
|
<md-option value="never"><var:string label:value="Never"/></md-option>
|
||||||
|
<md-option value="count"><var:string label:value="After"/></md-option>
|
||||||
|
<md-option value="until"><var:string label:value="On Date"/></md-option>
|
||||||
|
</md-select>
|
||||||
|
</md-input-container>
|
||||||
|
<md-input-container class="md-block md-input-number"
|
||||||
|
ng-show="editor.component.repeat.end == 'count'">
|
||||||
|
<label><var:string label:value="times"/></label>
|
||||||
|
<input type="number" label:aria-label="times" ng-model="editor.component.repeat.count"/>
|
||||||
|
</md-input-container>
|
||||||
|
<md-input-container ng-show="editor.component.repeat.end == 'until'">
|
||||||
|
<md-datepicker name="repeat_until"
|
||||||
|
ng-model="editor.component.repeat.until"
|
||||||
|
md-min-date="editor.component.end"
|
||||||
|
label:md-placeholder="On Date"><!-- date picker --></md-datepicker>
|
||||||
|
<div ng-messages="eventForm.repeat_until.$error">
|
||||||
|
<div ng-message="mindate"><var:string label:value="validate_untilbeforeend"/></div>
|
||||||
|
</div>
|
||||||
|
</md-input-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sg-form-section"
|
||||||
|
ng-show="editor.component.start">
|
||||||
|
<!-- reminder -->
|
||||||
|
<md-checkbox ng-model="editor.component.$hasAlarm"
|
||||||
|
label:aria-label="Reminder">
|
||||||
|
<var:string label:value="Reminder"/>
|
||||||
|
</md-checkbox>
|
||||||
|
<div flex-offset="5"
|
||||||
|
ng-show="editor.component.$hasAlarm">
|
||||||
|
<var:component className="UIxReminderEditor" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</md-dialog-content>
|
</md-dialog-content>
|
||||||
<!-- cancel/reset/save -->
|
<!-- cancel/reset/save -->
|
||||||
<md-dialog-actions>
|
<md-dialog-actions>
|
||||||
|
|
|
@ -1129,7 +1129,7 @@
|
||||||
else if (this.repeat.frequency && this.repeat.frequency != 'never') {
|
else if (this.repeat.frequency && this.repeat.frequency != 'never') {
|
||||||
component.repeat = { frequency: this.repeat.frequency };
|
component.repeat = { frequency: this.repeat.frequency };
|
||||||
}
|
}
|
||||||
if (this.repeat.frequency) {
|
if (component.startDate && this.repeat.frequency) {
|
||||||
if (this.repeat.end == 'until' && this.repeat.until)
|
if (this.repeat.end == 'until' && this.repeat.until)
|
||||||
component.repeat.until = this.repeat.until.stringWithSeparator('-');
|
component.repeat.until = this.repeat.until.stringWithSeparator('-');
|
||||||
else if (this.repeat.end == 'count' && this.repeat.count)
|
else if (this.repeat.end == 'count' && this.repeat.count)
|
||||||
|
@ -1150,7 +1150,7 @@
|
||||||
delete component.completedDate;
|
delete component.completedDate;
|
||||||
|
|
||||||
// Verify alarm
|
// Verify alarm
|
||||||
if (this.$hasAlarm) {
|
if (component.startDate && this.$hasAlarm) {
|
||||||
if (this.alarm.action && this.alarm.action == 'email' &&
|
if (this.alarm.action && this.alarm.action == 'email' &&
|
||||||
!(this.attendees && this.attendees.length > 0)) {
|
!(this.attendees && this.attendees.length > 0)) {
|
||||||
// No attendees; email reminder must be sent to organizer only
|
// No attendees; email reminder must be sent to organizer only
|
||||||
|
|
Loading…
Reference in a new issue