+ ui-sref="calendars.component({calendarId: event.c_folder,
+ componentType: 'appointment',
+ componentId: event.c_name})">
{{event.c_title}}
{{event.c_location}}
@@ -392,12 +393,20 @@
-
-
- {{task.c_title}}
- {{task.formatted_enddate}}
+
+
+
+
{{task.c_title}}
+
+ {{task.formatted_enddate}}
+
+
+
+
diff --git a/UI/Templates/SchedulerUI/UIxReminderEditor.wox b/UI/Templates/SchedulerUI/UIxReminderEditor.wox
index d8cb9312a..518cf90ca 100644
--- a/UI/Templates/SchedulerUI/UIxReminderEditor.wox
+++ b/UI/Templates/SchedulerUI/UIxReminderEditor.wox
@@ -7,19 +7,19 @@
>
-
+
-
+
-
+
-
+
@@ -29,7 +29,7 @@
+ ng-model="editor.component.alarm.action">
@@ -39,14 +39,14 @@
-
+
-
diff --git a/UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox b/UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
new file mode 100644
index 000000000..1665f3e27
--- /dev/null
+++ b/UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
@@ -0,0 +1,184 @@
+
+
+
+
diff --git a/UI/WebServerResources/js/Scheduler.app.js b/UI/WebServerResources/js/Scheduler.app.js
index 0a03d2f68..e33eaaaf7 100644
--- a/UI/WebServerResources/js/Scheduler.app.js
+++ b/UI/WebServerResources/js/Scheduler.app.js
@@ -64,7 +64,11 @@
url: '/:calendarId/{componentType:(?:appointment|task)}/new',
views: {
componentEditor: {
- templateUrl: 'UIxAppointmentEditorTemplate',
+ templateUrl: function($stateParams) {
+ // UI/Templates/SchedulerUI/UIxAppointmentEditorTemplate.wox or
+ // UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
+ return 'UIx' + $stateParams.componentType.capitalize() + 'EditorTemplate';
+ },
controller: 'ComponentController',
controllerAs: 'editor'
}
@@ -74,10 +78,14 @@
}
})
.state('calendars.component', {
- url: '/:calendarId/event/:componentId',
+ url: '/:calendarId/{componentType:(?:appointment|task)}/:componentId',
views: {
componentEditor: {
- templateUrl: 'UIxAppointmentEditorTemplate',
+ templateUrl: function($stateParams) {
+ // UI/Templates/SchedulerUI/UIxAppointmentEditorTemplate.wox or
+ // UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
+ return 'UIx' + $stateParams.componentType.capitalize() + 'EditorTemplate';
+ },
controller: 'ComponentController',
controllerAs: 'editor'
}
diff --git a/UI/WebServerResources/js/Scheduler/Component.service.js b/UI/WebServerResources/js/Scheduler/Component.service.js
index 15eb38d62..ac8eb84ed 100644
--- a/UI/WebServerResources/js/Scheduler/Component.service.js
+++ b/UI/WebServerResources/js/Scheduler/Component.service.js
@@ -246,12 +246,15 @@
this.categories = [];
this.repeat = {};
this.alarm = { action: 'display', quantity: 5, unit: 'MINUTES', reference: 'BEFORE', relation: 'START' };
+ this.status = 'not-specified';
angular.extend(this, data);
if (this.startDate)
this.start = new Date(this.startDate.substring(0,10) + ' ' + this.startDate.substring(11,16));
if (this.endDate)
this.end = new Date(this.endDate.substring(0,10) + ' ' + this.endDate.substring(11,16));
+ if (this.dueDate)
+ this.due = new Date(this.dueDate.substring(0,10) + ' ' + this.dueDate.substring(11,16));
// Parse recurrence rule definition and initialize default values
if (this.repeat.days) {
@@ -294,7 +297,7 @@
this.$hasAlarm = angular.isDefined(data.alarm);
- // Allow the event to be moved to a different calendar
+ // Allow the component to be moved to a different calendar
this.destinationCalendar = this.pid;
// Load freebusy of attendees
@@ -311,7 +314,7 @@
* @function hasCustomRepeat
* @memberof Component.prototype
* @desc Check if the component has a custom recurrence rule.
- * @returns true if the the recurrence rule requires the full recurrence editor
+ * @returns true if the recurrence rule requires the full recurrence editor
*/
Component.prototype.hasCustomRepeat = function() {
var b = angular.isDefined(this.repeat) &&
@@ -322,6 +325,19 @@
return b;
};
+ /**
+ * @function enablePercentComplete
+ * @memberof Component.prototype
+ * @desc Check if the percent completion should be enabled with respect to the
+ * component's type and status.
+ * @returns true if the percent completion should be displayed
+ */
+ Component.prototype.enablePercentComplete = function() {
+ return (this.component = 'vtodo' &&
+ this.status != 'not-specified' &&
+ this.status != 'cancelled');
+ };
+
/**
* @function coversFreeBusy
* @memberof Component.prototype
diff --git a/UI/WebServerResources/js/Scheduler/ComponentController.js b/UI/WebServerResources/js/Scheduler/ComponentController.js
index 2505ce9d2..170f7286a 100644
--- a/UI/WebServerResources/js/Scheduler/ComponentController.js
+++ b/UI/WebServerResources/js/Scheduler/ComponentController.js
@@ -11,11 +11,11 @@
var vm = this;
vm.calendars = stateCalendars;
- vm.event = stateComponent;
+ vm.component = stateComponent;
vm.categories = {};
- vm.showRecurrenceEditor = vm.event.$hasCustomRepeat;
+ vm.showRecurrenceEditor = vm.component.$hasCustomRepeat;
vm.toggleRecurrenceEditor = toggleRecurrenceEditor;
- vm.showAttendeesEditor = angular.isDefined(vm.event.attendees);
+ vm.showAttendeesEditor = angular.isDefined(vm.component.attendees);
vm.toggleAttendeesEditor = toggleAttendeesEditor;
vm.cardFilter = cardFilter;
vm.cardResults = [];
@@ -23,8 +23,8 @@
vm.cancel = cancel;
vm.save = save;
vm.attendeesEditor = {
- startDate: vm.event.startDate,
- endDate: vm.event.endDate,
+ startDate: vm.component.startDate,
+ endDate: vm.component.endDate,
days: getDays(),
hours: getHours()
};
@@ -47,21 +47,21 @@
}, 100); // don't ask why
});
- $scope.$watch('editor.event.startDate', function(newStartDate, oldStartDate) {
+ $scope.$watch('editor.component.startDate', function(newStartDate, oldStartDate) {
if (newStartDate) {
$timeout(function() {
- vm.event.start = new Date(newStartDate.substring(0,10) + ' ' + newStartDate.substring(11,16));
- vm.event.freebusy = vm.event.updateFreeBusyCoverage();
+ vm.component.start = new Date(newStartDate.substring(0,10) + ' ' + newStartDate.substring(11,16));
+ vm.component.freebusy = vm.component.updateFreeBusyCoverage();
vm.attendeesEditor.days = getDays();
});
}
});
- $scope.$watch('editor.event.endDate', function(newEndDate, oldEndDate) {
+ $scope.$watch('editor.component.endDate', function(newEndDate, oldEndDate) {
if (newEndDate) {
$timeout(function() {
- vm.event.end = new Date(newEndDate.substring(0,10) + ' ' + newEndDate.substring(11,16));
- vm.event.freebusy = vm.event.updateFreeBusyCoverage();
+ vm.component.end = new Date(newEndDate.substring(0,10) + ' ' + newEndDate.substring(11,16));
+ vm.component.freebusy = vm.component.updateFreeBusyCoverage();
vm.attendeesEditor.days = getDays();
});
}
@@ -69,7 +69,7 @@
function toggleRecurrenceEditor() {
vm.showRecurrenceEditor = !vm.showRecurrenceEditor;
- vm.event.$hasCustomRepeat = vm.showRecurrenceEditor;
+ vm.component.$hasCustomRepeat = vm.showRecurrenceEditor;
}
function toggleAttendeesEditor() {
@@ -98,7 +98,7 @@
}
_.each(results, function(card) {
// Add cards matching the search query but not already in the list of attendees
- if (!vm.event.hasAttendee(card))
+ if (!vm.component.hasAttendee(card))
vm.cardResults.push(card);
});
});
@@ -110,18 +110,18 @@
if (angular.isString(card)) {
// User pressed "Enter" in search field, adding a non-matching card
if (card.isValidEmail()) {
- vm.event.addAttendee(new Card({ emails: [{ value: card }] }));
+ vm.component.addAttendee(new Card({ emails: [{ value: card }] }));
vm.searchText = '';
}
}
else {
- vm.event.addAttendee(card);
+ vm.component.addAttendee(card);
}
}
function save(form) {
if (form.$valid) {
- vm.event.$save()
+ vm.component.$save()
.then(function(data) {
$scope.$emit('calendars:list');
$mdSidenav('right').close();
@@ -132,10 +132,10 @@
}
function cancel() {
- vm.event.$reset();
- if (vm.event.isNew) {
+ vm.component.$reset();
+ if (vm.component.isNew) {
// Cancelling the creation of a component
- vm.event = null;
+ vm.component = null;
}
$mdSidenav('right').close();
}
@@ -143,8 +143,8 @@
function getDays() {
var days = [];
- if (vm.event.start && vm.event.end)
- days = vm.event.start.daysUpTo(vm.event.end);
+ if (vm.component.start && vm.component.end)
+ days = vm.component.start.daysUpTo(vm.component.end);
return _.map(days, function(date) {
return { stringWithSeparator: date.stringWithSeparator(),