]> err.no Git - scalable-opengroupware.org/commitdiff
Schedule view and associated functionality, work in progress
authorznek <znek@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Thu, 16 Dec 2004 19:52:40 +0000 (19:52 +0000)
committerznek <znek@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Thu, 16 Dec 2004 19:52:40 +0000 (19:52 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@477 d1b88da0-ebda-0310-925b-ed51d893ca5b

23 files changed:
OGoContentStore/ChangeLog
OGoContentStore/OCSiCalFieldExtractor.m
OGoContentStore/Version
SOGo/Main/ChangeLog
SOGo/Main/SOGoUserHomePage.m
SOGo/Main/Version
SOGo/SOGo.xcode/project.pbxproj
SOGo/SoObjects/Appointments/SOGoAppointmentFolder.m
SOGo/SoObjects/Appointments/Version
SOGo/SoObjects/ChangeLog
SOGo/UI/Common/ChangeLog
SOGo/UI/Common/Version
SOGo/UI/Common/calendar.css
SOGo/UI/Scheduler/ChangeLog
SOGo/UI/Scheduler/English.lproj/default.strings
SOGo/UI/Scheduler/GNUmakefile
SOGo/UI/Scheduler/UIxAppointmentEditor.m
SOGo/UI/Scheduler/UIxAppointmentView.m
SOGo/UI/Scheduler/UIxCalScheduleOverview.m [new file with mode: 0644]
SOGo/UI/Scheduler/UIxCalScheduleOverview.wox [new file with mode: 0644]
SOGo/UI/Scheduler/UIxCalSelectTab.m
SOGo/UI/Scheduler/UIxCalSelectTab.wox
SOGo/UI/Scheduler/product.plist

index a49c40a7a60eb8ebddcd32859a87b4847611afb1..fe5320fabff6ae3dfa03677cfff7915a36a97771 100644 (file)
@@ -1,3 +1,13 @@
+2004-12-15  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * OCSiCalFieldExtractor.m: partmails + cn's are concatenated by '\n'
+         now - this directly eliminates any ambiguities. Also, instead of
+         using 'email' for partmails and orgmail, the extractor uses the
+         'rfc822Email' value which strips away any preceeding 'mailto:'
+         prefix, compacting the representation and speeding up comparison.
+         Also, "iscycle", "isallday" and "isopaque" are now provided by
+         NGiCal and thus always extracted (v0.9.17)
+
 2004-12-13  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * sql/generate-folderinfo-sql-for-user.sh: fixed critical error in
index 81f76f17786bab6ae827a4fdeb20600ed7085c88..c1b9492f879deed3e8bf3b3dfa11b4aa2ba0ac72 100644 (file)
@@ -86,13 +86,11 @@ static OCSiCalFieldExtractor *extractor = nil;
   status       = [[_event status] uppercaseString];
 
   participants = [_event attendees];
-  partmails    = [participants valueForKey:@"email"];
-  partmails    = [partmails componentsJoinedByString:@""];
+  partmails    = [participants valueForKey:@"rfc822Email"];
+  partmails    = [partmails componentsJoinedByString:@"\n"];
   participants = [participants valueForKey:@"cn"];
-  participants = [participants componentsJoinedByString:@""];
+  participants = [participants componentsJoinedByString:@"\n"];
 
-  // TODO: cyclic/allday (not supported by NGiCal)
-  
   /* build row */
 
   row = [NSMutableDictionary dictionaryWithCapacity:8];
@@ -101,7 +99,14 @@ static OCSiCalFieldExtractor *extractor = nil;
     [row setObject:uid forKey:@"uid"];
   else
     [self logWithFormat:@"WARNING: could not extract a uid from event!"];
-  
+
+  [row setObject:[NSNumber numberWithBool:[_event isAllDay]]
+       forKey:@"isallday"];
+  [row setObject:[NSNumber numberWithBool:[_event isRecurrent]]
+       forKey:@"iscycle"];
+  [row setObject:[NSNumber numberWithBool:[_event isOpaque]]
+       forKey:@"isopaque"];
+
   if ([title    isNotNull]) [row setObject:title    forKey:@"title"];
   if ([location isNotNull]) [row setObject:location forKey:@"location"];
   if ([sequence isNotNull]) [row setObject:sequence forKey:@"sequence"];
@@ -137,14 +142,11 @@ static OCSiCalFieldExtractor *extractor = nil;
     [row setObject:[NSNumber numberWithBool:YES] forKey:@"ispublic"];
   }
 
