Review task/event viewer/editor

Components will now appear in dialogs instead of a right sidenav.

This commit also introduces read-only viewers for tasks and events.
This commit is contained in:
Francis Lachapelle
2015-07-21 08:29:28 -04:00
parent 5eeb473fe8
commit a75524af9f
15 changed files with 530 additions and 251 deletions
+22
View File
@@ -329,6 +329,24 @@
@end
/* Appointment Viewer */
@interface UIxAppointmentViewTemplate : UIxComponent
@end
@implementation UIxAppointmentViewTemplate
@end
/* Task Viewer */
@interface UIxTaskViewTemplate : UIxComponent
@end
@implementation UIxTaskViewTemplate
@end
/* Component Editor, parent class of Appointment Editor and Task Editor */
@interface UIxComponentEditorTemplate : UIxComponent
{
id item;
@@ -388,12 +406,16 @@
@end
/* Appointment Editor */
@interface UIxAppointmentEditorTemplate : UIxComponentEditorTemplate
@end
@implementation UIxAppointmentEditorTemplate
@end
/* Task Editor */
@interface UIxTaskEditorTemplate : UIxComponentEditorTemplate
@end
+2 -1
View File
@@ -433,7 +433,8 @@
* @apiSuccess (Success 200) {String} location Location
* @apiSuccess (Success 200) {String} comment Comment
* @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
* @apiSuccess (Success 200) {Number} priority Priority (0-9)
* @apiSuccess (Success 200) {NSString} [classification] Either public, confidential or private
* @apiSuccess (Success 200) {String[]} [categories] Categories
* @apiSuccess (Success 200) {String} status Status (needs-action, in-process, completed, or cancelled)
* @apiSuccess (Success 200) {Object} [organizer] Appointment organizer
@@ -21,7 +21,7 @@
<h1 class="sg-md-display-2--light" ng-bind-html="editor.card.$fullname()"><!-- fullname --></h1>
<h6 class="sg-md-display-2-subheader">{{editor.card.$description()}}</h6>
<md-chips ng-model="editor.card.categories"
readonly="true">
class="sg-readonly" readonly="true">
<md-chip-template>
{{$chip.value}}
</md-chip-template>
@@ -3,44 +3,48 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
<form name="eventForm" ng-submit="editor.save(eventForm)">
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
<!-- summary -->
<md-input-container md-no-float="true">
<input type="text"
class="md-display-1"
label:placeholder="Title"
ng-model="editor.component.summary"
md-sidenav-focus="md-sidenav-focus" />
</md-input-container>
xmlns:label="OGo:label">
<md-dialog flex="60">
<form name="eventForm" ng-submit="editor.save(eventForm)">
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
<div class="md-toolbar-tools">
<!-- summary -->
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
<md-input-container md-no-float="true">
<input type="text"
class="md-title"
label:placeholder="Title"
ng-model="editor.component.summary"/>
</md-input-container>
<md-button class="md-icon-button" ng-click="editor.cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<!--<md-chips>
<md-chip ng-repeat="category in editor.component.categories">{{category}}</md-chip>
</md-chips>-->
</md-toolbar>
<md-content md-scroll-y="md-scroll-y" class="md-padding bg-sogoPaper-50 md-whiteframe-z1">
<md-dialog-content>
<!-- location -->
<md-input-container>
<label><var:string label:value="Location"/></label>
<input type="text" ng-model="editor.component.location"/>
</md-input-container>
<!-- categories -->
<div class="pseudo-input-container">
<md-chips ng-model="editor.component.categories">
<md-autocomplete
md-selected-item="editor.categories.selected"
md-search-text="editor.categories.searchText"
md-items="category in editor.component.constructor.filterCategories(editor.categories.searchText)"
label:placeholder="Add a category">
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
</md-autocomplete>
</md-chips>
</div>
<md-chips ng-model="editor.component.categories">
<md-autocomplete
md-selected-item="editor.categories.selected"
md-search-text="editor.categories.searchText"
md-items="category in editor.component.constructor.filterCategories(editor.categories.searchText)"
label:placeholder="Add a category">
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
</md-autocomplete>
</md-chips>
<!-- calendar -->
<md-input-container>
<label><var:string label:value="Calendar"/></label>
<md-select ng-model="editor.component.destinationCalendar" class="pseudo-input-field">
<md-select ng-model="editor.component.destinationCalendar">
<md-option ng-repeat="calendar in ::editor.calendars"
ng-value="calendar.id">{{calendar.name}}</md-option>
</md-select>
@@ -137,7 +141,7 @@
<div class="md-flex">
<md-input-container>
<label><var:string label:value="Repeat"/></label>
<md-select class="pseudo-input-field" ng-model="editor.component.repeat.frequency">
<md-select ng-model="editor.component.repeat.frequency">
<var:foreach list="repeatList" item="item">
<md-option var:value="item"><var:string var:value="itemRepeatText"/></md-option>
</var:foreach>
@@ -159,7 +163,7 @@
<div ng-show="editor.component.repeat.frequency != 'never'">
<md-input-container>
<label><var:string label:value="End Repeat"/></label>
<md-select class="pseudo-input-field" ng-model="editor.component.repeat.end">
<md-select ng-model="editor.component.repeat.end">
<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>
@@ -226,8 +230,9 @@
ng-show="editor.component.$hasAlarm">
<var:component className="UIxReminderEditor" />
</div>
</md-dialog-content>
<!-- cancel/reset/save -->
<div class="fieldset md-layout-margin" layout="row" layout-align="end center">
<div class="md-actions">
<md-button type="button" ng-click="editor.cancel()">
<var:string label:value="Cancel"/>
</md-button>
@@ -238,6 +243,6 @@
<var:string label:value="Save"/>
</md-button>
</div>
</md-content>
</form>
</md-dialog>
</container>
@@ -0,0 +1,123 @@
<?xml version='1.0' standalone='yes'?>
<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label">
<md-dialog flex="40">
<form name="eventForm" ng-submit="viewer.save(eventForm)">
<md-toolbar class="md-padding" ng-class="viewer.component.getClassName('bg')">
<div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">event</md-icon>
<h2 class="md-flex">
<!-- classification -->
<md-icon ng-if="viewer.component.classification == 'confidential'">visibility_off</md-icon>
<md-icon ng-if="viewer.component.classification == 'private'">vpn_key</md-icon>
<!-- summary -->
{{viewer.component.summary}}
<!-- priority -->
<md-icon ng-repeat="i in viewer.component.priority | range">star</md-icon>
</h2>
<md-button class="md-icon-button" ng-click="viewer.close()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<md-list>
<!-- categories -->
<md-list-item ng-show="viewer.component.categories.length > 0">
<md-chips class="sg-readonly" ng-model="viewer.component.categories" readonly="true">
<md-chip-template>
<span>{{$chip}}</span>
</md-chip-template>
</md-chips>
</md-list-item>
<!-- location -->
<md-list-item ng-show="viewer.component.location">
<md-icon>place</md-icon>
<p>{{viewer.component.location}}</p>
</md-list-item>
<!-- calendar -->
<md-list-item>
<md-icon>event</md-icon>
<p>{{viewer.component.calendar}}</p>
</md-list-item>
<!-- start/end dates -->
<md-list-item class="md-2-line">
<md-icon>access_time</md-icon>
<div layout="row" class="md-flex">
<div class="md-list-item-text" ng-show="viewer.component.startDate">
<p><var:string label:value="Start:"/></p>
<h3>
{{viewer.component.localizedStartDate}}
<span ng-hide="viewer.component.isAllDay"> {{viewer.component.localizedStartTime}}</span>
</h3>
</div>
<div class="md-list-item-text" ng-show="viewer.component.endDate">
<p><var:string label:value="End:"/></p>
<h3>
{{viewer.component.localizedEndDate}}
<span ng-hide="viewer.component.isAllDay">{{viewer.component.localizedEndTime}}</span>
</h3>
</div>
</div>
</md-list-item>
<!-- is transparent -->
<md-list-item ng-show="viewer.component.isTransparent">
<md-icon>event_available</md-icon>
<p><var:string label:value="Show Time as Free"/></p>
</md-list-item>
<!-- send appointment notifications -->
<md-list-item ng-show="viewer.component.sendAppointmentNotifications">
<md-icon>send</md-icon>
<p><var:string label:value="Send Appointment Notifications"/></p>
</md-list-item>
<!-- attach urls -->
<md-list-item ng-show="viewer.component.attachUrls.length > 0">
<md-icon>link</md-icon>
<p ng-repeat="url in viewer.component.attachUrls"><a ng-href="{{url.value}}">{{url.value}}</a></p>
</md-list-item>
<!-- comment -->
<md-list-item ng-show="viewer.component.comment">
<md-icon>mode_comment</md-icon>
<p>{{viewer.component.comment}}</p>
</md-list-item>
<!-- repeat -->
<md-list-item ng-show="viewer.component.repeat">
<md-icon>repeat</md-icon>
<p><!-- viewer.component.repeat.toString() --></p>
</md-list-item>
<!-- reminder -->
<md-list-item ng-show="viewer.component.$hasAlarm">
<md-icon>alarm</md-icon>
<p><!-- viewer.component.alarm.toString() --></p>
</md-list-item>
<!-- attendees -->
<md-list-item ng-show="viewer.component.attendees.length > 0">
<div class="pseudo-input-container">
<label class="pseudo-input-label"><var:string label:value="Attendees:"/></label>
<div class="sg-avatars">
<sg-gravatar-image ng-repeat="currentAttendee in viewer.component.attendees track by currentAttendee.email"
email="{{currentAttendee.email}}"
size="32">
<!-- gravatar -->
</sg-gravatar-image>
</div>
</div>
</md-list-item>
</md-list>
<!-- attendees -->
<div ng-show="viewer.showAttendeesEditor" class="sg-subcontent attendees">
<var:component className="UIxAttendeesEditor" />
</div>
</md-dialog-content>
<!-- edit -->
<div class="md-actions">
<md-button type="button" ng-click="viewer.edit()">
<var:string label:value="Edit"/>
</md-button>
</div>
</form>
</md-dialog>
</container>
+72 -78
View File
@@ -180,29 +180,29 @@
md-menu-origin="md-menu-origin">more_vert</md-icon>
<md-menu-content width="2">
<md-menu-item>
<md-button type="button" ng-click="calendars.confirmDelete(calendar)">
<md-button ng-click="calendars.confirmDelete(calendar)">
<var:string label:value="Delete"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button type="button" ng-click="calendars.exportCalendar()">
<md-button ng-click="calendars.exportCalendar()">
<var:string label:value="Export"/>
</md-button>
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item>
<md-button type="button" ng-click="calendars.showLinks(calendar)">
<md-button ng-click="calendars.showLinks(calendar)">
<var:string label:value="Links to this Calendar"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button type="button" ng-click="calendars.share(calendar)">
<md-button ng-click="calendars.share(calendar)">
<var:string label:value="Sharing..."/>
</md-button>
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item>
<md-button type="button" ng-click="calendars.showProperties(calendar)">
<md-button ng-click="calendars.showProperties(calendar)">
<var:string label:value="Properties"/>
</md-button>
</md-menu-item>
@@ -238,19 +238,19 @@
md-menu-origin="md-menu-origin">more_vert</md-icon>
<md-menu-content width="2">
<md-menu-item>
<md-button type="button" ng-click="calendars.confirmDelete(calendar)">
<md-button ng-click="calendars.confirmDelete(calendar)">
<var:string label:value="Unsubscribe Calendar"/>
</md-button>
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item>
<md-button type="button" ng-click="calendars.showLinks(calendar)">
<md-button ng-click="calendars.showLinks(calendar)">
<var:string label:value="Links to this Calendar"/>
</md-button>
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item>
<md-button type="button" ng-click="calendars.showProperties(calendar)">
<md-button ng-click="calendars.showProperties(calendar)">
<var:string label:value="Properties"/>
</md-button>
</md-menu-item>
@@ -285,19 +285,19 @@
md-menu-origin="md-menu-origin">more_vert</md-icon>
<md-menu-content width="2">
<md-menu-item>
<md-button type="button" ng-click="calendars.confirmDelete(calendar)">
<md-button ng-click="calendars.confirmDelete(calendar)">
<var:string label:value="Delete"/>
</md-button>
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item>
<md-button type="button" ng-click="calendars.showLinks(calendar)">
<md-button ng-click="calendars.showLinks(calendar)">
<var:string label:value="Links to this Calendar"/>
</md-button>
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item>
<md-button type="button" ng-click="calendars.showProperties(calendar)">
<md-button ng-click="calendars.showProperties(calendar)">
<var:string label:value="Properties"/>
</md-button>
</md-menu-item>
@@ -321,7 +321,7 @@
</md-button>
</div>
</div><!-- .md-toolbar-tools -->
<div class="md-toolbar-tools md-toolbar-tools-bottom" layout="row" layout-align="space-between center">
<div class="md-toolbar-tools" layout="row" layout-align="space-between center">
<!-- sort/filter mode -->
<div class="view-list" layout="row" layout-align="space-between center"
ng-hide="list.mode.search">
@@ -383,25 +383,25 @@
<md-menu-item ng-if="list.componentType == 'events'">
<md-button ng-click="list.filter('view_selectedday')">
<md-icon ng-class="{ 'icon-check': list.component.$queryEvents.filterpopup == 'view_selectedday' }">
<!-- selected --></md-icon><var:string label:value="view_selectedday"/>
<!-- selected --></md-icon> <var:string label:value="view_selectedday"/>
</md-button>
</md-menu-item>
<md-menu-item ng-if="list.componentType == 'tasks'">
<md-button ng-click="list.filter('view_not_started')">
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_not_started' }">
<!-- selected --></md-icon><var:string label:value="view_not_started"/>
<!-- selected --></md-icon> <var:string label:value="view_not_started"/>
</md-button>
</md-menu-item>
<md-menu-item ng-if="list.componentType == 'tasks'">
<md-button ng-click="list.filter('view_overdue')">
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_overdue' }">
<!-- selected --></md-icon><var:string label:value="view_overdue"/>
<!-- selected --></md-icon> <var:string label:value="view_overdue"/>
</md-button>
</md-menu-item>
<md-menu-item ng-if="list.componentType == 'tasks'">
<md-button ng-click="list.filter('view_incomplete')">
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_incomplete' }">
<!-- selected --></md-icon><var:string label:value="view_incomplete"/>
<!-- selected --></md-icon> <var:string label:value="view_incomplete"/>
</md-button>
</md-menu-item>
<md-menu-divider ng-if="list.componentType == 'tasks'"><!-- divider --></md-menu-divider>
@@ -410,7 +410,7 @@
<md-checkbox
ng-model="list.component.$queryTasks.show_completed"
ng-true-value="1"
ng-false-value="0"><var:string label:value="Show completed tasks"/></md-checkbox>
ng-false-value="0"> <var:string label:value="Show completed tasks"/></md-checkbox>
</md-button>
</md-menu-item>
</md-menu-content>
@@ -530,77 +530,71 @@
</div>
</md-toolbar>
<md-content layout="row" class="md-flex">
<div class="view-list md-flex" layout="column" style="position: relative;">
<md-content id="componentsList">
<md-tabs md-dynamic-height="true"
md-selected="list.selectedList">
<md-tab label:label="Events"
md-on-select="list.selectComponentType('events')">
<md-list>
<md-list-item class="md-clickable md-2-line"
ng-repeat="event in list.component.$events">
<i class="md-avatar" ng-class="event.getClassName('bg')" ><!-- calendar color --></i>
<div class="md-list-item-text"
ui-sref="calendars.component({calendarId: event.c_folder,
componentType: 'appointment',
componentId: event.c_name})">
<h3>{{event.c_title}}</h3>
<p>{{event.c_location}}</p>
<p class="md-secondary" layout="row">
{{event.formatted_startdate}}
<span class="sg-tile-icons">
<md-icon ng-show="event.c_iscycle">repeat</md-icon>
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
</span>
</p>
</div>
</md-list-item>
<md-list-item ng-if="list.component.$events.length == 0">
<p class="sg-md-caption"><var:string label:value="No events for selected criteria"/></p>
</md-list-item>
</md-list>
</md-tab>
<md-tab label:label="Tasks"
md-on-select="list.selectComponentType('tasks')">
<md-list>
<md-list-item class="md-clickable md-2-line"
ng-repeat="task in list.component.$tasks">
<i class="md-avatar" ng-class="task.getClassName('bg')" ><!-- calendar color --></i>
<div class="md-list-item-text"
ui-sref="calendars.component({calendarId: task.c_folder,
componentType: 'task',
componentId: task.c_name})">
<h3>{{task.c_title}}</h3>
<p class="md-secondary" layout="row">
{{task.formatted_enddate}}
<span class="sg-tile-icons">
<md-icon ng-show="task.c_iscycle">repeat</md-icon>
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
</span>
</p>
</div>
</md-list-item>
<md-list-item ng-if="list.component.$tasks.length == 0">
<p class="sg-md-caption"><var:string label:value="No tasks for selected criteria"/></p>
</md-list-item>
</md-list>
</md-tab>
</md-tabs>
</md-content>
<md-content class="view-list md-flex" layout="column">
<md-tabs md-dynamic-height="true"
md-selected="list.selectedList">
<!-- Events list -->
<md-tab label:label="Events"
md-on-select="list.selectComponentType('events')">
<md-list>
<md-list-item class="md-clickable md-2-line"
ng-repeat="event in list.component.$events"
ng-click="list.openEvent($event, event)">
<i class="md-avatar" ng-class="event.getClassName('bg')" ><!-- calendar color --></i>
<div class="md-list-item-text">
<h3>{{event.c_title}}</h3>
<p>{{event.c_location}}</p>
<p class="md-secondary" layout="row">
{{event.formatted_startdate}}
<span class="sg-tile-icons">
<md-icon ng-show="event.c_iscycle">repeat</md-icon>
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
</span>
</p>
</div>
</md-list-item>
<md-list-item ng-if="list.component.$events.length == 0">
<p class="sg-md-caption"><var:string label:value="No events for selected criteria"/></p>
</md-list-item>
</md-list>
</md-tab>
<!-- Tasks list -->
<md-tab label:label="Tasks"
md-on-select="list.selectComponentType('tasks')">
<md-list>
<md-list-item class="md-clickable md-2-line"
ng-repeat="task in list.component.$tasks"
ng-click="list.openTask($event, task)">
<i class="md-avatar" ng-class="task.getClassName('bg')" ><!-- calendar color --></i>
<div class="md-list-item-text">
<h3>{{task.c_title}}</h3>
<p class="md-secondary" layout="row">
{{task.formatted_enddate}}
<span class="sg-tile-icons">
<md-icon ng-show="task.c_iscycle">repeat</md-icon>
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
</span>
</p>
</div>
</md-list-item>
<md-list-item ng-if="list.component.$tasks.length == 0">
<p class="sg-md-caption"><var:string label:value="No tasks for selected criteria"/></p>
</md-list-item>
</md-list>
</md-tab>
</md-tabs>
<md-button class="md-fab md-fab-bottom-right md-accent hide-sm"
label:aria-label="New Appointment"
ng-click="list.newComponent()">
ng-click="list.newComponent($event)">
<md-icon>add</md-icon>
</md-button>
</div>
</md-content>
<md-content class="view-detail sg-padded" ui-view="calendarView"><!-- calendar view --></md-content>
</md-content>
<md-sidenav class="md-sidenav-right" md-component-id="right" layout="column" ui-view="componentEditor"><!-- appointment editor view --><!--<var:component className="UIxAppointmentEditorTemplate" />--></md-sidenav>
</section>
</script>
<script type="text/ng-template" id="UIxUserRightsEditor">
<var:component className="UIxCalUserRightsEditor" />
</script>
</var:component>
@@ -3,8 +3,7 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
xmlns:label="OGo:label">
<div layout="row" layout-align="start center">
<md-input-container class="md-input-number">
<input type="number" label:aria-label="quantity" ng-model="editor.component.alarm.quantity"/>
@@ -3,40 +3,45 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
<form name="eventForm" ng-submit="editor.save(eventForm)">
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
<!-- summary -->
<md-input-container md-no-float="true">
<input type="text"
class="md-display-1"
label:placeholder="Title"
ng-model="editor.component.summary"/>
</md-input-container>
</md-toolbar>
<md-content md-scroll-y="md-scroll-y" class="md-padding bg-sogoPaper-50 md-whiteframe-z1">
xmlns:label="OGo:label">
<md-dialog flex="60">
<form name="eventForm" ng-submit="editor.save(eventForm)">
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
<div class="md-toolbar-tools">
<!-- summary -->
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
<md-input-container md-no-float="true">
<input type="text"
class="md-title"
label:placeholder="Title"
ng-model="editor.component.summary"/>
</md-input-container>
<md-button class="md-icon-button" ng-click="editor.cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<!-- location -->
<md-input-container>
<label><var:string label:value="Location"/></label>
<input type="text" ng-model="editor.component.location"/>
</md-input-container>
<!-- categories -->
<div class="pseudo-input-container">
<md-chips ng-model="editor.component.categories">
<md-autocomplete
md-selected-item="editor.categories.selected"
md-search-text="editor.categories.searchText"
md-items="category in editor.component.constructor.filterCategories(editor.categories.searchText)"
label:placeholder="Add a category">
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
</md-autocomplete>
</md-chips>
</div>
<md-chips ng-model="editor.component.categories">
<md-autocomplete
md-selected-item="editor.categories.selected"
md-search-text="editor.categories.searchText"
md-items="category in editor.component.constructor.filterCategories(editor.categories.searchText)"
label:placeholder="Add a category">
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
</md-autocomplete>
</md-chips>
<!-- calendar -->
<md-input-container>
<label><var:string label:value="Calendar"/></label>
<md-select ng-model="editor.component.destinationCalendar" class="pseudo-input-field">
<md-select ng-model="editor.component.destinationCalendar">
<md-option ng-repeat="calendar in ::editor.calendars"
ng-value="calendar.id">{{calendar.name}}</md-option>
</md-select>
@@ -86,14 +91,14 @@
</div>
<!-- status -->
<div layout="row">
<div class="pseudo-input-container" flex="50">
<label class="pseudo-input-label"><var:string label:value="Status"/></label>
<md-input-container flex="50">
<label><var:string label:value="Status"/></label>
<md-select ng-model="editor.component.status">
<var:foreach list="statusList" item="item">
<md-option var:value="item"><var:string value="itemStatusText"/></md-option>
</var:foreach>
</md-select>
</div>
</md-input-container>
<md-input-container ng-show="editor.component.status == 'completed'">
<label><var:string label:value="status_COMPLETED"/></label>
<input type="text" ng-model="editor.component.completedDate"/>
@@ -108,7 +113,7 @@
min="0"
max="100"
label:aria-label="% complete"><!-- slider --></md-slider>
<div flex="30"><var:string label:value="% complete"/></div>
<div flex="30">{{editor.component.percentComplete}} <var:string label:value="% complete"/></div>
</div>
<!-- attach urls -->
<div class="attr" ng-repeat="attach in editor.component.attachUrls">
@@ -192,18 +197,19 @@
ng-show="editor.component.$hasAlarm">
<var:component className="UIxReminderEditor" />
</div>
<!-- cancel/reset/save -->
<div class="fieldset md-layout-margin" layout="row" layout-align="end center">
<md-button type="button" ng-click="editor.cancel()">
<var:string label:value="Cancel"/>
</md-button>
<md-button type="button" ng-click="editor.component.$reset()">
<var:string label:value="Reset"/>
</md-button>
<md-button class="md-primary md-hue-3" type="submit">
<var:string label:value="Save"/>
</md-button>
</div>
</md-content>
</md-dialog-content>
<!-- cancel/reset/save -->
<div class="md-actions">
<md-button type="button" ng-click="editor.cancel()">
<var:string label:value="Cancel"/>
</md-button>
<md-button type="button" ng-click="editor.component.$reset()">
<var:string label:value="Reset"/>
</md-button>
<md-button class="md-primary md-hue-3" type="submit">
<var:string label:value="Save"/>
</md-button>
</div>
</form>
</md-dialog>
</container>
@@ -0,0 +1,103 @@
<?xml version='1.0' standalone='yes'?>
<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label">
<md-dialog flex="40">
<md-toolbar class="md-padding" ng-class="viewer.component.getClassName('bg')">
<div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">assignment_turned_in</md-icon>
<h2 class="md-flex">
<!-- classification -->
<md-icon ng-if="viewer.component.classification == 'confidential'">visibility_off</md-icon>
<md-icon ng-if="viewer.component.classification == 'private'">vpn_key</md-icon>
<!-- summary -->
{{viewer.component.summary}}
<!-- priority -->
<md-icon ng-repeat="i in viewer.component.priority | range">star</md-icon>
</h2>
<md-button class="md-icon-button" ng-click="viewer.close()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<md-list>
<!-- categories -->
<md-list-item ng-show="viewer.component.categories.length > 0">
<md-chips ng-model="viewer.component.categories" readonly="true">
<md-chip-template>
<span>{{$chip}}</span>
</md-chip-template>
</md-chips>
</md-list-item>
<!-- location -->
<md-list-item ng-show="viewer.component.location">
<md-icon>place</md-icon>
<p>{{viewer.component.location}}</p>
</md-list-item>
<!-- calendar -->
<md-list-item>
<md-icon>event</md-icon>
<p>{{viewer.component.calendar}}</p>
</md-list-item>
<!-- start/due dates -->
<md-list-item class="md-2-line">
<md-icon>access_time</md-icon>
<div layout="row" class="md-flex">
<div class="md-list-item-text" ng-show="viewer.component.startDate">
<p><var:string label:value="Start:"/></p>
<h3>
{{viewer.component.localizedStartDate}}
<span ng-hide="viewer.component.isAllDay"> {{viewer.component.localizedStartTime}}</span>
</h3>
</div>
<div class="md-list-item-text" ng-show="viewer.component.dueDate">
<p><var:string label:value="Due Date:"/></p>
<h3>
{{viewer.component.localizedDueDate}}
<span ng-hide="viewer.component.isAllDay">{{viewer.component.localizedDueTime}}</span>
</h3>
</div>
</div>
</md-list-item>
<!-- status -->
<md-list-item ng-show="viewer.component.status == 'completed'">
<md-icon>check</md-icon>
<p>{{viewer.component.localizedCompletedDate}} {{viewer.component.localizedCompletedTime}}</p>
</md-list-item>
<md-list-item ng-show="viewer.component.enablePercentComplete()">
<md-icon>call_made</md-icon>
<p>{{viewer.component.percentComplete}} %</p>
</md-list-item>
<!-- attach urls -->
<md-list-item ng-show="viewer.component.attachUrls.length > 0">
<md-icon>link</md-icon>
<p ng-repeat="url in viewer.component.attachUrls"><a ng-href="url.value">{{url.value}}</a></p>
</md-list-item>
<!-- comment -->
<md-list-item ng-show="viewer.component.comment">
<md-icon>mode_comment</md-icon>
<p>{{viewer.component.comment}}</p>
</md-list-item>
<!-- repeat -->
<md-list-item ng-show="viewer.component.repeat">
<md-icon>repeat</md-icon>
<p><!-- viewer.component.repeat.toString() --></p>
</md-list-item>
<!-- reminder -->
<md-list-item ng-show="viewer.component.$hasAlarm">
<md-icon>alarm</md-icon>
<p><!-- viewer.component.alarm.toString() --></p>
</md-list-item>
</md-list>
</md-dialog-content>
<!-- edit -->
<div class="md-actions">
<md-button ng-click="viewer.edit()">
<var:string label:value="Edit"/>
</md-button>
</div>
</md-dialog>
</container>
-63
View File
@@ -61,46 +61,6 @@
resolve: {
stateEventsBlocks: stateEventsBlocks
}
})
.state('calendars.newComponent', {
url: '/:calendarId/{componentType:(?:appointment|task)}/new',
views: {
componentEditor: {
templateUrl: function($stateParams) {
// UI/Templates/SchedulerUI/UIxAppointmentEditorTemplate.wox or
// UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
return 'UIx' + $stateParams.componentType.capitalize() + 'EditorTemplate';
},
controller: 'ComponentController',
controllerAs: 'editor'
}
},
resolve: {
stateComponent: stateNewComponent
}
})
.state('calendars.component', {
url: '/:calendarId/{componentType:(?:appointment|task)}/:componentId',
views: {
componentEditor: {
templateUrl: function($stateParams) {
// UI/Templates/SchedulerUI/UIxAppointmentEditorTemplate.wox or
// UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
return 'UIx' + $stateParams.componentType.capitalize() + 'EditorTemplate';
},
controller: 'ComponentController',
controllerAs: 'editor'
}
},
// onEnter: ['$mdSidenav', function($mdSidenav) {
// $mdSidenav('right').open()
// .then(function() {
// console.debug("toggle RIGHT is done");
// });
// }],
resolve: {
stateComponent: stateComponent
}
});
$urlRouterProvider.when('/calendar/day', function() {
@@ -139,29 +99,6 @@
return Component.$eventsBlocksForView($stateParams.view, $stateParams.day.asDate());
}
/**
* @ngInject
*/
stateNewComponent.$inject = ['$stateParams', 'Component'];
function stateNewComponent($stateParams, Component) {
var component = new Component({ pid: $stateParams.calendarId, type: $stateParams.componentType });
return component;
}
/**
* @ngInject
*/
stateComponent.$inject = ['$q', '$stateParams', 'Calendar'];
function stateComponent($q, $stateParams, Calendar) {
var component = Calendar.$get($stateParams.calendarId).$getComponent($stateParams.componentId);
return $q(function(resolve, reject) {
component.$futureComponentData.then(function() {
resolve(component);
}, reject);
});
}
/**
* @ngInject
*/
@@ -6,14 +6,16 @@
/**
* @ngInject
*/
CalendarListController.$inject = ['$scope', '$rootScope', '$timeout', '$state', 'sgFocus', 'encodeUriFilter', 'Dialog', 'sgSettings', 'Preferences', 'Calendar', 'Component', '$mdSidenav'];
function CalendarListController($scope, $rootScope, $timeout, $state, focus, encodeUriFilter, Dialog, Settings, Preferences, Calendar, Component, $mdSidenav) {
CalendarListController.$inject = ['$scope', '$timeout', '$state', '$mdDialog', 'encodeUriFilter', 'Dialog', 'Preferences', 'Calendar', 'Component'];
function CalendarListController($scope, $timeout, $state, $mdDialog, encodeUriFilter, Dialog, Preferences, Calendar, Component) {
var vm = this;
vm.component = Component;
vm.componentType = 'events';
vm.selectedList = 0;
vm.selectComponentType = selectComponentType;
vm.openEvent = openEvent;
vm.openTask = openTask;
vm.newComponent = newComponent;
vm.filter = filter;
vm.filteredBy = filteredBy;
@@ -42,13 +44,54 @@
}
}
function newComponent() {
var type = 'appointment';
function openEvent($event, event) {
openComponent($event, event, 'appointment');
}
function openTask($event, task) {
openComponent($event, task, 'task');
}
function openComponent($event, component, type) {
// UI/Templates/SchedulerUI/UIxAppointmentViewTemplate.wox or
// UI/Templates/SchedulerUI/UIxTaskViewTemplate.wox
var templateUrl = 'UIx' + type.capitalize() + 'ViewTemplate';
$mdDialog.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: true,
escapeToClose: true,
templateUrl: templateUrl,
controller: 'ComponentController',
controllerAs: 'viewer',
locals: {
stateComponent: component
}
});
}
function newComponent($event) {
var type = 'appointment', component;
if (vm.componentType == 'tasks')
type = 'task';
component = new Component({ pid: 'personal', type: type });
$state.go('calendars.newComponent', { calendarId: 'personal', componentType: type });
// UI/Templates/SchedulerUI/UIxAppointmentEditorTemplate.wox or
// UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
var templateUrl = 'UIx' + type.capitalize() + 'EditorTemplate';
$mdDialog.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: true,
escapeToClose: true,
templateUrl: templateUrl,
controller: 'ComponentEditorController',
controllerAs: 'editor',
locals: {
stateComponent: component
}
});
}
function filter(filterpopup) {
@@ -6,11 +6,55 @@
/**
* @ngInject
*/
ComponentController.$inject = ['$scope', '$log', '$q', '$timeout', '$state', '$previousState', '$mdSidenav', '$mdDialog', 'User', 'Calendar', 'Component', 'AddressBook', 'Card', 'stateCalendars', 'stateComponent'];
function ComponentController($scope, $log, $q, $timeout, $state, $previousState, $mdSidenav, $mdDialog, User, Calendar, Component, AddressBook, Card, stateCalendars, stateComponent) {
var vm = this;
ComponentController.$inject = ['$mdDialog', 'Calendar', 'stateComponent'];
function ComponentController($mdDialog, Calendar, stateComponent) {
var vm = this, component;
vm.calendars = stateCalendars;
vm.component = stateComponent;
vm.close = close;
vm.edit = edit;
// Load all attributes of component
if (angular.isUndefined(vm.component.$futureComponentData)) {
component = Calendar.$get(vm.component.c_folder).$getComponent(vm.component.c_name);
component.$futureComponentData.then(function() {
vm.component = component;
});
}
function close() {
$mdDialog.hide();
}
function edit() {
var type = (vm.component.component == 'vevent')? 'Appointment':'Task';
$mdDialog.hide().then(function() {
// UI/Templates/SchedulerUI/UIxAppointmentEditorTemplate.wox or
// UI/Templates/SchedulerUI/UIxTaskEditorTemplate.wox
var templateUrl = 'UIx' + type + 'EditorTemplate';
$mdDialog.show({
parent: angular.element(document.body),
clickOutsideToClose: true,
escapeToClose: true,
templateUrl: templateUrl,
controller: 'ComponentEditorController',
controllerAs: 'editor',
locals: {
stateComponent: vm.component
}
});
});
}
}
/**
* @ngInject
*/
ComponentEditorController.$inject = ['$scope', '$log', '$timeout', '$mdDialog', 'User', 'Calendar', 'Component', 'AddressBook', 'Card', 'stateComponent'];
function ComponentEditorController($scope, $log, $timeout, $mdDialog, User, Calendar, Component, AddressBook, Card, stateComponent) {
var vm = this, component;
vm.calendars = Calendar.$calendars;
vm.component = stateComponent;
vm.categories = {};
vm.showRecurrenceEditor = vm.component.$hasCustomRepeat;
@@ -30,24 +74,6 @@
hours: getHours()
};
// Open sidenav when loading the view;
// Return to previous state when closing the sidenav.
$scope.$on('$viewContentLoaded', function(event) {
$timeout(function() {
$mdSidenav('right').open()
.then(function() {
$scope.$watch($mdSidenav('right').isOpen, function(isOpen, wasOpen) {
if (!isOpen) {
if ($previousState.get())
$previousState.go()
else
$state.go('calendars');
}
});
});
}, 100); // don't ask why
});
$scope.$watch('editor.component.startDate', function(newStartDate, oldStartDate) {
if (newStartDate) {
$timeout(function() {
@@ -130,7 +156,7 @@
vm.component.$save()
.then(function(data) {
$scope.$emit('calendars:list');
$mdSidenav('right').close();
$mdDialog.hide();
}, function(data, status) {
$log.debug('failed');
});
@@ -143,7 +169,7 @@
// Cancelling the creation of a component
vm.component = null;
}
$mdSidenav('right').close();
$mdDialog.hide();
}
function getDays() {
@@ -170,5 +196,6 @@
angular
.module('SOGo.SchedulerUI')
.controller('ComponentController', ComponentController);
.controller('ComponentController', ComponentController)
.controller('ComponentEditorController', ComponentEditorController);
})();
@@ -2,13 +2,16 @@
@import 'extends';
// Remove the line under the tags of the message viewer
.msg-header {
md-chips {
md-chips {
&.sg-readonly {
.md-chips {
box-shadow: none;
&.md-focused {
box-shadow: none;
}
.md-chip-content {
max-width: initial; // fix bug in ng-material
}
}
}
}
@@ -45,6 +45,13 @@
// Define CSS styles to use ng-class with md-icon
md-icon {
transition: 240ms;
&.sg-icon-toolbar-bg {
font-size: 84px;
opacity: 0.2;
position: absolute;
right: $mg * 3;
transform: rotate(-15deg);
}
&.md-rotate-45 {
transform: rotate(45deg);
}
@@ -56,7 +63,10 @@ md-icon {
}
// &.icon-add:before {
// content: "\e317";
// }
// }
&.icon-alarm:before {
content: "\e855";
}
&.icon-check:before {
content: "\e5ca";
}
@@ -81,6 +91,12 @@ md-icon {
// &.icon_public:before {
// content: "\e80b";
// }
&.icon-visibility-off:before {
content: "\e8f5";
}
&.icon-vpn-key:before {
content: "\e0da";
}
}
// Message flag
@@ -46,7 +46,7 @@ md-list-item {
// Add some padding to the first icon in a list item
.md-list-item-inner {
> i:first-child {
padding-right: $mg;
margin-left: $mg;
}
}