Monotone-Parent: 1ccd34fd9ea99e675935d745db7e70d19716428a
Monotone-Revision: c40151185171e3ba8a257569b8ab5ec86930d393 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-05-05T14:40:53 Monotone-Branch: ca.inverse.sogo
@@ -1,5 +1,28 @@
|
||||
2010-05-05 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* UI/Scheduler/UIxComponentEditor.m (-ownerLogin): new accessor
|
||||
the differenciate between the type of users in the list of
|
||||
attendees.
|
||||
|
||||
* UI/WebServerResources/UIxAttendeesEditor.js
|
||||
(performSearchCallback): differenciate between the organizer user
|
||||
and other attendees, as in Lightning.
|
||||
|
||||
* UI/WebServerResources/UIxAppointmentEditor.js
|
||||
(setupAttendeeNode): removed useless calls to $().
|
||||
|
||||
* UI/Scheduler/UIxComponentEditor.m
|
||||
(-ownerIsAttendee:andClientObject:)
|
||||
(delegateIsAttendee:andClientObject:): handle the case where the
|
||||
user is found but has no RSVP or one with "FALSE" as value.
|
||||
(-userHasRSVP): renamed from "userIsAttendee", since we don't
|
||||
enable users without a RSVP set as "TRUE" to repond to
|
||||
invitations.
|
||||
(-currentAttendeeClasses): new method.
|
||||
|
||||
* UI/MailPartViewers/UIxMailPartICalActions.m (-tentativeAction):
|
||||
new action method for the "TENTATIVE" partstat.
|
||||
|
||||
* SoObjects/Appointments/iCalEntityObject+SOGo.m
|
||||
(-userIsParticipant:): renamed to "userIsAttendee:". We now
|
||||
request the list of attendees rather than the list of
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
- (WOResponse *) acceptAction;
|
||||
- (WOResponse *) declineAction;
|
||||
- (WOResponse *) tentativeAction;
|
||||
- (WOResponse *) delegateAction;
|
||||
- (WOResponse *) addToCalendarAction;
|
||||
- (WOResponse *) deleteFromCalendarAction;
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#import <Mailer/SOGoMailObject.h>
|
||||
#import <SOGo/SOGoParentFolder.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/iCalEntityObject+Utilities.h>
|
||||
#import <Mailer/SOGoMailBodyPart.h>
|
||||
|
||||
#import "UIxMailPartICalActions.h"
|
||||
@@ -261,6 +260,12 @@
|
||||
withDelegate: nil];
|
||||
}
|
||||
|
||||
- (WOResponse *) tentativeAction
|
||||
{
|
||||
return [self _changePartStatusAction: @"TENTATIVE"
|
||||
withDelegate: nil];
|
||||
}
|
||||
|
||||
- (WOResponse *) delegateAction
|
||||
{
|
||||
// BOOL receiveUpdates;
|
||||
@@ -369,7 +374,7 @@
|
||||
address = [[mailObject fromEnvelopeAddresses] objectAtIndex: 0];
|
||||
emailFrom = [address baseEMail];
|
||||
|
||||
return [event findParticipantWithEmail: emailFrom];
|
||||
return [event findAttendeeWithEmail: emailFrom];
|
||||
}
|
||||
|
||||
- (BOOL) _updateParticipantStatusInEvent: (iCalEvent *) calendarEvent
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
actionClass = "UIxMailPartICalActions";
|
||||
actionName = "decline";
|
||||
};
|
||||
tentative = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailPartICalActions";
|
||||
actionName = "tentative";
|
||||
};
|
||||
delegate = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailPartICalActions";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "A data que você informou ocorre antes da data ini
|
||||
= "Você tem certeza que quer apagar o calendário \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Participante Requerido";
|
||||
"Optional participant" = "Participante Opcional";
|
||||
"Participant" = "Participante";
|
||||
"Optional Participant" = "Participante Opcional";
|
||||
"Non Participant" = "Não Participante";
|
||||
"Chair" = "Cadeira";
|
||||
|
||||
"Needs action" = "Ações necessárias";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "Zadané datum konce je před začátkem události.
|
||||
= "Opravdu chcete smazat kalendář \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Vyžadovaný účastník";
|
||||
"Optional participant" = "Nepovinný účastník";
|
||||
"Participant" = "Účastník";
|
||||
"Optional Participant" = "Nepovinný účastník";
|
||||
"Non Participant" = "Non Participant";
|
||||
"Chair" = "Židle";
|
||||
|
||||
"Needs action" = "Vyžaduje akci";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "Het begin vindt plaats vóór het einde.";
|
||||
= "Weet u zeker dat u de agenda \"%{0}\" wilt verwijderen?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Vereiste deelnemer";
|
||||
"Optional participant" = "Gewenste deelnemer";
|
||||
"Participant" = "Deelnemer";
|
||||
"Optional Participant" = "Gewenste deelnemer";
|
||||
"Non Participant" = "Non Participant";
|
||||
"Chair" = "Voorzitter";
|
||||
|
||||
"Needs action" = "Actie vereist";
|
||||
|
||||
@@ -246,10 +246,10 @@
|
||||
|
||||
/* Appointments (participation state) */
|
||||
|
||||
"partStat_NEEDS-ACTION" = "Needs action";
|
||||
"partStat_NEEDS-ACTION" = "I will confirm later";
|
||||
"partStat_ACCEPTED" = "I will attend";
|
||||
"partStat_DECLINED" = "I will not attend";
|
||||
"partStat_TENTATIVE" = "I will confirm later";
|
||||
"partStat_TENTATIVE" = "I might attend";
|
||||
"partStat_DELEGATED" = "I delegate";
|
||||
"partStat_OTHER" = "Other";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "The end date that you entered occurs before the st
|
||||
= "Are you sure you want to delete the calendar \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Required participant";
|
||||
"Optional participant" = "Optional participant";
|
||||
"Participant" = "Participant";
|
||||
"Optional Participant" = "Optional Participant";
|
||||
"Non Participant" = "Non Participant";
|
||||
"Chair" = "Chair";
|
||||
|
||||
"Needs action" = "Needs action";
|
||||
|
||||
@@ -246,10 +246,10 @@
|
||||
|
||||
/* Appointments (participation state) */
|
||||
|
||||
"partStat_NEEDS-ACTION" = "Décision attendue";
|
||||
"partStat_NEEDS-ACTION" = "Je confirmerai plus tard";
|
||||
"partStat_ACCEPTED" = "Je participerai";
|
||||
"partStat_DECLINED" = "Je ne participerai pas";
|
||||
"partStat_TENTATIVE" = "Je confirmerai plus tard";
|
||||
"partStat_TENTATIVE" = "Je participerai peut-être";
|
||||
"partStat_DELEGATED" = "Je délègue";
|
||||
"partStat_OTHER" = "???";
|
||||
|
||||
@@ -460,9 +460,10 @@ validate_endbeforestart = "La date de fin est avant la date de début.";
|
||||
= "Voulez-vous vraiment supprimer l'agenda «%{0}»?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Participant obligatoire";
|
||||
"Optional participant" = "Participant facultatif";
|
||||
"Chair" = "Chaise";
|
||||
"Participant" = "Invité";
|
||||
"Optional Participant" = "Invité optionnel";
|
||||
"Non Participant" = "Non-invité";
|
||||
"Chair" = "Président";
|
||||
|
||||
"Needs action" = "En attente";
|
||||
"Accepted" = "Accepté";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "Ihr Beginn ist nach dem Ende";
|
||||
= "Wollen Sie diesen Kalender wirklich löschen \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "notwendiger Teilnehmer";
|
||||
"Optional participant" = "optionaler Teilnehmer";
|
||||
"Participant" = "Teilnehmer";
|
||||
"Optional Participant" = "optionaler Teilnehmer";
|
||||
"Non Participant" = "Non Participant";
|
||||
"Chair" = "Vorsitz";
|
||||
|
||||
"Needs action" = "Benötigt Eingriff";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "A megadott befejező dátum korábbi, mint a kezd
|
||||
= "Biztosan törli ezt a naptárat: \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Kötelező résztvevő";
|
||||
"Optional participant" = "Nem kötelező résztvevő";
|
||||
"Participant" = "Kötelező résztvevő";
|
||||
"Optional Participant" = "Nem kötelező résztvevő";
|
||||
"Non Participant" = "Non Participant";
|
||||
"Chair" = "Szék";
|
||||
|
||||
"Needs action" = "Foglalkozni kell vele";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "La data finale specificata è precedente alla data
|
||||
= "Sei sicuro di voler cancellare il calendario \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Richiede partecipanti";
|
||||
"Optional participant" = "Partecipanti opzionali";
|
||||
"Participant" = "Partecipanti";
|
||||
"Optional Participant" = "Partecipanti opzionali";
|
||||
"Non Participant" = "Non Partecipanti";
|
||||
"Chair" = "Sedia";
|
||||
|
||||
"Needs action" = "Richiede un'azione";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "The end date that you entered occurs before the st
|
||||
= "Вы уверены что хотите удалить календарь \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Required participant";
|
||||
"Optional participant" = "Optional participant";
|
||||
"Participant" = "Participant";
|
||||
"Optional Participant" = "Optional Participant";
|
||||
"Non Participant" = "Non Participant";
|
||||
"Chair" = "Chair";
|
||||
|
||||
"Needs action" = "Needs action";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "Su fecha/hora de comienzo es posterio a la de fina
|
||||
= "¿Está seguro/a que desea borrar el calendario \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Asistente obligatorio";
|
||||
"Optional participant" = "Asistentes opcionales";
|
||||
"Participant" = "Asistente";
|
||||
"Optional Participant" = "Asistentes opcionales";
|
||||
"Non Participant" = "Non Particpant";
|
||||
"Chair" = "Presidente";
|
||||
|
||||
"Needs action" = "Requiere intervención";
|
||||
|
||||
@@ -460,8 +460,9 @@ validate_endbeforestart = "Angivet slutdatumet inträffar före angivet start
|
||||
= "Är du säker på att du vill ta bort kalendern \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "Deltagande krävs";
|
||||
"Optional participant" = "Deltagande valfritt";
|
||||
"Participant" = "Deltagande krävs";
|
||||
"Optional Participant" = "Deltagande valfritt";
|
||||
"Non Participant" = "Non Participant";
|
||||
"Chair" = "Stol";
|
||||
|
||||
"Needs action" = "Behöver åtgärd";
|
||||
|
||||
@@ -522,22 +522,32 @@
|
||||
[event setTransparency: (isTransparent? @"TRANSPARENT" : @"OPAQUE")];
|
||||
}
|
||||
|
||||
// TODO: add tentatively
|
||||
- (id) _statusChangeAction: (NSString *) newStatus
|
||||
{
|
||||
[[self clientObject] changeParticipationStatus: newStatus
|
||||
withDelegate: nil];
|
||||
|
||||
return [self responseWith204];
|
||||
}
|
||||
|
||||
- (id) acceptAction
|
||||
{
|
||||
[[self clientObject] changeParticipationStatus: @"ACCEPTED"
|
||||
withDelegate: nil];
|
||||
|
||||
return self;
|
||||
return [self _statusChangeAction: @"ACCEPTED"];
|
||||
}
|
||||
|
||||
- (id) declineAction
|
||||
{
|
||||
[[self clientObject] changeParticipationStatus: @"DECLINED"
|
||||
withDelegate: nil];
|
||||
return [self _statusChangeAction: @"DECLINED"];
|
||||
}
|
||||
|
||||
return self;
|
||||
- (id) needsActionAction
|
||||
{
|
||||
return [self _statusChangeAction: @"NEEDS-ACTION"];
|
||||
}
|
||||
|
||||
- (id) tentativeAction
|
||||
{
|
||||
return [self _statusChangeAction: @"TENTATIVE"];
|
||||
}
|
||||
|
||||
- (id) delegateAction
|
||||
@@ -584,7 +594,7 @@
|
||||
reason: @"missing 'to' parameter"];
|
||||
|
||||
if (!response)
|
||||
response = [self responseWithStatus: 200];
|
||||
response = [self responseWith204];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
#import <Appointments/SOGoAppointmentObject.h>
|
||||
#import <Appointments/SOGoAppointmentOccurence.h>
|
||||
#import <Appointments/SOGoTaskObject.h>
|
||||
#import <SOGo/iCalEntityObject+Utilities.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSDictionary+BSJSONAdditions.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
@@ -268,6 +267,8 @@ iRANGE(2);
|
||||
|
||||
[currentAttendeeData setObject: [[currentAttendee partStat] lowercaseString]
|
||||
forKey: @"partstat"];
|
||||
[currentAttendeeData setObject: [[currentAttendee role] lowercaseString]
|
||||
forKey: @"role"];
|
||||
|
||||
if ([[currentAttendee delegatedTo] length])
|
||||
[currentAttendeeData setObject: [[currentAttendee delegatedTo] rfc822Email]
|
||||
@@ -587,7 +588,7 @@ iRANGE(2);
|
||||
um = [SOGoUserManager sharedUserManager];
|
||||
owner = [componentCalendar ownerInContext: context];
|
||||
ownerEmail = [um getEmailForUID: owner];
|
||||
ASSIGN (ownerAsAttendee, [component findParticipantWithEmail: (id)ownerEmail]);
|
||||
ASSIGN (ownerAsAttendee, [component findAttendeeWithEmail: (id)ownerEmail]);
|
||||
}
|
||||
}
|
||||
// /* cycles */
|
||||
@@ -990,14 +991,26 @@ iRANGE(2);
|
||||
{
|
||||
NSString *word;
|
||||
|
||||
if ([item intValue] == iCalPersonPartStatAccepted)
|
||||
word = @"ACCEPTED";
|
||||
else if ([item intValue] == iCalPersonPartStatDeclined)
|
||||
word = @"DECLINED";
|
||||
else if ([item intValue] == iCalPersonPartStatDelegated)
|
||||
word = @"DELEGATED";
|
||||
else
|
||||
word = @"UNKNOWN";
|
||||
switch ([item intValue])
|
||||
{
|
||||
case iCalPersonPartStatAccepted:
|
||||
word = @"ACCEPTED";
|
||||
break;
|
||||
case iCalPersonPartStatDeclined:
|
||||
word = @"DECLINED";
|
||||
break;
|
||||
case iCalPersonPartStatNeedsAction:
|
||||
word = @"NEEDS-ACTION";
|
||||
break;
|
||||
case iCalPersonPartStatTentative:
|
||||
word = @"TENTATIVE";
|
||||
break;
|
||||
case iCalPersonPartStatDelegated:
|
||||
word = @"DELEGATED";
|
||||
break;
|
||||
default:
|
||||
word = @"UNKNOWN";
|
||||
}
|
||||
|
||||
return [self labelForKey: [NSString stringWithFormat: @"partStat_%@", word]];
|
||||
}
|
||||
@@ -1005,8 +1018,10 @@ iRANGE(2);
|
||||
- (NSArray *) replyList
|
||||
{
|
||||
return [NSArray arrayWithObjects:
|
||||
[NSNumber numberWithInt: iCalPersonPartStatAccepted],
|
||||
[NSNumber numberWithInt: iCalPersonPartStatAccepted],
|
||||
[NSNumber numberWithInt: iCalPersonPartStatDeclined],
|
||||
[NSNumber numberWithInt: iCalPersonPartStatNeedsAction],
|
||||
[NSNumber numberWithInt: iCalPersonPartStatTentative],
|
||||
[NSNumber numberWithInt: iCalPersonPartStatDelegated],
|
||||
nil];
|
||||
}
|
||||
@@ -1508,7 +1523,7 @@ RANGE(2);
|
||||
unsigned int count, max;
|
||||
NSString *currentEmail;
|
||||
iCalPerson *currentAttendee;
|
||||
NSString *json;
|
||||
NSString *json, *role, *partstat;
|
||||
NSDictionary *attendeesData;
|
||||
NSArray *attendees;
|
||||
NSDictionary *currentData;
|
||||
@@ -1529,17 +1544,33 @@ RANGE(2);
|
||||
{
|
||||
currentData = [attendees objectAtIndex: count];
|
||||
currentEmail = [currentData objectForKey: @"email"];
|
||||
currentAttendee = [component findParticipantWithEmail: currentEmail];
|
||||
role = [[currentData objectForKey: @"role"] uppercaseString];
|
||||
if (!role)
|
||||
role = @"REQ-PARTICIPANT";
|
||||
if ([role isEqualToString: @"NON-PARTICIPANT"])
|
||||
partstat = @"";
|
||||
else
|
||||
{
|
||||
partstat = [[currentData objectForKey: @"partstat"]
|
||||
uppercaseString];
|
||||
if (!partstat)
|
||||
partstat = @"NEEDS-ACTION";
|
||||
}
|
||||
currentAttendee = [component findAttendeeWithEmail: currentEmail];
|
||||
if (!currentAttendee)
|
||||
{
|
||||
currentAttendee = [iCalPerson elementWithTag: @"attendee"];
|
||||
[currentAttendee setCn: [currentData objectForKey: @"name"]];
|
||||
[currentAttendee setEmail: currentEmail];
|
||||
[currentAttendee setRole: @"REQ-PARTICIPANT"];
|
||||
[currentAttendee setRsvp: @"TRUE"];
|
||||
[currentAttendee
|
||||
setParticipationStatus: iCalPersonPartStatNeedsAction];
|
||||
// [currentAttendee
|
||||
// setParticipationStatus: iCalPersonPartStatNeedsAction];
|
||||
}
|
||||
[currentAttendee
|
||||
setRsvp: ([role isEqualToString: @"NON-PARTICIPANT"]
|
||||
? @"FALSE"
|
||||
: @"TRUE")];
|
||||
[currentAttendee setRole: role];
|
||||
[currentAttendee setPartStat: partstat];
|
||||
[newAttendees addObject: currentAttendee];
|
||||
}
|
||||
[component setAttendees: newAttendees];
|
||||
@@ -1965,8 +1996,7 @@ RANGE(2);
|
||||
isOrganizer = ![ownerUser hasEmail: [[component organizer] sentBy]];
|
||||
|
||||
if ([componentCalendar isKindOfClass: [SOGoWebAppointmentFolder class]]
|
||||
|| ([[component attendees] count]
|
||||
&& [component userIsParticipant: ownerUser]
|
||||
|| ([component userIsAttendee: ownerUser]
|
||||
&& !isOrganizer
|
||||
// Lightning does not manage participation status within tasks,
|
||||
// so we also ignore the participation status of tasks in the
|
||||
@@ -1991,14 +2021,12 @@ RANGE(2);
|
||||
{
|
||||
SoSecurityManager *sm;
|
||||
NSString *toolbarFilename, *adminToolbar;
|
||||
SOGoUser *currentUser;
|
||||
|
||||
if ([clientObject isKindOfClass: [SOGoAppointmentObject class]])
|
||||
adminToolbar = @"SOGoAppointmentObject.toolbar";
|
||||
else
|
||||
adminToolbar = @"SOGoTaskObject.toolbar";
|
||||
|
||||
currentUser = [context activeUser];
|
||||
sm = [SoSecurityManager sharedSecurityManager];
|
||||
|
||||
if (![sm validatePermission: SOGoCalendarPerm_ModifyComponent
|
||||
@@ -2035,36 +2063,45 @@ RANGE(2);
|
||||
|
||||
|
||||
- (int) ownerIsAttendee: (SOGoUser *) ownerUser
|
||||
andClientObject: (SOGoContentObject
|
||||
<SOGoComponentOccurence> *) clientObject
|
||||
andClientObject: (SOGoContentObject
|
||||
<SOGoComponentOccurence> *) clientObject
|
||||
{
|
||||
BOOL isOrganizer;
|
||||
int rc = 0;
|
||||
iCalPerson *ownerAttendee;
|
||||
int rc;
|
||||
|
||||
rc = 0;
|
||||
|
||||
isOrganizer = [component userIsOrganizer: ownerUser];
|
||||
if (isOrganizer)
|
||||
isOrganizer = ![ownerUser hasEmail: [[component organizer] sentBy]];
|
||||
|
||||
if ([[component attendees] count]
|
||||
&& [component userIsParticipant: ownerUser]
|
||||
&& !isOrganizer
|
||||
&& ![[component tag] isEqualToString: @"VTODO"])
|
||||
rc = 1;
|
||||
if (!isOrganizer && ![[component tag] isEqualToString: @"VTODO"])
|
||||
{
|
||||
ownerAttendee = [component userAsAttendee: ownerUser];
|
||||
if (ownerAttendee)
|
||||
{
|
||||
if ([[ownerAttendee rsvp] isEqualToString: @"true"])
|
||||
rc = 1;
|
||||
else
|
||||
rc = 2;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) delegateIsAttendee: (SOGoUser *) ownerUser
|
||||
andClientObject: (SOGoContentObject
|
||||
<SOGoComponentOccurence> *) clientObject
|
||||
andClientObject: (SOGoContentObject
|
||||
<SOGoComponentOccurence> *) clientObject
|
||||
{
|
||||
SoSecurityManager *sm;
|
||||
SOGoUser *currentUser;
|
||||
int rc = 0;
|
||||
iCalPerson *ownerAttendee;
|
||||
int rc;
|
||||
|
||||
rc = 0;
|
||||
|
||||
currentUser = [context activeUser];
|
||||
sm = [SoSecurityManager sharedSecurityManager];
|
||||
|
||||
if (![sm validatePermission: SOGoCalendarPerm_ModifyComponent
|
||||
onObject: clientObject
|
||||
inContext: context])
|
||||
@@ -2072,11 +2109,15 @@ RANGE(2);
|
||||
andClientObject: clientObject];
|
||||
else if (![sm validatePermission: SOGoCalendarPerm_RespondToComponent
|
||||
onObject: clientObject
|
||||
inContext: context]
|
||||
&& [[component attendees] count]
|
||||
&& [component userIsParticipant: ownerUser]
|
||||
&& ![component userIsOrganizer: ownerUser])
|
||||
rc = 1;
|
||||
inContext: context])
|
||||
{
|
||||
ownerAttendee = [component userAsAttendee: ownerUser];
|
||||
if ([[ownerAttendee rsvp] isEqualToString: @"true"]
|
||||
&& ![component userIsOrganizer: ownerUser])
|
||||
rc = 1;
|
||||
else
|
||||
rc = 2;
|
||||
}
|
||||
else
|
||||
rc = 2; // not invited, just RO
|
||||
|
||||
@@ -2090,9 +2131,8 @@ RANGE(2);
|
||||
int rc;
|
||||
|
||||
clientObject = [self clientObject];
|
||||
ownerUser = [SOGoUser userWithLogin: [clientObject ownerInContext: context]
|
||||
roles: nil];
|
||||
|
||||
ownerUser
|
||||
= [SOGoUser userWithLogin: [clientObject ownerInContext: context]];
|
||||
if ([componentCalendar isKindOfClass: [SOGoWebAppointmentFolder class]])
|
||||
rc = 2;
|
||||
else
|
||||
@@ -2113,9 +2153,54 @@ RANGE(2);
|
||||
return [self getEventRWType] != 0;
|
||||
}
|
||||
|
||||
- (BOOL) userIsAttendee
|
||||
- (BOOL) userHasRSVP
|
||||
{
|
||||
return [self getEventRWType] == 1;
|
||||
return ([self getEventRWType] == 1);
|
||||
}
|
||||
|
||||
- (NSString *) currentAttendeeClasses
|
||||
{
|
||||
NSMutableArray *classes;
|
||||
iCalPerson *ownerAttendee;
|
||||
SOGoUser *ownerUser;
|
||||
NSString *role, *partStat;
|
||||
SOGoCalendarComponent *co;
|
||||
|
||||
classes = [NSMutableArray arrayWithCapacity: 5];
|
||||
|
||||
/* rsvp class */
|
||||
if (![[attendee rsvp] isEqualToString: @"true"])
|
||||
[classes addObject: @"not-rsvp"];
|
||||
|
||||
/* partstat class */
|
||||
partStat = [[attendee partStat] lowercaseString];
|
||||
if (![partStat length])
|
||||
partStat = @"no-partstat";
|
||||
[classes addObject: partStat];
|
||||
|
||||
/* role class */
|
||||
role = [[attendee role] lowercaseString];
|
||||
if (![partStat length])
|
||||
role = @"no-role";
|
||||
[classes addObject: role];
|
||||
|
||||
/* attendee class */
|
||||
if ([[attendee delegatedFrom] length] > 0)
|
||||
[classes addObject: @"delegate"];
|
||||
|
||||
/* current attendee class */
|
||||
co = [self clientObject];
|
||||
ownerUser = [SOGoUser userWithLogin: [co ownerInContext: context]];
|
||||
ownerAttendee = [component userAsAttendee: ownerUser];
|
||||
if (attendee == ownerAttendee)
|
||||
[classes addObject: @"attendeeUser"];
|
||||
|
||||
return [classes componentsJoinedByString: @" "];
|
||||
}
|
||||
|
||||
- (NSString *) ownerLogin
|
||||
{
|
||||
return [[self clientObject] ownerInContext: context];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -462,6 +462,7 @@ validate_endbeforestart = "Mae'r dyddiad gorffen sydd wedi'i roi yn digwydd c
|
||||
/* Legend */
|
||||
"Required participant" = "Cyfranogwr gofynnol";
|
||||
"Optional participant" = "Cyfranogwr opsiynol";
|
||||
"Non Participant" = "Non Participant";
|
||||
"Chair" = "Cadair";
|
||||
|
||||
"Needs action" = "Angen gweithred";
|
||||
|
||||
@@ -235,6 +235,16 @@
|
||||
pageName = "UIxAppointmentEditor";
|
||||
actionName = "delegate";
|
||||
};
|
||||
tentative = {
|
||||
protectedBy = "RespondToComponent";
|
||||
pageName = "UIxAppointmentEditor";
|
||||
actionName = "tentative";
|
||||
};
|
||||
needsaction = {
|
||||
protectedBy = "RespondToComponent";
|
||||
pageName = "UIxAppointmentEditor";
|
||||
actionName = "needsAction";
|
||||
};
|
||||
adjust = {
|
||||
protectedBy = "ModifyComponent";
|
||||
actionClass = "UIxAppointmentActions";
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<var:if condition="hasCalendarAccess">
|
||||
<div class="uix_ical_toolbar" id="iCalendarToolbar">
|
||||
<p>
|
||||
<var:if condition="currentUserAttendee.rsvp" const:value="true">
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="ACCEPTED" const:negate="YES">
|
||||
<a href="#" class="button actionButton" id="iCalendarAccept">
|
||||
@@ -56,6 +57,11 @@
|
||||
<span><var:string label:value="Decline" /></span></a>
|
||||
</var:if>
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="TENTATIVE" const:negate="YES">
|
||||
<a href="#" class="button actionButton" id="iCalendarTentative">
|
||||
<span><var:string label:value="Tentative" /></span></a>
|
||||
</var:if>
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="DELEGATED" const:negate="YES">
|
||||
<a href="#" class="button actionButton" id="editDelegate">
|
||||
<span><var:string label:value="Delegate ..." /></span></a>
|
||||
@@ -76,6 +82,7 @@
|
||||
<span><var:string label:value="OK" /></span></a>
|
||||
</span>
|
||||
</var:if>
|
||||
</var:if>
|
||||
<var:if condition="isEventStoredInCalendar" const:negate="YES">
|
||||
<a href="#" class="button actionButton" id="iCalendarAddToCalendar">
|
||||
<span><var:string label:value="Add to calendar" /></span></a>
|
||||
@@ -223,7 +230,9 @@
|
||||
<td valign="top"><var:string label:value="Attendees"/>:</td>
|
||||
<td id="iCalAttendees">
|
||||
<var:foreach list="authorativeEvent.participants" item="attendee">
|
||||
<var:if condition="attendee.delegatedTo" const:negate="YES"><!-- don't show attendees that delegated the invitation --><span var:class="currentAttendeeClass"><a var:href="attendee.email">
|
||||
<var:if condition="attendee.delegatedTo" const:negate="YES"><!-- don't show attendees that delegated the invitation --><span var:class="currentAttendeeClass"
|
||||
><div class="status-icon"><!-- space --></div
|
||||
><a var:href="attendee.email">
|
||||
<var:string value="attendeeForDisplay"/></a>
|
||||
(<var:string label:value="$attendee.partStatWithDefault" /><var:if condition="attendee.delegatedTo"> <var:string label:value="to" /> <var:string value="attendee.delegatedTo.rfc822Email" /></var:if><var:if condition="attendee.delegatedFrom">, <var:string label:value="delegated from" /> <var:string value="attendee.delegatedFrom.rfc822Email" /></var:if>)</span>
|
||||
<br /></var:if>
|
||||
|
||||
@@ -22,29 +22,23 @@
|
||||
<div id="freeBusyViewButtons">
|
||||
<var:string label:value="Suggest time slot:"/>
|
||||
<span class="buttons"><a id="nextSlot" href="#" class="button"
|
||||
><span><var:string label:value="Next slot" /></span></a>
|
||||
<a id="previousSlot" href="#" class="button"
|
||||
><span><var:string label:value="Previous slot" /></span></a></span>
|
||||
><span><var:string label:value="Next slot" /></span></a>
|
||||
<a id="previousSlot" href="#" class="button"
|
||||
><span><var:string label:value="Previous slot" /></span></a></span>
|
||||
<input class="checkbox" type="checkbox"
|
||||
checked="1" id="onlyOfficeHours" /><var:string label:value="Only office hours" />
|
||||
checked="1" id="onlyOfficeHours" /><var:string label:value="Only office hours" />
|
||||
</div>
|
||||
<div id="freeBusyView">
|
||||
<table id="freeBusy" cellspacing="0" cellpadding="0"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:uix="OGo:uix"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
<table id="freeBusy" cellspacing="0" cellpadding="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<td><!--space --></td>
|
||||
<td class="freeBusyHeader">
|
||||
<div><table id="freeBusyHeader" cellspacing="0" cellpadding="0">
|
||||
<tr class="freeBusyHeader1"><!--space --></tr>
|
||||
<tr class="freeBusyHeader2"><!--space --></tr>
|
||||
<tr id="currentEventPosition" class="freeBusyHeader3"><!--space --></tr>
|
||||
</table></div>
|
||||
<tr class="freeBusyHeader1"><!--space --></tr>
|
||||
<tr class="freeBusyHeader2"><!--space --></tr>
|
||||
<tr id="currentEventPosition" class="freeBusyHeader3"><!--space --></tr>
|
||||
</table></div>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -52,25 +46,28 @@
|
||||
<tr>
|
||||
<td class="freeBusyAttendees">
|
||||
<div><table id="freeBusyAttendees" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr class="futureAttendee"
|
||||
><td class="attendees"><a href="#" class="button"
|
||||
readonly="readonly"><span
|
||||
><var:string label:value="newAttendee" /></span></a></td
|
||||
></tr>
|
||||
<tr class="attendeeModel"
|
||||
><td class="attendees"><input type="text" class="textField" /></td
|
||||
></tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<tbody>
|
||||
<tr class="futureAttendee"
|
||||
><td class="attendeeStatus"><div><!-- space --></div></td
|
||||
><td class="attendees"><a href="#" class="button"
|
||||
readonly="readonly"><span
|
||||
><var:string label:value="newAttendee" /></span></a></td
|
||||
></tr>
|
||||
<tr class="attendeeModel"
|
||||
><td class="attendeeStatus"><div><!-- space --></div></td
|
||||
><td class="attendees"
|
||||
><input type="text" class="textField" /></td
|
||||
></tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
</td>
|
||||
<td class="freeBusyData">
|
||||
<div><table id="freeBusyData" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr class="futureData"></tr>
|
||||
<tr class="dataModel"></tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<tbody>
|
||||
<tr class="futureData"></tr>
|
||||
<tr class="dataModel"></tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -78,27 +75,38 @@
|
||||
</div>
|
||||
<div id="freeBusyFooter">
|
||||
<div id="legend" onmousedown="return false;">
|
||||
<ul>
|
||||
<ul class="roles-legend">
|
||||
<li role="req-participant"><span class="role-icon"><!-- space --></span
|
||||
><var:string label:value="Participant"/></li>
|
||||
<li role="opt-participant"><span class="role-icon"><!-- space --></span
|
||||
><var:string label:value="Optional Participant"/></li>
|
||||
<li role="non-participant"><span class="role-icon"><!-- space --></span
|
||||
><var:string label:value="Non Participant"/></li>
|
||||
<li role="chair"><span class="role-icon"><!-- space --></span
|
||||
><var:string label:value="Chair"/></li>
|
||||
</ul>
|
||||
|
||||
<ul class="freebusy-legend">
|
||||
<li><span class="colorBox free"><!-- spacer --></span
|
||||
><var:string label:value="Free" /></li>
|
||||
<li><span class="colorBox busy"><!-- spacer --></span
|
||||
><var:string label:value="Busy" /></li>
|
||||
<!-- li><span class="colorBox maybe-busy">\- spacer -\->/span -->
|
||||
<!-- >var:string label:value="Maybe busy" />/li> -->
|
||||
<!-- li><span class="colorBox maybe-busy">\- spacer -\->/span -->
|
||||
<!-- >var:string label:value="Maybe busy" />/li> -->
|
||||
<li><span class="colorBox noFreeBusy"><!-- spacer --></span
|
||||
><var:string label:value="No free-busy information" /></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="freeBusyReplicas">
|
||||
<div><span><var:string label:value="Start:"
|
||||
/></span><var:component className="UIxTimeDateControl"
|
||||
/></span><var:component className="UIxTimeDateControl"
|
||||
const:controlID="startTime"
|
||||
date="aptStartDate"
|
||||
const:dayStartHour="0"
|
||||
const:dayEndHour="23"
|
||||
/></div>
|
||||
<div><span><var:string label:value="End:"
|
||||
/></span><var:component className="UIxTimeDateControl"
|
||||
<div><span><var:string label:value="End:"
|
||||
/></span><var:component className="UIxTimeDateControl"
|
||||
const:controlID="endTime"
|
||||
date="aptEndDate"
|
||||
const:dayStartHour="0"
|
||||
@@ -108,9 +116,9 @@
|
||||
<div id="windowButtons">
|
||||
<hr />
|
||||
<a id="okButton" href="#" class="button actionButton"
|
||||
><span><var:string label:value="OK"/></span></a>
|
||||
><span><var:string label:value="OK"/></span></a>
|
||||
<a id="cancelButton" href="#" class="button"
|
||||
><span><var:string label:value="Cancel"/></span></a>
|
||||
><span><var:string label:value="Cancel"/></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
var activeComponent = '<var:if condition="isChildOccurence"><var:string value="clientObject.container.nameInContainer"/>/</var:if><var:string value="clientObject.nameInContainer"/>';
|
||||
var readOnly = <var:if condition="eventIsReadOnly">true</var:if><var:if condition="eventIsReadOnly"
|
||||
const:negate="YES">false</var:if>;
|
||||
var attendees = <var:string value="jsonAttendees" const:escapeHTML="NO" />;
|
||||
var attendees = <var:string value="jsonAttendees" const:escapeHTML="NO"/>;
|
||||
var ownerLogin = '<var:string value="ownerLogin"/>';
|
||||
</script>
|
||||
|
||||
<var:if condition="eventIsReadOnly" const:negate="YES">
|
||||
@@ -203,11 +204,9 @@
|
||||
<span class="content"><var:string value="organizerName"/></span>
|
||||
</label>
|
||||
</var:if>
|
||||
<var:if condition="userIsAttendee">
|
||||
<var:if condition="userHasRSVP">
|
||||
<label><var:string label:value="Reply:" />
|
||||
<span class="content"><var:popup list="replyList" item="item"
|
||||
const:disabledValue="-"
|
||||
label:noSelectionString="partStat_NEEDS-ACTION"
|
||||
const:name="replyList"
|
||||
const:id="replyList"
|
||||
string="itemReplyText"
|
||||
@@ -251,8 +250,17 @@
|
||||
</label>
|
||||
<label id="attendeesLabel">
|
||||
<span class="content"><div id="attendeesMenu" class="fakeTextArea">
|
||||
<var:foreach list="component.participants" item="attendee">
|
||||
<var:if condition="attendee.delegatedTo" const:negate="YES"><div var:class="attendee.partStatWithDefault.lowercaseString"><a var:href="attendee.email" var:email="attendee.email.rfc822Email"><var:string value="attendeeForDisplay" /></a><var:if condition="attendee.delegatedFrom"> (<var:string label:value="delegated from" /> <var:string value="attendee.delegatedFrom.rfc822Email" />)</var:if></div></var:if>
|
||||
<var:foreach list="component.attendees" item="attendee"
|
||||
><var:if condition="attendee.delegatedTo" const:negate="YES"
|
||||
><div var:class="currentAttendeeClasses"
|
||||
><div const:class="statusIcon"><!-- space --></div
|
||||
><a var:href="attendee.email" var:email="attendee.email.rfc822Email"
|
||||
><var:string value="attendeeForDisplay" /></a
|
||||
><var:if condition="attendee.delegatedFrom"
|
||||
> (<var:string label:value="delegated from" />
|
||||
<var:string value="attendee.delegatedFrom.rfc822Email" />)</var:if
|
||||
></div
|
||||
></var:if>
|
||||
</var:foreach>
|
||||
</div></span>
|
||||
</label>
|
||||
@@ -331,7 +339,7 @@
|
||||
var:value="reminderReference"/>
|
||||
|
||||
<div id="windowButtons">
|
||||
<var:if condition="userIsAttendee"><a id="okButton" href="#" class="button actionButton"
|
||||
<var:if condition="userHasRSVP"><a id="okButton" href="#" class="button actionButton"
|
||||
><span><var:string label:value="OK"/></span></a></var:if>
|
||||
<a id="cancelButton" href="#" class="button"
|
||||
><span><var:string label:value="Cancel"/></span></a>
|
||||
|
||||
@@ -796,22 +796,34 @@ TR#messageCountHeader TD
|
||||
{ padding: 0; }
|
||||
|
||||
#iCalAttendees SPAN
|
||||
{ line-height: 19px; }
|
||||
|
||||
#iCalAttendees DIV.status-icon
|
||||
{ background-repeat: no-repeat;
|
||||
background-position: 5px 1px;
|
||||
padding-left: 22px;
|
||||
padding-right: 4px; }
|
||||
float: left;
|
||||
padding: 0px;
|
||||
clear: both;
|
||||
width: 12px;
|
||||
height: 18px;
|
||||
margin-top: 1px;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
background-image: url("attendee-partstats.png"); }
|
||||
|
||||
#iCalAttendees .accepted
|
||||
{ background-image: url("accepted.png"); }
|
||||
#iCalAttendees .accepted DIV.status-icon
|
||||
{ background-position: 0px 0px; }
|
||||
|
||||
#iCalAttendees .needs-action
|
||||
{ background-image: url("needs-action.png"); }
|
||||
#iCalAttendees .declined DIV.status-icon
|
||||
{ background-position: -12px 0px; }
|
||||
|
||||
#iCalAttendees .declined
|
||||
{ background-image: url("declined.png"); }
|
||||
#iCalAttendees .needs-action DIV.status-icon
|
||||
{ background-position: -24px 0px; }
|
||||
|
||||
#iCalAttendees .delegated
|
||||
{ background-image: url("delegated.png"); }
|
||||
#iCalAttendees .tentative DIV.status-icon
|
||||
{ background-position: -36px 0px; }
|
||||
|
||||
#iCalAttendees .delegated DIV.status-icon
|
||||
{ background-position: -48px 0px; }
|
||||
|
||||
#iCalAttendees .attendeeUser,
|
||||
#iCalAttendees .attendeeUser A
|
||||
|
||||
@@ -1330,18 +1330,23 @@ DIV.event.alarm DIV.text
|
||||
background-repeat: no-repeat;
|
||||
background-position: top right; }
|
||||
|
||||
DIV.eventInside.tentative,
|
||||
DIV.eventInside.needs-action
|
||||
{ border: 1px dotted #666;
|
||||
-moz-opacity: 0.6;
|
||||
{ -moz-opacity: 0.7;
|
||||
opacity: 0.7; }
|
||||
|
||||
DIV.eventInside.needs-action
|
||||
{ border: 2px dotted #000; }
|
||||
|
||||
DIV.eventInside.tentative DIV.text,
|
||||
DIV.eventInside.needs-action DIV.text
|
||||
{ top: 0px;
|
||||
left: 0px; }
|
||||
left: 2px; }
|
||||
|
||||
DIV.eventInside.delegated,
|
||||
DIV.eventInside.declined
|
||||
{ -moz-opacity: 0.3;
|
||||
opacity: 0.3; }
|
||||
{ -moz-opacity: 0.4;
|
||||
opacity: 0.4; }
|
||||
|
||||
/* event DnD */
|
||||
DIV.event DIV.topDragGrip,
|
||||
|
||||
@@ -25,7 +25,7 @@ var calendarEvents = null;
|
||||
|
||||
var preventAutoScroll = false;
|
||||
|
||||
var userStates = [ "needs-action", "accepted", "declined", "tentative" ];
|
||||
var userStates = [ "needs-action", "accepted", "declined", "tentative", "delegated" ];
|
||||
|
||||
var calendarHeaderAdjusted = false;
|
||||
|
||||
@@ -297,7 +297,7 @@ function closeInvitationWindow() {
|
||||
|
||||
function modifyEventCallback(http) {
|
||||
if (http.readyState == 4) {
|
||||
if (http.status == 200) {
|
||||
if (isHttpStatus204(http.status) || http.status == 200) {
|
||||
var mailInvitation = queryParameters["mail-invitation"];
|
||||
if (mailInvitation && mailInvitation.toLowerCase() == "yes")
|
||||
closeInvitationWindow();
|
||||
|
||||
@@ -122,42 +122,53 @@ A#attendeesHref
|
||||
text-decoration: underline; }
|
||||
|
||||
DIV#attendeesMenu LI
|
||||
{ padding-left: 10px; }
|
||||
{ padding-left: 10px;
|
||||
width: auto; }
|
||||
|
||||
DIV#attendeesMenu .attendee,
|
||||
DIV#attendeesMenu DIV
|
||||
DIV#attendeesMenu .attendeeUser
|
||||
{ font-weight: bold; }
|
||||
|
||||
DIV#attendeesMenu .opt-participant
|
||||
{ font-style: italic; }
|
||||
|
||||
DIV#attendeesMenu .non-participant A
|
||||
{ color: #888; }
|
||||
|
||||
#attendeesLabel DIV#attendeesMenu > DIV
|
||||
{ margin-left: 4px; }
|
||||
|
||||
#attendeesLabel DIV#attendeesMenu > DIV,
|
||||
DIV#attendeesMenu .attendee
|
||||
{ height: 18px; }
|
||||
|
||||
#attendeesLabel DIV#attendeesMenu .statusIcon
|
||||
{ margin-top: 4px; }
|
||||
|
||||
DIV#attendeesMenu .statusIcon
|
||||
{ background-repeat: no-repeat;
|
||||
background-position: 5px center;
|
||||
padding-left: 22px; }
|
||||
float: left;
|
||||
width: 12px;
|
||||
height: 14px;
|
||||
margin-right: 4px;
|
||||
background-image: url("attendee-partstats.png"); }
|
||||
|
||||
DIV#attendeesMenu .accepted
|
||||
{ background-image: url("accepted.png"); }
|
||||
DIV#attendeesMenu .accepted .statusIcon
|
||||
{ background-position: 0px 0px; }
|
||||
|
||||
DIV#attendeesMenu .accepted:hover
|
||||
{ background-image: url("accepted.selected.png"); }
|
||||
DIV#attendeesMenu .declined .statusIcon
|
||||
{ background-position: -12px 0px; }
|
||||
|
||||
DIV#attendeesMenu .needs-action
|
||||
{ background-image: url("needs-action.png"); }
|
||||
DIV#attendeesMenu .needs-action .statusIcon
|
||||
{ background-position: -24px 0px; }
|
||||
|
||||
DIV#attendeesMenu .needs-action:hover
|
||||
{ background-image: url("needs-action.selected.png"); }
|
||||
DIV#attendeesMenu .tentative .statusIcon
|
||||
{ background-position: -36px 0px; }
|
||||
|
||||
DIV#attendeesMenu .declined
|
||||
{ background-image: url("declined.png"); }
|
||||
DIV#attendeesMenu .delegated .statusIcon
|
||||
{ background-position: -48px 0px; }
|
||||
|
||||
DIV#attendeesMenu .declined:hover
|
||||
{ background-image: url("declined.selected.png"); }
|
||||
|
||||
DIV#attendeesMenu .delegated
|
||||
{ background-image: url("delegated.png"); }
|
||||
|
||||
DIV#attendeesMenu .delegated:hover
|
||||
{ background-image: url("delegated.selected.png"); }
|
||||
DIV#attendeesMenu .no-partstat .statusIcon
|
||||
{ background-position: -60px 0px; }
|
||||
|
||||
DIV#attendeesMenu .delegate
|
||||
{ background-position: 15px center;
|
||||
padding-left: 32px; }
|
||||
|
||||
/* read-only view */
|
||||
DIV#attendeesMenu DIV
|
||||
{ padding-left: 20px; }
|
||||
{ padding-left: 16px !important; }
|
||||
|
||||
@@ -164,7 +164,7 @@ function addContact(tag, fullContactName, contactId, contactName, contactEmail)
|
||||
|
||||
function saveEvent(sender) {
|
||||
if (validateAptEditor()) {
|
||||
document.forms['editform'].attendees.value = attendees.toJSON();
|
||||
document.forms['editform'].attendees.value = $(attendees).toJSON();
|
||||
document.forms['editform'].submit();
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ function initTimeWidgets(widgets) {
|
||||
}
|
||||
}
|
||||
|
||||
function refreshAttendeesRO () {
|
||||
function refreshAttendeesRO() {
|
||||
var attendeesMenu = $("attendeesMenu");
|
||||
var attendeesLabel = $("attendeesLabel");
|
||||
var attendeesDiv = $("attendeesDiv");
|
||||
@@ -323,7 +323,7 @@ function refreshAttendees(newAttendees) {
|
||||
var attendeesMenu = $("attendeesMenu");
|
||||
|
||||
if (!attendeesHref)
|
||||
return refreshAttendeesRO ();
|
||||
return refreshAttendeesRO();
|
||||
|
||||
if (attendeesMenu)
|
||||
attendeesMenu = $("attendeesMenu").down("ul");
|
||||
@@ -337,9 +337,10 @@ function refreshAttendees(newAttendees) {
|
||||
if (menuItems && attendeesMenu)
|
||||
for (var i = 0; i < menuItems.length; i++)
|
||||
attendeesMenu.removeChild(menuItems[i]);
|
||||
|
||||
if (newAttendees)
|
||||
attendees = $H(newAttendees.evalJSON(true));
|
||||
|
||||
if (newAttendees) {
|
||||
attendees = $H(newAttendees.evalJSON());
|
||||
}
|
||||
|
||||
if (attendees.keys().length > 0) {
|
||||
// Update attendees link and show label
|
||||
@@ -353,13 +354,13 @@ function refreshAttendees(newAttendees) {
|
||||
if (attendeesMenu) {
|
||||
var delegatedTo = attendee.get('delegated-to');
|
||||
if (!attendee.get('delegated-from') || delegatedTo) {
|
||||
var node = document.createElement("li");
|
||||
var node = createElement("li");
|
||||
attendeesMenu.appendChild(node);
|
||||
setupAttendeeNode(node, attendee);
|
||||
}
|
||||
if (delegatedTo) {
|
||||
var delegate = attendees.get(delegatedTo);
|
||||
var node = document.createElement("li");
|
||||
var node = createElement("li");
|
||||
attendeesMenu.appendChild(node);
|
||||
setupAttendeeNode(node, $H(delegate), true);
|
||||
}
|
||||
@@ -384,13 +385,18 @@ function setupAttendeeNode(aNode, aAttendee, isDelegate) {
|
||||
// name = email;
|
||||
name = name || email;
|
||||
|
||||
$(aNode).writeAttribute("email", email);
|
||||
$(aNode).addClassName("attendee");
|
||||
$(aNode).addClassName(aAttendee.get('partstat'));
|
||||
aNode.writeAttribute("email", email);
|
||||
aNode.addClassName("attendee");
|
||||
var partstat = aAttendee.get('partstat');
|
||||
if (!partstat)
|
||||
partstat = "no-partstat";
|
||||
aNode.addClassName(partstat);
|
||||
if (isDelegate)
|
||||
$(aNode).addClassName("delegate");
|
||||
aNode.addClassName("delegate");
|
||||
var statusIconNode = createElement("div", null, "statusIcon");
|
||||
aNode.appendChild(statusIconNode);
|
||||
aNode.appendChild(document.createTextNode(name));
|
||||
$(aNode).observe("click", onMailTo);
|
||||
aNode.observe("click", onMailTo);
|
||||
}
|
||||
|
||||
function initializeAttendeesHref() {
|
||||
@@ -410,8 +416,8 @@ function onAttendeesHrefClick(event) {
|
||||
}
|
||||
|
||||
function onMailTo(event) {
|
||||
var target = getTarget(event);
|
||||
var address = target.firstChild.nodeValue.trim() + " <" + target.readAttribute("email") + ">";
|
||||
var target = $(getTarget(event));
|
||||
var address = target.lastChild.nodeValue.trim() + " <" + target.readAttribute("email") + ">";
|
||||
openMailTo(address);
|
||||
Event.stop(event);
|
||||
return false;
|
||||
|
||||
@@ -48,20 +48,62 @@ TABLE#freeBusy TD.freeBusyAttendees DIV
|
||||
TABLE#freeBusy TD.freeBusyData DIV
|
||||
{ overflow: scroll; }
|
||||
|
||||
TABLE#freeBusyAttendees TR.needs-action TD.attendees
|
||||
{ background-image: url("needs-action.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5px center; }
|
||||
TABLE#freeBusyAttendees TD.attendeeStatus
|
||||
{ width: 24px;
|
||||
min-width: 24px;
|
||||
max-width: 24px; }
|
||||
|
||||
TABLE#freeBusyAttendees TR.declined TD.attendees
|
||||
{ background-image: url("declined.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5px center; }
|
||||
TABLE#freeBusyAttendees TD.attendeeStatus DIV
|
||||
{ width: 12px;
|
||||
min-width: 12px;
|
||||
max-width: 24px;
|
||||
background-image: none; }
|
||||
|
||||
TABLE#freeBusyAttendees TR.accepted TD.attendees
|
||||
{ background-image: url("accepted.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5px center; }
|
||||
UL.roles-legend SPAN.role-icon
|
||||
{ display: block;
|
||||
float: left; }
|
||||
|
||||
UL.roles-legend SPAN.role-icon,
|
||||
TABLE#freeBusyAttendees TR.attendee-row TD.attendeeStatus DIV
|
||||
{ background-repeat: no-repeat;
|
||||
width: 24px;
|
||||
height: 20px;
|
||||
background-image: url("attendee-roles.png"); }
|
||||
|
||||
LI[role="req-participant"] > SPAN.role-icon,
|
||||
TABLE#freeBusyAttendees TR[role="req-participant"].attendee-row TD.attendeeStatus DIV
|
||||
{ background-position: 0px 4px; }
|
||||
|
||||
LI[role="opt-participant"] > SPAN.role-icon,
|
||||
TABLE#freeBusyAttendees TR[role="opt-participant"].attendee-row TD.attendeeStatus DIV
|
||||
{ background-position: -24px 4px; }
|
||||
|
||||
LI[role="non-participant"] > SPAN.role-icon,
|
||||
TABLE#freeBusyAttendees TR[role="non-participant"].attendee-row TD.attendeeStatus DIV
|
||||
{ background-position: -72px 4px; }
|
||||
|
||||
LI[role="chair"] > SPAN.role-icon,
|
||||
TABLE#freeBusyAttendees TR[role="chair"].attendee-row TD.attendeeStatus DIV
|
||||
{ background-position: -48px 4px; }
|
||||
|
||||
TABLE#freeBusyAttendees TR.organizer-row TD.attendeeStatus DIV
|
||||
{ background-repeat: no-repeat;
|
||||
width: 12px;
|
||||
height: 18px;
|
||||
margin-left: 6px;
|
||||
background-image: url("attendee-partstats.png"); }
|
||||
|
||||
TABLE#freeBusyAttendees TR[partstat="accepted"].organizer-row TD.attendeeStatus DIV
|
||||
{ background-position: 0px 4px; }
|
||||
|
||||
TABLE#freeBusyAttendees TR[partstat="declined"].organizer-row TD.attendeeStatus DIV
|
||||
{ background-position: -12px 4px; }
|
||||
|
||||
TABLE#freeBusyAttendees TR[partstat="needs-action"].organizer-row TD.attendeeStatus DIV
|
||||
{ background-position: -24px 4px; }
|
||||
|
||||
TABLE#freeBusyAttendees TR[partstat="tentative"].organizer-row TD.attendeeStatus DIV
|
||||
{ background-position: -36px 4px; }
|
||||
|
||||
TABLE#freeBusyHeader TR.freeBusyHeader2 TH
|
||||
{ font-weight: normal; }
|
||||
@@ -112,8 +154,7 @@ TABLE#freeBusyAttendees TD.attendees INPUT
|
||||
background-position: 4px center;
|
||||
border: 0px;
|
||||
width: 12em;
|
||||
padding-left: 24px;
|
||||
margin-left: 2em; }
|
||||
padding-left: 24px; }
|
||||
|
||||
TABLE#freeBusyAttendees TR.futureAttendee INPUT
|
||||
{ background-image: none;
|
||||
@@ -124,9 +165,6 @@ TABLE#freeBusyData TR.futureData TD
|
||||
{ border: 0;
|
||||
line-height: 3em; }
|
||||
|
||||
TABLE#freeBusyAttendees TR.futureAttendee TD A
|
||||
{ margin-left: 20px; }
|
||||
|
||||
SPAN.freeBusyZoneElement
|
||||
{ display: block;
|
||||
float: left;
|
||||
@@ -165,32 +203,29 @@ DIV#legend
|
||||
DIV#legend UL
|
||||
{ cursor: default;
|
||||
float: left;
|
||||
width: 30%;
|
||||
margin: 0px;
|
||||
margin-right: 10px;
|
||||
padding: 0px;
|
||||
line-height: 1.5em;
|
||||
list-style-type: none;
|
||||
list-style-image: none; }
|
||||
|
||||
DIV#legend UL LI
|
||||
{ white-space: nowrap;
|
||||
DIV#legend LI
|
||||
{ height: 20px;
|
||||
white-space: nowrap;
|
||||
margin: 0px;
|
||||
padding: 0px; }
|
||||
|
||||
DIV#legend UL IMG
|
||||
{ margin-right: .5em; }
|
||||
|
||||
DIV#legend UL LI SPAN.colorBox
|
||||
UL.freebusy-legend SPAN.colorBox
|
||||
{ float: left;
|
||||
margin-right: .5em; }
|
||||
|
||||
SPAN.colorBox
|
||||
{ display: block;
|
||||
float: right;
|
||||
border: 1px solid #333;
|
||||
margin: .12em;
|
||||
width: 1em;
|
||||
height: .75em; }
|
||||
margin-top: 5px;
|
||||
margin-right: 2px;
|
||||
display: block;
|
||||
border: 1px solid #999;
|
||||
border-left: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
border-bottom: 1px solid #eee;
|
||||
width: 32px;
|
||||
height: 10px; }
|
||||
|
||||
SPAN.colorBox.busy,
|
||||
SPAN.freeBusyZoneElement.busy
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
var OwnerLogin = "";
|
||||
|
||||
var resultsDiv;
|
||||
var address;
|
||||
var awaitingFreeBusyRequests = new Array();
|
||||
@@ -16,7 +18,6 @@ var attendeesEditor = {
|
||||
selectedIndex: -1
|
||||
};
|
||||
|
||||
|
||||
function handleAllDay () {
|
||||
window.timeWidgets['end']['hour'].value = 17;
|
||||
window.timeWidgets['end']['minute'].value = 0;
|
||||
@@ -189,8 +190,23 @@ function performSearchCallback(http) {
|
||||
if (data.contacts.length == 1) {
|
||||
// Single result
|
||||
var contact = data.contacts[0];
|
||||
if (contact["uid"].length > 0)
|
||||
if (contact["uid"].length > 0) {
|
||||
var row = $(input.parentNode.parentNode);
|
||||
input.uid = contact["uid"];
|
||||
if (input.uid == OwnerLogin) {
|
||||
row.removeAttribute("role");
|
||||
row.setAttribute("partstat", "accepted");
|
||||
row.addClassName("organizer-row");
|
||||
row.removeClassName("attendee-row");
|
||||
row.isOrganizer = true;
|
||||
} else {
|
||||
row.removeAttribute("partstat");
|
||||
row.setAttribute("role", "req-participant");
|
||||
row.addClassName("attendee-row");
|
||||
row.removeClassName("organizer-row");
|
||||
row.isOrganizer = false;
|
||||
}
|
||||
}
|
||||
var completeEmail = contact["name"] + " <" + contact["email"] + ">";
|
||||
if (contact["name"].substring(0, input.value.length).toUpperCase()
|
||||
== input.value.toUpperCase())
|
||||
@@ -284,17 +300,54 @@ function redisplayFreeBusyZone() {
|
||||
scrollToEvent();
|
||||
}
|
||||
|
||||
function onAttendeeStatusClick(event) {
|
||||
rotateAttendeeStatus(this);
|
||||
}
|
||||
|
||||
function rotateAttendeeStatus(row) {
|
||||
var values;
|
||||
var attributeName;
|
||||
if (row.isOrganizer) {
|
||||
values = [ "accepted", "declined", "tentative", "needs-action" ];
|
||||
attributeName = "partstat";
|
||||
} else {
|
||||
values = [ "req-participant", "opt-participant",
|
||||
"chair", "non-participant" ];
|
||||
attributeName = "role";
|
||||
}
|
||||
var value = row.getAttribute(attributeName);
|
||||
var idx = (value ? values.indexOf(value) : -1);
|
||||
if (idx == -1 || idx > (values.length - 2)) {
|
||||
idx = 0;
|
||||
} else {
|
||||
idx++;
|
||||
}
|
||||
row.setAttribute(attributeName, values[idx]);
|
||||
if (Prototype.Browser.IE) {
|
||||
/* This hack enables a refresh of the row element right after the
|
||||
click. Otherwise, this occurs only when leaving the element with
|
||||
them mouse cursor. */
|
||||
row.className = row.className;
|
||||
}
|
||||
}
|
||||
|
||||
function newAttendee(event) {
|
||||
var table = $("freeBusyAttendees");
|
||||
var tbody = table.tBodies[0];
|
||||
var model = tbody.rows[tbody.rows.length - 1];
|
||||
var futureRow = tbody.rows[tbody.rows.length - 2];
|
||||
var newRow = model.cloneNode(true);
|
||||
var newRow = $(model.cloneNode(true));
|
||||
tbody.insertBefore(newRow, futureRow);
|
||||
|
||||
|
||||
var statusTD = newRow.down(".attendeeStatus");
|
||||
if (statusTD) {
|
||||
var boundOnStatusClick = onAttendeeStatusClick.bindAsEventListener(newRow);
|
||||
statusTD.observe("click", boundOnStatusClick, false);
|
||||
}
|
||||
|
||||
$(newRow).removeClassName("attendeeModel");
|
||||
|
||||
var input = $(newRow).down("input");
|
||||
var input = newRow.down("input");
|
||||
input.observe("keydown", onContactKeydown);
|
||||
input.observe("blur", checkAttendee);
|
||||
|
||||
@@ -305,9 +358,9 @@ function newAttendee(event) {
|
||||
tbody = table.tBodies[0];
|
||||
model = tbody.rows[tbody.rows.length - 1];
|
||||
futureRow = tbody.rows[tbody.rows.length - 2];
|
||||
newRow = model.cloneNode(true);
|
||||
newRow = $(model.cloneNode(true));
|
||||
tbody.insertBefore(newRow, futureRow);
|
||||
$(newRow).removeClassName("dataModel");
|
||||
newRow.removeClassName("dataModel");
|
||||
|
||||
var attendeesDiv = $$('TABLE#freeBusy TD.freeBusyAttendees DIV').first();
|
||||
var dataDiv = $$('TABLE#freeBusy TD.freeBusyData DIV').first();
|
||||
@@ -315,7 +368,7 @@ function newAttendee(event) {
|
||||
dataDiv.scrollTop = attendeesDiv.scrollTop;
|
||||
}
|
||||
|
||||
function checkAttendee() { log ("checkAttendee");
|
||||
function checkAttendee() { // log ("checkAttendee");
|
||||
if (document.currentPopupMenu)
|
||||
hideMenu(document.currentPopupMenu);
|
||||
|
||||
@@ -335,17 +388,11 @@ function checkAttendee() { log ("checkAttendee");
|
||||
var dataRow = dataTable.rows[row.sectionRowIndex];
|
||||
tbody.removeChild(row);
|
||||
dataTable.removeChild(dataRow);
|
||||
}
|
||||
}
|
||||
else if (this.readAttribute("modified") == "1") {
|
||||
if (!$(row).hasClassName("needs-action")) {
|
||||
$(row).addClassName("needs-action");
|
||||
$(row).removeClassName("declined");
|
||||
$(row).removeClassName("accepted");
|
||||
}
|
||||
if (!this.hasfreebusy) {
|
||||
if (this.uid && this.confirmedValue)
|
||||
this.value = this.confirmedValue;
|
||||
log ("4");
|
||||
displayFreeBusyForNode(this);
|
||||
this.hasfreebusy = true;
|
||||
}
|
||||
@@ -357,7 +404,8 @@ function checkAttendee() { log ("checkAttendee");
|
||||
|
||||
function displayFreeBusyForNode(input) {
|
||||
var rowIndex = input.parentNode.parentNode.sectionRowIndex;
|
||||
var nodes = $("freeBusyData").tBodies[0].rows[rowIndex].cells; log ("displayFreeBusyForNode index " + rowIndex + " (" + nodes.length + " cells)");
|
||||
var nodes = $("freeBusyData").tBodies[0].rows[rowIndex].cells;
|
||||
log ("displayFreeBusyForNode index " + rowIndex + " (" + nodes.length + " cells)");
|
||||
if (input.uid) {
|
||||
if (document.contactFreeBusyAjaxRequest) { log ("busy -- delay " + rowIndex);
|
||||
awaitingFreeBusyRequests.push(input); }
|
||||
@@ -453,7 +501,7 @@ function initializeWindowButtons() {
|
||||
$("nextSlot").observe ("click", onNextSlotClick, false);
|
||||
}
|
||||
|
||||
function findSlot (direction) {
|
||||
function findSlot(direction) {
|
||||
var userList = UserLogin;
|
||||
var table = $("freeBusy");
|
||||
var inputs = table.getElementsByTagName("input");
|
||||
@@ -565,7 +613,7 @@ function onNextSlotClick(event) {
|
||||
|
||||
function onEditorOkClick(event) {
|
||||
preventDefault(event);
|
||||
|
||||
|
||||
var attendees = window.opener.attendees;
|
||||
var newAttendees = new Hash();
|
||||
var table = $("freeBusy");
|
||||
@@ -582,12 +630,20 @@ function onEditorOkClick(event) {
|
||||
name = inputs[i].uid;
|
||||
else
|
||||
name = email;
|
||||
var attendee = attendees.get(email);
|
||||
if (!attendee)
|
||||
attendee = new Hash({'email': email,
|
||||
'name': name,
|
||||
'uid': uid,
|
||||
'partstat': 'needs-action'});
|
||||
var attendee = attendees["email"];
|
||||
if (!attendee) {
|
||||
attendee = {"email": email,
|
||||
"name": name,
|
||||
"role": "req-participant",
|
||||
"partstat": "needs-action",
|
||||
"uid": uid};
|
||||
}
|
||||
var partstat = row.getAttribute("partstat");
|
||||
if (partstat)
|
||||
attendee["partstat"] = partstat;
|
||||
var role = row.getAttribute("role");
|
||||
if (role)
|
||||
attendee["role"] = role;
|
||||
newAttendees.set(email, attendee);
|
||||
}
|
||||
window.opener.refreshAttendees(newAttendees.toJSON());
|
||||
@@ -733,33 +789,51 @@ function prepareAttendees() {
|
||||
var modelData = tbodyData.rows[tbodyData.rows.length - 1];
|
||||
var newDataRow = tbodyData.rows[tbodyData.rows.length - 2];
|
||||
|
||||
attendees.values().each(function(attendee) {
|
||||
attendee = $H(attendee);
|
||||
var row = modelAttendee.cloneNode(true);
|
||||
tbodyAttendees.insertBefore(row, newAttendeeRow);
|
||||
$(row).removeClassName("attendeeModel");
|
||||
$(row).addClassName(attendee.get('partstat'));
|
||||
var input = $(row).down("input");
|
||||
var value = attendee.get('name');
|
||||
if (value)
|
||||
value += " ";
|
||||
else
|
||||
value = "";
|
||||
value += "<" + attendee.get('email') + ">";
|
||||
input.value = value;
|
||||
if (attendee.get('uid'))
|
||||
input.uid = attendee.get('uid');
|
||||
input.setAttribute("name", "");
|
||||
input.setAttribute("modified", "0");
|
||||
input.observe("blur", checkAttendee);
|
||||
input.observe("keydown", onContactKeydown);
|
||||
attendees.keys().each(function(atKey) {
|
||||
var attendee = attendees.get(atKey);
|
||||
// attendee = $H(attendee);
|
||||
var row = $(modelAttendee.cloneNode(true));
|
||||
tbodyAttendees.insertBefore(row, newAttendeeRow);
|
||||
row.removeClassName("attendeeModel");
|
||||
row.setAttribute("partstat", attendee["partstat"]);
|
||||
row.setAttribute("role", attendee["role"]);
|
||||
var uid = attendee["uid"];
|
||||
if (uid && uid == OwnerLogin) {
|
||||
row.addClassName("organizer-row");
|
||||
row.removeClassName("attendee-row");
|
||||
row.isOrganizer = true;
|
||||
} else {
|
||||
row.addClassName("attendee-row");
|
||||
row.removeClassName("organizer-row");
|
||||
row.isOrganizer = false;
|
||||
}
|
||||
var statusTD = row.down(".attendeeStatus");
|
||||
if (statusTD) {
|
||||
var boundOnStatusClick
|
||||
= onAttendeeStatusClick.bindAsEventListener(row);
|
||||
statusTD.observe("click", boundOnStatusClick, false);
|
||||
}
|
||||
|
||||
var input = row.down("input");
|
||||
var value = attendee["name"];
|
||||
if (value)
|
||||
value += " ";
|
||||
else
|
||||
value = "";
|
||||
value += "<" + attendee["email"] + ">";
|
||||
input.value = value;
|
||||
if (uid)
|
||||
input.uid = uid;
|
||||
input.setAttribute("name", "");
|
||||
input.setAttribute("modified", "0");
|
||||
input.observe("blur", checkAttendee);
|
||||
input.observe("keydown", onContactKeydown);
|
||||
|
||||
row = modelData.cloneNode(true);
|
||||
tbodyData.insertBefore(row, newDataRow);
|
||||
$(row).removeClassName("dataModel");
|
||||
log ("3");
|
||||
displayFreeBusyForNode(input);
|
||||
});
|
||||
row = $(modelData.cloneNode(true));
|
||||
tbodyData.insertBefore(row, newDataRow);
|
||||
row.removeClassName("dataModel");
|
||||
displayFreeBusyForNode(input);
|
||||
});
|
||||
}
|
||||
|
||||
// Activate "Add attendee" button
|
||||
@@ -799,6 +873,8 @@ function onFreeBusyLoadHandler() {
|
||||
'hour': $("endTime_time_hour"),
|
||||
'minute': $("endTime_time_minute")}};
|
||||
|
||||
OwnerLogin = window.opener.getOwnerLogin();
|
||||
|
||||
synchronizeWithParent("startTime", "startTime");
|
||||
synchronizeWithParent("endTime", "endTime");
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ var ComponentEditor = {
|
||||
reminderWindow: null
|
||||
};
|
||||
|
||||
function getOwnerLogin() {
|
||||
return ownerLogin;
|
||||
}
|
||||
|
||||
function onPopupAttendeesWindow(event) {
|
||||
if (event)
|
||||
preventDefault(event);
|
||||
@@ -202,7 +206,7 @@ function onSummaryChange (e) {
|
||||
|
||||
function onReplyChange(event) {
|
||||
var delegateEditor = $("delegateEditor");
|
||||
if (this.value == 2) {
|
||||
if (this.value == 4) {
|
||||
// Delegated
|
||||
delegateEditor.show();
|
||||
$("delegatedTo").focus();
|
||||
@@ -328,7 +332,11 @@ function onOkButtonClick (e) {
|
||||
action = 'accept';
|
||||
else if (value == 1)
|
||||
action = 'decline';
|
||||
else if (value == 2) {
|
||||
else if (value == 2)
|
||||
action = 'needsaction';
|
||||
else if (value == 3)
|
||||
action = 'tentative';
|
||||
else if (value == 4) {
|
||||
var url = ApplicationBaseURL + activeCalendar + '/' + activeComponent;
|
||||
document.modifyEventAjaxRequest = delegateInvitation(url, modifyEventCallback);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 510 B |
|
Before Width: | Height: | Size: 511 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 419 B |
|
Before Width: | Height: | Size: 354 B |
|
Before Width: | Height: | Size: 540 B |
|
Before Width: | Height: | Size: 452 B |
@@ -67,7 +67,7 @@ function createElement(tagName, id, classes,
|
||||
if (parentNode)
|
||||
parentNode.appendChild(newElement);
|
||||
|
||||
return $(newElement);
|
||||
return newElement;
|
||||
}
|
||||
|
||||
function URLForFolderID(folderID) {
|
||||
|
||||
@@ -83,6 +83,10 @@ DIV#attendeesMenu LI.separator
|
||||
DIV#attendeesView
|
||||
{ left: 0.5em; }
|
||||
|
||||
TABLE#freeBusyAttendees TD.attendeeStatus,
|
||||
TABLE#freeBusyAttendees TD.attendeeStatus DIV
|
||||
{ width: 24px; }
|
||||
|
||||
TABLE
|
||||
{ empty-cells: show; }
|
||||
|
||||
@@ -100,6 +104,18 @@ DIV#propertiesView LEGEND
|
||||
|
||||
/* UIxMailPartICalViewer */
|
||||
|
||||
#iCalAttendees SPAN
|
||||
{ display: block;
|
||||
height: 18px;
|
||||
border: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px; }
|
||||
|
||||
#iCalAttendees DIV.status-icon
|
||||
{ margin-top: 2px;
|
||||
border: 0px;
|
||||
padding: 0px; }
|
||||
|
||||
.clear
|
||||
{ padding-top: 0; }
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 506 B |
|
Before Width: | Height: | Size: 428 B |