-  // TODO: fix transparency when it's supported in iCalEvent
-  [row setObject:[NSNumber numberWithBool:NO] forKey:@"isopaque"];
-
   organizer = [_event organizer];
   if (organizer) {
       NSString *email;
       
-      email = [organizer valueForKey:@"email"];
+      email = [organizer valueForKey:@"rfc822Email"];
       if (email)
           [row setObject:email forKey:@"orgmail"];
   }
index c585d0f597a84e3ef0e2367744f0f5cffc7d7a4c..f48344243f60816736be5e01c78d581af4e39c66 100644 (file)
@@ -2,8 +2,9 @@
 
 MAJOR_VERSION=0
 MINOR_VERSION=9
-SUBMINOR_VERSION:=16
+SUBMINOR_VERSION:=17
 
+# v0.9.17 requires libNGiCal       v4.5.37
 # v0.9.11 requires libFoundation   v1.0.63
 # v0.9.11 requires libNGExtensions v4.3.125
 # v0.9.7  requires libGDLAccess    v1.1.35
index 3df83e9f14d8a03c10c05279b8a9aea9539f12f6..ab345bcf614ecd9ba23aeb15b181e02f18b0cc19 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-15  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * SOGoUserHomePage.m: added defaultAction to redirect to
+         "Calendar/" (v0.9.17)
+
 2004-12-08  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * SOGoProductLoader.m, sogod.m: changed to use NGLogging (v0.9.16)
index 941e2a29db29a72acf10347bc31eb0ce6e0c53fb..6b6a5d64456e5c9d5b0fb415567c819185865fc5 100644 (file)
   return [self relativePathToUserFolderSubPath:@"Mail/"];
 }
 
+/* actions */
+
+- (id)defaultAction {
+  return [self redirectToLocation:[self relativeCalendarPath]];
+}
+
 @end /* SOGoUserHomePage */
index 3b517c7b6a687e1d4009601936a63bf8bb178178..83dc54403d7e2ddd2da540ee377e055e29efa82d 100644 (file)
@@ -1,5 +1,5 @@
 # $Id$
 
-SUBMINOR_VERSION:=16
+SUBMINOR_VERSION:=17
 
 # v0.9.16 requires NGExtensions v4.5.136
index 9c9dbfaa145f7c53b6919e0658debd013a72e91b..3ea15f34dc827d7d676a4cf6a48d2129cf98fc86 100644 (file)
                        refType = 4;
                        sourceTree = "<group>";
                };
+               AD7BA88A0770A62B008F4F3D = {
+                       children = (
+                               AD7BA88D0770A67D008F4F3D,
+                               AD7BA88C0770A67D008F4F3D,
+                       );
+                       isa = PBXGroup;
+                       name = News;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               AD7BA88C0770A67D008F4F3D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.xml;
+                       path = UIxCalScheduleOverview.wox;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               AD7BA88D0770A67D008F4F3D = {
+                       fileEncoding = 5;
+                       indentWidth = 2;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = UIxCalScheduleOverview.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
                AD88394906EF807D00981A3E = {
                        fileEncoding = 5;
                        indentWidth = 2;
                                E87208FF0692E3D30099CBBD,
                                E87209040692E3D30099CBBD,
                                E87209050692E3D30099CBBD,
+                               AD7BA88A0770A62B008F4F3D,
                                AD0137A406DF8875000910D8,
                                AD73BEE206CFA17700226A2D,
                                ADE2C28F06B7C7EA0065D56F,
index 6a79ba3257d61c1cef507e503de4f190e3458612..a5371bff9df526381d713e72f45c6da06a1eebc7 100644 (file)
@@ -179,7 +179,7 @@ static NSTimeZone *MET = nil;
   to:(NSCalendarDate *)_endDate 
 {
   EOQualifier *qualifier;
-  NSArray     *fields, *records;
+  NSArray     *records;
   NSString    *sql;
   
   if (_folder == nil) {
@@ -444,8 +444,8 @@ static NSTimeZone *MET = nil;
 
   uri = [[_ctx request] uri];
   if (![uri hasSuffix:@"/"]) uri = [uri stringByAppendingString:@"/"];
-  uri = [uri stringByAppendingString:@"weekoverview"];
-  
+  uri = [uri stringByAppendingString:@"schedule"];
+
   r = [_ctx response];
   [r setStatus:302 /* moved */];
   [r setHeader:uri forKey:@"location"];
index 3fe6c4137fbc2eb6c05a57459f244695f62a560a..63f19036a23f9692404dde6128fc0c0242764ee3 100644 (file)
@@ -1,6 +1,6 @@
 # Version file
 
-SUBMINOR_VERSION:=20
+SUBMINOR_VERSION:=22
 
 # v0.9.19 requires NGiCal  v4.5.36
 # v0.9.13 requires libSOGo v0.9.26
index 8f7cb0ea55353a9e87b90be8394be6be47e9a3dc..9818b304b5e8d2a34c85ac4792bbed685381d794 100644 (file)
@@ -1,5 +1,10 @@
 2004-12-15  Marcus Mueller  <znek@mulle-kybernetik.com>
 
+       * Appointments/SOGoAppointmentFolder.m: default redirect is now
+         "schedule" instead of "weekoverview" (0.9.22)
+
+       * Appointments/SOGoAppointmentFolder.m: cleanup (v0.9.21)
+
        * Appointments/SOGoAppointmentFolder.m: compile fix (v0.9.20)
 
 2004-12-13  Marcus Mueller  <znek@mulle-kybernetik.com>
index 50966c620b4d3b43aba6529c8dc7cb45ed767bae..cce2575a973303f4b98a7eaae6f255e97ec67054 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-16  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * calendar.css: added CSS for "Schedule" (v0.9.31)
+
 2004-12-09  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * UIxPageFrame.[wox,m]: added -ownerInContext debug info (v0.9.30)
index cd3c0f2b2498d45d6375c0a1a766d20e74dbba47..d6d5bf5be5c239d53ce74c2f7748bad9d115528a 100644 (file)
@@ -1,5 +1,5 @@
 # Version file
 
-SUBMINOR_VERSION:=30
+SUBMINOR_VERSION:=31
 
 # v0.9.28 requires NGExtensions v4.5.136
index b3dda7eb9ff0e9c35b947d6f2b1b89cc408c0259..81ea3a6b5b334ef56306288a77f0fdcc1344e187 100644 (file)
 }
 
 
+/* schedule */
+
+.schedoverview {
+  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
+  letter-spacing:   0pt;
+  font-size:        10pt;
+}
+
+th.schedoverview_title {
+  font-size:        10pt;
+  font-weight:      bold;
+  text-align:       left;
+  background-color: #e8e8e0;
+  vertical-align:   top;
+}
+
+th.schedoverview {
+  font-size:        10pt;
+  font-weight:      bold;
+  text-align:       left;
+  vertical-align:   top;
+}
+
+td.schedoverview {
+  font-size:        10pt;
+  text-align:       left;
+  vertical-align:   top;
+}
+
+.schedoverview a {
+  color:            #000000;
+  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
+  font-size:        10pt;
+  letter-spacing:   0pt;
+  padding:          0px;
+  text-decoration:  none;
+}
+.schedoverview a:hover {
+  text-decoration:  underline;
+}
+
+
 /* day overview */
 
 .dayoverview_content {
index 3c8e469e883dfedb8cfee38ac4886bc4daaa773f..1284cce43bdcc453cfc5228842c578e9be08a9ea 100644 (file)
@@ -1,4 +1,25 @@
-2004-12-15  Marcus Mueller  <znek@mulle-kybernetik.com>
+2004-12-16  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * v0.9.103
+
+       * UIxCalScheduleOverview.[wox,m]: the entry point for agenor,
+         presenting the upcoming schedule to users. This is still incomplete,
+         but nevertheless functional.
+
+       * English.lproj/default.strings: new localizations for the schedule
+         view.
+
+       * product.plist: added new actions and schedule view
+
+       * UIxCalSelectTab.[wox,m]: added new "Schedule" tab
+
+       * UIxAppointmentEditor.m: default participants are selected from
+         current calendarUIDs - that is, if you've selected multiple calendars
+         and then create a new appointment, all currently viewed calendar
+         owners are added to the new appointment as default participants.
+
+       * UIxAppointmentView.m: added "accept" and "reject" actions - no
+         function yet.
 
        * UIxAppointmentProposal.m: compile fix (v0.9.102)
 
index a70917af0cafa0bb73873442f236513b243a2f83..fca12bbe9bc8afd5e63f9f9f3f41bb2f42006e73 100644 (file)
@@ -73,7 +73,7 @@
 /* Misc */
 
 "OpenGroupware.org"    = "OpenGroupware.org";
-
+"Forbidden"            = "Forbidden";
 
 /* Button titles */
 
 "Cancel"               = "Cancel";
 
 
+/* Schedule */
+
+"Schedule"             = "Schedule";
+"No appointments found" = "You don't have any appointments in the near future.";
+"Meetings proposed by you" = "Meetings proposed by you";
+"Meetings proposed to you" = "Meetings proposed to you";
+"sched_startDateFormat" = "%d.%m. %H:%M";
+"action"               = "Actions";
+"accept"               = "Accept";
+"reject"               = "Reject";
+
+
 /* Appointments */
 
 "Appointment viewer"   = "Appointment Viewer";
index 090c1911db761be3a4f0d79139f288e9d9d0e79c..ffd914f70776610d6e93a069c55b34a9c73baae1 100644 (file)
@@ -47,6 +47,7 @@ SchedulerUI_OBJC_FILES =              \
        UIxTimeSelector.m               \
        UIxTimeDateControl.m            \
        UIxCalInlineAptView.m           \
+       UIxCalScheduleOverview.m        \
 
 SchedulerUI_RESOURCE_FILES += \
        Version         \
@@ -79,6 +80,7 @@ SchedulerUI_RESOURCE_FILES +=         \
        UIxTimeSelector.wox             \
        UIxTimeDateControl.wox          \
        UIxCalInlineAptView.wox         \
+       UIxCalScheduleOverview.wox      \
 
 SchedulerUI_RESOURCE_FILES += \
        images/next_week.gif                    \
index cb7bb3b3ca78645a2e9dea8fc7a3f28bf0dd1de5..f595fa67c86d37ed1c1886b9bbc73e6f036300cc 100644 (file)
           Update: remember that there are group folders as well.
   */
   NSString *uri, *objectId, *method;
-  
+
   objectId = [NSClassFromString(@"SOGoAppointmentFolder")
                               globallyUniqueObjectId];
   if ([objectId length] == 0) {
   method = [NSString stringWithFormat:@"Calendar/%@/edit", objectId];
   method = [[self userFolderPath] stringByAppendingPathComponent:method];
 
+  /* add all current calendarUIDs as default participants */
+  if ([[self clientObject] respondsToSelector:@selector(calendarUIDs)]) {
+    AgenorUserManager *um;
+    NSArray           *uids;
+    NSMutableArray    *emails;
+    NSString          *ps;
+    unsigned          i, count;
+
+    um     = [AgenorUserManager sharedUserManager];
+    uids   = [[self clientObject] calendarUIDs];
+    count  = [uids count];
+    emails = [NSMutableArray arrayWithCapacity:count];
+    
+    for (i = 0; i < count; i++) {
+      NSString *email;
+      
+      email = [um getEmailForUID:[uids objectAtIndex:i]];
+      if (email)
+        [emails addObject:email];
+    }
+    ps = [emails componentsJoinedByString:@","];
+    [self setQueryParameter:ps forKey:@"ps"];
+  }
   uri = [self completeHrefForMethod:method];
   return [self redirectToLocation:uri];
 }
index 9346d7742c4d61d7a8ff56e18388a49c91f18487..44f9b9b1dc44569921f4b60c5bc000262456c900 100644 (file)
   return [self redirectToLocation:url];
 }
 
+- (id)acceptAction {
+  if ([self appointment] == nil) {
+    return [NSException exceptionWithHTTPStatus:404
+                        reason:@"could not locate appointment"];
+  }
+  return self;
+}
+
+- (id)rejectAction {
+  if ([self appointment] == nil) {
+    return [NSException exceptionWithHTTPStatus:404
+                                         reason:@"could not locate appointment"];
+  }
+  return self;
+}
+
 @end /* UIxAppointmentView */
diff --git a/SOGo/UI/Scheduler/UIxCalScheduleOverview.m b/SOGo/UI/Scheduler/UIxCalScheduleOverview.m
new file mode 100644 (file)
index 0000000..2736ba9
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ Copyright (C) 2004 SKYRIX Software AG
+ This file is part of OpenGroupware.org
+ OGo is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+ OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with OGo; see the file COPYING.  If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+ */
+
+#include <SOGoUI/UIxComponent.h>
+
+@class NSMutableArray;
+
+@interface UIxCalScheduleOverview : UIxComponent
+{
+  NSMutableArray *userApts;
+  NSMutableArray *foreignApts;
+  id             item;
+}
+
+- (NSCalendarDate *)startDate;
+- (NSCalendarDate *)endDate;
+
+- (NSArray *)userAppointments;
+- (NSArray *)foreignAppointments;
+
+- (BOOL)hasUserAppointments;
+- (BOOL)hasForeignAppointments;
+- (BOOL)hasAnyAppointments;
+
+- (void)fetchInfos;
+
+- (NSString *)appointmentBaseURL;
+
+@end
+
+#include <NGObjWeb/SoComponent.h>
+#include "UIxComponent+Agenor.h"
+#include "SoObjects/Appointments/SOGoAppointmentFolder.h"
+#include "common.h"
+
+@implementation UIxCalScheduleOverview
+
+- (void)dealloc {
+  [self->userApts    release];
+  [self->foreignApts release];
+  [self->item        release];
+  [super dealloc];
+}
+
+
+/* accessors */
+
+- (void)setItem:(id)_item {
+  ASSIGN(self->item, _item);
+}
+- (id)item {
+  return self->item;
+}
+
+- (BOOL)hasUserAppointments {
+  return [[self userAppointments] count] > 0;
+}
+- (BOOL)hasForeignAppointments {
+  return [[self foreignAppointments] count] > 0;
+}
+- (BOOL)hasAnyAppointments {
+  return ([self hasUserAppointments] ||
+          [self hasForeignAppointments]) ? YES : NO;
+}
+
+- (NSString *)participants {
+  NSString *s;
+  
+  s = [self->item valueForKey:@"participants"];
+  if (!s)
+    return @"";
+  if ([s length] > 100)
+    s = [NSString stringWithFormat:@"%@...", [s substringToIndex:100]];
+  return s;
+}
+
+
+/* fetching */
+
+- (NSCalendarDate *)startDate {
+  return [[NSCalendarDate date] beginOfDay];
+}
+
+/* ZNeK: is a month ok? */
+- (NSCalendarDate *)endDate {
+  NSCalendarDate *date;
+  
+  date = [NSCalendarDate date];
+  date = [date dateByAddingYears:0 months:1 days:0
+                           hours:0 minutes:0 seconds:0];
+  date = [date endOfDay];
+  return date;
+}
+
+- (NSArray *)userAppointments {
+  if (!self->userApts) {
+    [self fetchInfos];
+  }
+  return self->userApts;
+}
+
+- (NSArray *)foreignAppointments {
+  if (!self->foreignApts) {
+    [self fetchInfos];
+  }
+  return self->foreignApts;
+}
+
+- (void)fetchInfos {
+  static NSArray *orders = nil;
+  id       aptFolder;
+  NSArray  *apts;
+  NSString *userEmail;
+  unsigned i, count;
+
+  if (!orders) {
+    orders = [[NSArray alloc] initWithObjects:@"startDate", nil];
+  }
+
+  aptFolder = [self clientObject];
+  apts      = [aptFolder fetchCoreInfosFrom:[self startDate]
+                         to:[self endDate]];
+  userEmail = [self emailForUser];
+  count     = [apts count];
+
+  self->userApts    = [[NSMutableArray alloc] initWithCapacity:count];
+  self->foreignApts = [[NSMutableArray alloc] initWithCapacity:count];
+
+  for (i = 0; i < count; i++) {
+    id       apt;
+    NSString *orgEmail;
+
+    apt      = [apts objectAtIndex:i];
+    orgEmail = [apt objectForKey:@"orgmail"];
+    if (orgEmail && [orgEmail isEqualToString:userEmail])
+      [self->userApts addObject:apt];
+    else
+      [self->foreignApts addObject:apt];
+  }
+  [self->userApts sortedArrayUsingKeyOrderArray:orders];
+  [self->foreignApts sortedArrayUsingKeyOrderArray:orders];
+}
+
+
+/* URLs */
+
+- (NSString *)appointmentBaseURL {
+  id pkey;
+  
+  if (![(pkey = [self->item valueForKey:@"uid"]) isNotNull])
+    return nil;
+  
+  return [[self clientObject] baseURLForAptWithUID:[pkey stringValue]
+                              inContext:[self context]];
+}
+- (NSString *)appointmentViewURL {
+  return [[self appointmentBaseURL] stringByAppendingPathComponent:@"view"];
+}
+- (NSString *)acceptAppointmentURL {
+  return [[self appointmentBaseURL] stringByAppendingPathComponent:@"accept"];
+}
+- (NSString *)rejectAppointmentURL {
+  return [[self appointmentBaseURL] stringByAppendingPathComponent:@"reject"];
+}
+
+
+/* access protection */
+
+- (BOOL)canAccess {
+  NSString *owner;
+  
+  owner = [[self clientObject] ownerInContext:[self context]];
+  if (!owner)
+    return NO;
+  return [[[[self context] activeUser] login] isEqualToString:owner];
+}
+
+@end
diff --git a/SOGo/UI/Scheduler/UIxCalScheduleOverview.wox b/SOGo/UI/Scheduler/UIxCalScheduleOverview.wox
new file mode 100644 (file)
index 0000000..3acd437
--- /dev/null
@@ -0,0 +1,210 @@
+<?xml version='1.0' standalone='yes'?>
+
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+               xmlns:var="http://www.skyrix.com/od/binding"
+               xmlns:const="http://www.skyrix.com/od/constant"
+               xmlns:rsrc="OGo:url"
+               xmlns:label="OGo:label"
+               className="UIxPageFrame"
+               title="name"
+>
+  <var:if condition="canAccess" const:negate="YES">
+    <var:string label:value="Forbidden" />
+  </var:if>
+  <var:if condition="canAccess">
+    <table id="skywintable"
+           class="wintable"
+           cellspacing="0"
+           cellpadding="5"
+           width="100%"
+    >
+      <tr>
+        <td class="wintitle">
+          <table cellpadding="0" cellspacing="0" width="100%">
+            <tr>
+              <td width="5"/>
+              <td class="wintitle">
+                <span class="window_label">
+                <var:string label:value="Schedule"/>
+                <var:string value="startDate" label:dateformat="dayLabelFormat" /> -
+                <var:string value="endDate" label:dateformat="dayLabelFormat" />
+                </span>
+              </td>
+              <td width="36" align="right" valign="center">
+                <var:component className="UIxWinClose"/>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" width="100%" cellpadding="0" cellspacing="0">
+            <tr>
+              <td colspan="2">
+                <var:component className="UIxCalSelectTab"
+                               const:selection="schedule"
+                               currentDate="selectedDate"
+                >
+                  <var:if condition="hasAnyAppointments" const:negate="YES">
+                    <var:string label:value="No appointments found" />
+                  </var:if>
+                  <var:if condition="hasAnyAppointments">
+                    <table border="0"
+                           width="100%"
+                           cellpadding="2"
+                           cellspacing="0"
+                           class="schedoverview"
+                    >
+                      <var:if condition="hasUserAppointments">
+                        <tr>
+                          <!-- meetings proposed by user -->
+                          <th colspan="4" class="schedoverview_title">
+                            <var:string label:value="Meetings proposed by you" />
+                          </th>
+                        </tr>
+                        <tr>
+                          <th class="schedoverview"
+                          ><var:string label:value="Start date" /></th>
+                          <th class="schedoverview"
+                          ><var:string label:value="Title" /></th>
+                          <th class="schedoverview"
+                          ><var:string label:value="participants"/></th>
+                        </tr>
+                        <var:foreach list="userAppointments" item="item">
+                          <tr>
+                            <td class="schedoverview">
+                              <var:string value="item.startDate"
+                                          label:dateformat="sched_startDateFormat"
+                              />
+                            </td>
+                            <td class="schedoverview">
+                              <a var:href="appointmentViewURL"
+                                 class="schedoverview"
+                              ><var:string value="item.title"
+                                           const:escapeHTML="YES"
+                               /></a>
+                            </td>
+                            <td class="schedoverview" colspan="2">
+                              <var:string value="participants"
+                                          const:escapeHTML="YES"
+                                          const:insertBR="YES"
+                              />
+                            </td>
+                          </tr>
+                        </var:foreach>
+                      </var:if>
+                      <var:if condition="hasForeignAppointments">
+                        <var:if condition="hasUserAppointments">
+                          <tr>
+                            <td><var:entity const:name="nbsp" /></td>
+                          </tr>
+                        </var:if>
+                        <tr>
+                          <!-- meetings proposed to user -->
+                          <th colspan="4" class="schedoverview_title">
+                            <var:string label:value="Meetings proposed to you" />
+                          </th>
+                        </tr>
+                        <tr>
+                          <th class="schedoverview"
+                          ><var:string label:value="Start date" /></th>
+                          <th class="schedoverview"
+                          ><var:string label:value="Title" /></th>
+                          <th class="schedoverview"
+                          ><var:string label:value="participants" /></th>
+                          <th class="schedoverview"
+                          ><var:string label:value="action" /></th>
+                        </tr>
+                        <var:foreach list="foreignAppointments" item="item">
+                          <tr>
+                            <td class="schedoverview">
+                              <var:string value="item.startDate"
+                                          label:dateformat="sched_startDateFormat"
+                              />
+                            </td>
+                            <td class="schedoverview">
+                              <a var:href="appointmentViewURL"
+                                 class="schedoverview"
+                              ><var:string value="item.title"
+                                           const:escapeHTML="YES"
+                               /></a>
+                            </td>
+                            <td class="schedoverview">
+                              <var:string value="participants"
+                                          const:escapeHTML="YES"
+                                          const:insertBR="YES"
+                              />
+                            </td>
+                            <td class="schedoverview">
+                              <a var:href="acceptAppointmentURL"
+                                 class="schedoverview"
+                              ><var:string label:value="accept" /></a><br />
+                              <a var:href="rejectAppointmentURL"
+                                 class="schedoverview"
+                              ><var:string label:value="reject" /></a>
+                            </td>
+                          </tr>
+                        </var:foreach>
+                      </var:if>
+                    </table>
+                  </var:if>
+                  <p>      
+                    workflow<br />
+                    ========<br />
+                    
+                    in fact, the workflow we wish to implement is :
+                    person A sets a meeting with B and C
+                    when he sets it, he clicks on a button : either "propose" or
+                    "propose and mail" (obvious)
+                    In both case, when B and C logs into SOGo, they see, in their
+                    'news page', that a new meeting has beeing proposed
+                    then by clicking on it, they can accept it
+                    on the news, you have to show : meetings proposed to the person
+                    logging in, meetings proposed BY the person logging in,
+                    and their different acceptance
+                    
+                    if you reject the meeting, it still appears in the news page
+                    as refused
+                    
+                    We have still two issues : ergonomic and functionnal
+                    
+                    The ergonomic one : I propose two sections in the news page,
+                    with each being a table, containing, each line, an apt,
+                    with title, day, hour, participants (truncated), the line
+                    being green if it has been accepted by all, red if rejected
+                    by someone
+                    grey if in another state
+                    
+                    the functionnal : a meeting that is still not accepted by
+                    everyone must appear in each participant's view, and be
+                    counted in the conflict manager, or not ?
+                    it's an open point
+                  </p>
+                </var:component>
+              </td>
+            </tr>
+            <tr bgcolor="#F5F5E9">
+              <td align="left" width="10">
+                <var:entity const:name="nbsp"/>
+              </td>
+              <td align="right">
+                <img border="0"
+                     alt=""
+                     src="/sogod.woa/so/ControlPanel/Products/CommonUI/Resources/corner_right.gif"
+                />
+              </td>
+            </tr>
+            <tr>
+              <td colspan="2" bgcolor="#F5F5E9">
+                <table border="0" width="100%" cellpadding="10" cellspacing="0">
+                  <tr/>
+                </table>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+    </table>
+  </var:if>
+</var:component>
\ No newline at end of file
index fcd77366f881531f570b29432399fd80ec507daa..ea97c4a57c7293a657f952f3b030b6122ffaf6fe 100644 (file)
@@ -91,6 +91,9 @@
 
 /* hrefs */
 
+- (NSString *)scheduletabLink {
+  return [self completeHrefForMethod:@"schedule"];
+}
 
 - (NSString *)daytabLink {
     return [self completeHrefForMethod:@"dayoverview"];
index d253e366f9a8b54bc0be805fae45866b8eb771db..9b92106240b58e598c84879ce1671dddcfd35f74 100644 (file)
@@ -4,12 +4,19 @@
              xmlns:var="http://www.skyrix.com/od/binding"
              xmlns:const="http://www.skyrix.com/od/constant"
              xmlns:rsrc="OGo:url"
+             xmlns:label="OGo:label"
              xmlns:uix="OGo:uix"
              var:selection="selection"
              const:tabStyle="tab"
              const:selectedTabStyle="tab_selected"
              const:bodyStyle="tabview_body"
 >
+  <uix:tab const:key="schedule"
+           label:label="Schedule"
+           var:href="scheduletabLink"
+  >
+     <var:component-content />
+  </uix:tab>
   <uix:tab const:key="day" var:label="dayLabel" var:href="daytabLink">
      <var:component-content />
   </uix:tab>
index 0cf550ea1a347d73c718bc29afc35fab6ad8427a..c74966145f996b08455f39f9f9d450a8634fafe2 100644 (file)
           protectedBy = "View";
           pageName    = "UIxCalYearOverview"; 
         };
+        schedule = { 
+          protectedBy = "View";
+          pageName    = "UIxCalScheduleOverview"; 
+        };
         new = { 
           protectedBy = "View";
           pageName    = "UIxAppointmentEditor"; 
           pageName    = "UIxAppointmentView"; 
           actionName  = "delete";
         };
+        accept = { 
+          protectedBy = "View";
+          pageName    = "UIxAppointmentView"; 
+          actionName  = "accept";
+        };
+        reject = { 
+          protectedBy = "View";
+          pageName    = "UIxAppointmentView"; 
+          actionName  = "reject";
+        };
         edit = { 
           protectedBy = "View";
           pageName    = "UIxAppointmentEditor";