(feat) "Materialization" of the IMIP handling template
parent
fb992db5ad
commit
8124faa6d4
|
@ -1,6 +1,6 @@
|
|||
/* UIxMailPartICalActions.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2014 Inverse inc.
|
||||
* Copyright (C) 2007-2015 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -288,12 +288,15 @@
|
|||
// BOOL receiveUpdates;
|
||||
NSString *delegatedEmail, *delegatedUid;
|
||||
iCalPerson *delegatedAttendee;
|
||||
NSDictionary *content;
|
||||
SOGoUser *user;
|
||||
WORequest *request;
|
||||
WOResponse *response;
|
||||
|
||||
request = [context request];
|
||||
delegatedEmail = [request formValueForKey: @"to"];
|
||||
content = [[request contentAsString] objectFromJSONString];
|
||||
delegatedEmail = [content objectForKey: @"delegatedTo"];
|
||||
|
||||
if ([delegatedEmail length])
|
||||
{
|
||||
user = [context activeUser];
|
||||
|
@ -307,13 +310,14 @@
|
|||
delegatedUser = [SOGoUser userWithLogin: delegatedUid];
|
||||
[delegatedAttendee setCn: [delegatedUser cn]];
|
||||
}
|
||||
|
||||
[delegatedAttendee setRole: @"REQ-PARTICIPANT"];
|
||||
[delegatedAttendee setRsvp: @"TRUE"];
|
||||
[delegatedAttendee setParticipationStatus: iCalPersonPartStatNeedsAction];
|
||||
[delegatedAttendee setDelegatedFrom:
|
||||
[NSString stringWithFormat: @"mailto:%@", [[user allEmails] objectAtIndex: 0]]];
|
||||
|
||||
// receiveUpdates = [[request formValueForKey: @"receiveUpdates"] boolValue];
|
||||
// receiveUpdates = [[content objectForKey: @"receiveUpdates"] boolValue];
|
||||
// if (receiveUpdates)
|
||||
// [delegatedAttendee setRole: @"NON-PARTICIPANT"];
|
||||
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
/*
|
||||
Copyright (C) 2004-2005 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.
|
||||
* Copyright (C) 2007-2015 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef UIXMAILPARTICALVIEWER_H
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
Copyright (C) 2006-2013 Inverse inc.
|
||||
Copyright (C) 2006-2015 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
|
@ -182,6 +181,59 @@
|
|||
return date;
|
||||
}
|
||||
|
||||
/*
|
||||
In v3.0, we moved the template's logic here to format
|
||||
the event's start/end date-time. The previous logic was:
|
||||
|
||||
<dd><var:string value="startDate" />
|
||||
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
||||
<var:string value="startTime" />
|
||||
</var:if>
|
||||
<var:if condition="isEndDateOnSameDay">
|
||||
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
||||
<var:string label:value="to" />
|
||||
<var:string value="endTime" />
|
||||
</var:if>
|
||||
</var:if>
|
||||
<var:if condition="isEndDateOnSameDay" const:negate="YES">
|
||||
<var:string label:value="to" />
|
||||
<var:string value="endDate" />
|
||||
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
||||
<var:string value="endTime" />
|
||||
</var:if>
|
||||
</var:if>
|
||||
</dd>
|
||||
|
||||
*/
|
||||
- (NSString *) formattedDateTime
|
||||
{
|
||||
NSMutableString *s;
|
||||
|
||||
s = [NSMutableString string];
|
||||
|
||||
[s appendString: [self startDate]];
|
||||
|
||||
if (![[self inEvent] isAllDay])
|
||||
[s appendFormat: @" %@", [self startTime]];
|
||||
|
||||
if ([self isEndDateOnSameDay] &&
|
||||
![[self inEvent] isAllDay])
|
||||
{
|
||||
[s appendFormat: @" %@", [self labelForKey: @"to"]];
|
||||
[s appendFormat: @" %@", [self endTime]];
|
||||
}
|
||||
else if (![self isEndDateOnSameDay])
|
||||
{
|
||||
[s appendFormat: @" %@", [self labelForKey: @"to"]];
|
||||
[s appendFormat: @" %@", [self endDate]];
|
||||
|
||||
if (![[self inEvent] isAllDay])
|
||||
[s appendFormat: @" %@", [self endTime]];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
- (NSString *) startDate
|
||||
{
|
||||
return [[self dateFormatter] formattedDate: [self startCalendarDate]];
|
||||
|
@ -388,10 +440,7 @@
|
|||
|
||||
cssClass = [[attendee partStatWithDefault] lowercaseString];
|
||||
|
||||
if ([[attendee rfc822Email] isEqualToString: [self loggedInUserEMail]])
|
||||
cssClass = [cssClass stringByAppendingString: @" attendeeUser"];
|
||||
|
||||
return cssClass;
|
||||
return [NSString stringWithFormat: @"sg-%@", cssClass];
|
||||
}
|
||||
|
||||
/* derived fields */
|
||||
|
|
|
@ -328,6 +328,15 @@
|
|||
return url;
|
||||
}
|
||||
|
||||
- (NSString *) pathToAttachmentFromMessage
|
||||
{
|
||||
SOGoMailBodyPart *bodyPart;
|
||||
|
||||
bodyPart = [self clientPart];
|
||||
|
||||
return [NSString stringWithFormat: @"%@/%@", [bodyPart nameInContainer], [self _filenameForAttachment: bodyPart]];
|
||||
}
|
||||
|
||||
- (NSString *) pathToAttachment
|
||||
{
|
||||
return [self _pathForAttachmentOrDownload: NO];
|
||||
|
|
|
@ -43,11 +43,6 @@
|
|||
actionClass = "UIxMailPartICalActions";
|
||||
actionName = "updateUserStatus";
|
||||
};
|
||||
/* tentative = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailPartICalAction";
|
||||
actionName = "markTentative";
|
||||
}; */
|
||||
addToCalendar = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailPartICalActions";
|
||||
|
|
|
@ -14,11 +14,12 @@ th, td { font-family: Lucida Grande, Bitstream VeraSans, Tahoma, sans-serif; fon
|
|||
<body>
|
||||
<table cellpadding="2" cellspacing="2" border="0" style="width: 100%; max-width: 600px;">
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><h1 style="font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc;"><var:string
|
||||
value="getSubject" const:escapeHTML="NO"/> <small style="font-size: 12px; color: #999;"><var:string
|
||||
value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1></td>
|
||||
</tr>
|
||||
<th></th>
|
||||
<td><h1 style="font-size: 18px; font-weight: normal;
|
||||
padding-bottom: 9px; border-bottom: 1px solid #ccc;" class="ng-hide"><var:string
|
||||
value="getSubject" const:escapeHTML="NO"/> <small style="font-size: 12px; color: #999;"><var:string
|
||||
value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="right" style="font-weight: bold;"><var:string label:value="location_label" const:escapeHTML="NO"/></th>
|
||||
<td><var:string value="location" const:escapeHTML="NO"/></td>
|
||||
|
|
|
@ -15,7 +15,8 @@ th, td { font-family: Lucida Grande, Bitstream VeraSans, Tahoma, sans-serif; fon
|
|||
<table cellpadding="2" cellspacing="2" border="0" style="width: 100%; max-width: 600px;">
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><h1 style="font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc;"><var:string
|
||||
<td><h1 style="font-size: 18px; font-weight: normal;
|
||||
padding-bottom: 9px; border-bottom: 1px solid #ccc;" class="ng-hide"><var:string
|
||||
value="getSubject" const:escapeHTML="NO"/> <small style="font-size: 12px; color: #999;"><var:string
|
||||
value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1></td>
|
||||
</tr>
|
||||
|
|
|
@ -15,7 +15,8 @@ th, td { font-family: Lucida Grande, Bitstream VeraSans, Tahoma, sans-serif; fon
|
|||
<table cellpadding="2" cellspacing="2" border="0" style="width: 100%; max-width: 600px;">
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><h1 style="font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc;"><var:string
|
||||
<td><h1 style="font-size: 18px; font-weight: normal;
|
||||
padding-bottom: 9px; border-bottom: 1px solid #ccc;" class="ng-hide"><var:string
|
||||
value="getSubject" const:escapeHTML="NO"/> <small style="font-size: 12px; color: #999;"><var:string
|
||||
value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1></td>
|
||||
</tr>
|
||||
|
|
|
@ -4,173 +4,219 @@
|
|||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:label="OGo:label"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
class="linked_attachment_frame"
|
||||
>
|
||||
<!-- TODO: add iMIP actions -->
|
||||
|
||||
<input id="iCalendarAttachment" type="hidden"
|
||||
var:value="pathToAttachment"/>
|
||||
|
||||
xmlns:rsrc="OGo:url">
|
||||
|
||||
<!-- PARSING ERROR -->
|
||||
<var:if condition="couldParseCalendar" const:negate="1">
|
||||
<fieldset>
|
||||
<legend>Parsing Error</legend>
|
||||
|
||||
The SOGo/SOPE iCalendar parser could not parse the body of this MIME part.
|
||||
|
||||
<pre><var:string value="flatContentAsString" /></pre>
|
||||
</fieldset>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="couldParseCalendar">
|
||||
<div class="popupMenu" id="contactsMenu">
|
||||
<ul></ul>
|
||||
<div>
|
||||
<md-toolbar class="md-medium-tall md-warn md-hue-3">
|
||||
<div class="md-toolbar-tools">
|
||||
<h2>
|
||||
SOGo could not parse the body of this calendar MIME part.
|
||||
</h2>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-whiteframe class="md-whiteframe-z1" layout="row" layout-align="space-between center">
|
||||
<pre><var:string value="flatContentAsString" /></pre>
|
||||
</md-whiteframe>
|
||||
</div>
|
||||
<fieldset>
|
||||
<legend>
|
||||
<var:string label:value="Appointment"/>:
|
||||
<strong><var:string value="inEvent.summary" /></strong> <!-- TODO: shorted title -->
|
||||
|
||||
<var:if condition="isLoggedInUserTheOrganizer">
|
||||
(<var:string label:value="organized_by_you"/>)
|
||||
</var:if>
|
||||
<var:if condition="isLoggedInUserAnAttendee">
|
||||
(<var:string label:value="you_are_an_attendee"/>)
|
||||
</var:if>
|
||||
</legend>
|
||||
</var:if> <!-- if condition="couldParseCalendar" const:negate="1" -->
|
||||
|
||||
<!-- EVENT PROPERLY PARSED -->
|
||||
<var:if condition="couldParseCalendar">
|
||||
|
||||
<md-divider class="md-padding"/>
|
||||
|
||||
<div sg-imip="message" var:sg-imip-path="pathToAttachmentFromMessage">
|
||||
<!-- TODO - remove unused strings
|
||||
<legend>
|
||||
<var:string label:value="Appointment"/>:
|
||||
<strong><var:string value="inEvent.summary" /></strong>
|
||||
|
||||
<var:if condition="isLoggedInUserTheOrganizer">
|
||||
(<var:string label:value="organized_by_you"/>)
|
||||
</var:if>
|
||||
<var:if condition="isLoggedInUserAnAttendee">
|
||||
(<var:string label:value="you_are_an_attendee"/>)
|
||||
</var:if>
|
||||
</legend> -->
|
||||
|
||||
<!-- IMIP REQUEST -->
|
||||
<var:if condition="inCalendar.method.uppercaseString" const:value="REQUEST">
|
||||
<!-- sent to attendees to propose or update a meeting -->
|
||||
<var:if condition="isLoggedInUserAnAttendee">
|
||||
<var:if condition="hasCalendarAccess">
|
||||
<div class="uix_ical_toolbar" id="iCalendarToolbar">
|
||||
<p>
|
||||
<div>
|
||||
<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">
|
||||
<span><var:string label:value="Accept" /></span></a>
|
||||
</var:if>
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="DECLINED" const:negate="YES">
|
||||
<a href="#" class="button actionButton" id="iCalendarDecline">
|
||||
<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>
|
||||
<span id="delegateEditor" style="display: none;">
|
||||
<span class="floatLeft"><var:string label:value="Delegated to" /></span>
|
||||
<input name="delegatedTo" id="delegatedTo" type="text" />
|
||||
<a href="#" class="button actionButton" id="iCalendarDelegate" name="delegateOK">
|
||||
<span><var:string label:value="OK" /></span></a>
|
||||
</span>
|
||||
</var:if>
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="DELEGATED">
|
||||
<span id="delegateEditor">
|
||||
<span class="floatLeft"><var:string label:value="Delegated to" />
|
||||
<a var:href="currentUserAttendee.delegatedTo" name="delegatedToLink" id="delegatedToLink"><var:string value="currentUserAttendee.delegatedTo.rfc822Email" /></a></span>
|
||||
<input name="delegatedTo" id="delegatedTo" type="text" var:value="currentUserAttendee.delegatedTo.rfc822Email" var:uid="currentUserAttendee.delegatedTo.rfc822Email" style="display: none;" />
|
||||
<a href="#" class="button actionButton" id="iCalendarDelegate" style="display: none;">
|
||||
<span><var:string label:value="OK" /></span></a>
|
||||
</span>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="ACCEPTED" const:negate="YES">
|
||||
<md-button type="button" ng-click="iCalendarAction('accept')">
|
||||
<var:string label:value="Accept" />
|
||||
</md-button>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="DECLINED" const:negate="YES">
|
||||
<md-button type="button" ng-click="iCalendarAction('decline')">
|
||||
<var:string label:value="Decline" />
|
||||
</md-button>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="TENTATIVE" const:negate="YES">
|
||||
<md-button type="button" ng-click="iCalendarAction('tentative')">
|
||||
<var:string label:value="Tentative" />
|
||||
</md-button>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="DELEGATED" const:negate="YES">
|
||||
<md-button type="button"
|
||||
ng-click="delegateInvitation = true"
|
||||
ng-hide="delegateInvitation == true">
|
||||
<var:string label:value="Delegate ..." />
|
||||
</md-button>
|
||||
|
||||
<div class="md-actions" layout="row"
|
||||
layout-align="start center"
|
||||
ng-show="delegateInvitation == true">
|
||||
|
||||
<md-autocomplete
|
||||
class="md-flex"
|
||||
md-search-text="searchText"
|
||||
md-selected-item="delegatedTo"
|
||||
md-items="user in userFilter(searchText)"
|
||||
md-min-length="3"
|
||||
md-no-cache="true"
|
||||
md-item-text="user.$shortFormat()"
|
||||
label:md-floating-label="Delegated to">
|
||||
<span class="md-contact-suggestion" layout="row" layout-align="space-between center">
|
||||
<span class="md-contact-name"
|
||||
md-highlight-text="searchText"
|
||||
md-highlight-flags="^i">{{user.cn}}</span> <span class="md-contact-email"
|
||||
md-highlight-text="searchText"
|
||||
md-highlight-flags="^i">{{user.c_email}}</span>
|
||||
</span>
|
||||
</md-autocomplete>
|
||||
<md-button ng-click="delegateInvitation = false"><var:string label:value="Cancel"/></md-button>
|
||||
<md-button class="md-primitive"
|
||||
ng-click="iCalendarAction('delegate')"
|
||||
ng-disabled="!delegatedTo || delegatedTo.length == 0"><var:string label:value="OK"/></md-button>
|
||||
</div>
|
||||
</var:if>
|
||||
<!-- TODO - should we re-enable this? It never
|
||||
worked in v2!
|
||||
<var:if condition="currentUserAttendee.partStatWithDefault"
|
||||
const:value="DELEGATED">
|
||||
<span id="delegateEditor">
|
||||
<span class="floatLeft"><var:string label:value="Delegated to" />
|
||||
<a var:href="currentUserAttendee.delegatedTo" name="delegatedToLink" id="delegatedToLink"><var:string value="currentUserAttendee.delegatedTo.rfc822Email" /></a></span>
|
||||
<input name="delegatedTo" id="delegatedTo" type="text" var:value="currentUserAttendee.delegatedTo.rfc822Email" var:uid="currentUserAttendee.delegatedTo.rfc822Email" style="display: none;" />
|
||||
<a href="#" class="button actionButton" id="iCalendarDelegate" style="display: none;">
|
||||
<span><var:string label:value="OK" /></span></a>
|
||||
</span>
|
||||
</var:if>
|
||||
-->
|
||||
</var:if> <!-- if condition="currentUserAttendee.rsvp" const:value="true" -->
|
||||
|
||||
<var:if condition="isEventStoredInCalendar" const:negate="YES">
|
||||
<md-button type="button" ng-click="iCalendarAction('addToCalendar')">
|
||||
<var:string label:value="Add to calendar" />
|
||||
</md-button>
|
||||
</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>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</var:if> <!-- if condition="hasCalendarAccess" -->
|
||||
|
||||
<p>
|
||||
<var:string label:value="Organizer" />
|
||||
<a var:href="inEvent.organizer.email"
|
||||
><var:string value="organizerDisplayName" /></a>
|
||||
<var:string label:value="request_info" />
|
||||
</p>
|
||||
|
||||
</var:if> <!-- if condition="isLoggedInUserAnAttendee" -->
|
||||
|
||||
<var:if condition="isLoggedInUserAnAttendee" const:negate="YES">
|
||||
<p>
|
||||
<var:string label:value="Organizer" />
|
||||
<a var:href="inEvent.organizer.email">
|
||||
<var:string value="organizerDisplayName" />
|
||||
</a>
|
||||
<var:string label:value="request_info_no_attendee" />
|
||||
</p>
|
||||
</var:if>
|
||||
</p>
|
||||
</div>
|
||||
</var:if>
|
||||
|
||||
<p class="clear">
|
||||
<var:string label:value="Organizer" />
|
||||
<a var:href="inEvent.organizer.email"
|
||||
><var:string value="organizerDisplayName" /></a>
|
||||
<var:string label:value="request_info" />
|
||||
</p>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="isLoggedInUserAnAttendee" const:negate="YES">
|
||||
<p>
|
||||
<var:string label:value="Organizer" />
|
||||
<a var:href="inEvent.organizer.email"
|
||||
><var:string value="organizerDisplayName" /></a>
|
||||
<var:string label:value="request_info_no_attendee" />
|
||||
</p>
|
||||
</var:if>
|
||||
</var:if>
|
||||
|
||||
</var:if> <!-- if condition="inCalendar.method.uppercaseString"
|
||||
const:value="REQUEST" -->
|
||||
|
||||
<!-- IMIP REPLY - sent to organizer to update the status of the
|
||||
participant -->
|
||||
<var:if condition="inCalendar.method.uppercaseString" const:value="REPLY">
|
||||
<!-- sent to organizer to update the status of the participant -->
|
||||
<var:if condition="isReplySenderAnAttendee" const:negate="1">
|
||||
<p><var:string label:value="reply_info_no_attendee" /></p>
|
||||
<p>
|
||||
<var:string label:value="reply_info_no_attendee" />
|
||||
</p>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="isReplySenderAnAttendee">
|
||||
<var:if condition="canOriginalEventBeUpdated"
|
||||
><dl class="dl-horizontal">
|
||||
<dt><var:string label:value="Status Update" />:</dt>
|
||||
<dd><i><var:string label:value="$inReplyAttendee.partStatWithDefault" /></i>,
|
||||
<var:if condition="canOriginalEventBeUpdated">
|
||||
<p>
|
||||
<var:string label:value="Status Update" />:
|
||||
<i><var:string label:value="$inReplyAttendee.partStatWithDefault" /></i>,
|
||||
<var:string label:value="was" />
|
||||
<i><var:string label:value="$storedReplyAttendee.partStatWithDefault" /></i>.
|
||||
<br/><input id="iCalendarUpdateUserStatus" class="button"
|
||||
type="button" label:value="Update status"/></dd>
|
||||
</dl></var:if>
|
||||
<i><var:string label:value="$storedReplyAttendee.partStatWithDefault"/></i>.
|
||||
</p>
|
||||
<br/>
|
||||
<md-button type="button" ng-click="iCalendarAction('updateUserStatus')">
|
||||
<var:string label:value="Update status" />
|
||||
</md-button>
|
||||
</var:if>
|
||||
</var:if>
|
||||
</var:if>
|
||||
|
||||
<!-- IMIP CANCEL - sent to attendees to notify of the attendee
|
||||
being removed or the
|
||||
event being deleted -->
|
||||
<var:if condition="inCalendar.method.uppercaseString" const:value="CANCEL">
|
||||
<!-- sent to attendees to notify of the attendee being removed or the
|
||||
event being deleted -->
|
||||
<dl class="dl-horizontal">
|
||||
<dd><var:string label:value="cancel_info_text" />
|
||||
<p><var:string label:value="cancel_info_text" /></p>
|
||||
<var:if condition="isEventStoredInCalendar">
|
||||
<br/><a href="#" id="iCalendarDeleteFromCalendar" class="button">
|
||||
<span><var:string label:value="Delete from calendar" /></span></a>
|
||||
</var:if></dd>
|
||||
</dl>
|
||||
<md-button type="button" ng-click="iCalendarAction('deleteFromCalendar')">
|
||||
<var:string label:value="Delete from calendar" />
|
||||
</md-button>
|
||||
</var:if>
|
||||
</var:if>
|
||||
|
||||
<!-- IMIP ADD - TODO -->
|
||||
<var:if condition="inCalendar.method.uppercaseString" const:value="ADD">
|
||||
<!-- TODO -->
|
||||
<dl class="dl-horizontal">
|
||||
<dd><var:string label:value="add_info_text" /></dd>
|
||||
</dl>
|
||||
<p><var:string label:value="add_info_text" /></p>
|
||||
</var:if>
|
||||
|
||||
<!-- IMIP PUBLISH - none-scheduling event sent to someone for
|
||||
adding to the calendar -->
|
||||
<var:if condition="inCalendar.method.uppercaseString" const:value="PUBLISH">
|
||||
<!-- none-scheduling event sent to someone for adding to the calendar -->
|
||||
<dl class="dl-horizontal">
|
||||
<dd><var:string label:value="publish_info_text" /></dd>
|
||||
</dl>
|
||||
<p><var:string label:value="publish_info_text" /></p>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="isLoggedInUserTheOrganizer">
|
||||
<!--
|
||||
Possible Status:
|
||||
REPLY => check whether it matches, if not suggest change, show
|
||||
comment
|
||||
REFRESH => add button to resent iCal
|
||||
COUNTER => show panel to decide on counter
|
||||
Possible Status:
|
||||
REPLY => check whether it matches, if not suggest change, show
|
||||
comment
|
||||
REFRESH => add button to resent iCal
|
||||
COUNTER => show panel to decide on counter
|
||||
-->
|
||||
</var:if>
|
||||
<var:if condition="isLoggedInUserTheOrganizer" const:negate="1">
|
||||
<!--
|
||||
Possible Status:
|
||||
REQUEST => ACCEPT, TENTATIVELY, DECLINE buttons with comment field
|
||||
- only show buttons for attendees
|
||||
PUBLISH => just the 'add to calendar' button, rewrite organizer?
|
||||
ADD / CANCEL
|
||||
DECLINE-COUNTER
|
||||
Possible Status:
|
||||
REQUEST => ACCEPT, TENTATIVELY, DECLINE buttons with comment field
|
||||
- only show buttons for attendees
|
||||
PUBLISH => just the 'add to calendar' button, rewrite organizer?
|
||||
ADD / CANCEL
|
||||
DECLINE-COUNTER
|
||||
-->
|
||||
</var:if>
|
||||
|
||||
|
@ -181,57 +227,60 @@
|
|||
</div>
|
||||
<br />
|
||||
</var:if>
|
||||
|
||||
<div class="linked_attachment_meta" style="background-color: white;">
|
||||
<dl id="iCalAttendees" class="dl-horizontal">
|
||||
<dt><var:string label:value="Time"/>:</dt>
|
||||
<dd><var:string value="startDate" />
|
||||
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
||||
<var:string value="startTime" />
|
||||
</var:if>
|
||||
<var:if condition="isEndDateOnSameDay">
|
||||
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
||||
<var:string label:value="to" />
|
||||
<var:string value="endTime" />
|
||||
</var:if>
|
||||
</var:if>
|
||||
<var:if condition="isEndDateOnSameDay" const:negate="YES">
|
||||
<var:string label:value="to" />
|
||||
<var:string value="endDate" />
|
||||
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
||||
<var:string value="endTime" />
|
||||
</var:if>
|
||||
</var:if>
|
||||
</dd>
|
||||
|
||||
<dt><var:string label:value="Organizer"/>:</dt>
|
||||
<dd><a var:href="authorativeEvent.organizer.email"
|
||||
><var:string value="organizerDisplayName" /></a>
|
||||
</dd>
|
||||
<dt><var:string label:value="Attendees"/>:</dt>
|
||||
<var:foreach list="authorativeEvent.participants" item="attendee">
|
||||
<var:if condition="attendee.delegatedTo" const:negate="YES"><!-- don't show attendees that delegated the invitation --> <dd><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.length">, <var:string label:value="delegated from" /> <var:string value="attendee.delegatedFrom.rfc822Email" /></var:if>)</span>
|
||||
</dd></var:if>
|
||||
</var:foreach>
|
||||
|
||||
<var:if condition="authorativeEvent.comment.isNotEmpty">
|
||||
<dt><var:string label:value="Comment"/>:</dt>
|
||||
<dd><var:string value="authorativeEvent.comment" const:insertBR="1" /></dd>
|
||||
</var:if>
|
||||
</dl>
|
||||
<!-- EVENT'S METADATA (time, organizer, attendees, etc.) -->
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="Organizer"/></label>
|
||||
<div>
|
||||
<var:string value="organizerDisplayName"/>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</var:if><!-- could parse -->
|
||||
|
||||
<!--
|
||||
<var:string value="appointment" />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
-->
|
||||
<!-- <pre style="display: none;"><var:string value="flatContentAsString" /></pre> -->
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="Time"/></label>
|
||||
<div>
|
||||
<var:string value="formattedDateTime"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<md-list>
|
||||
|
||||
<header class="sg-md-subheader">
|
||||
<var:string label:value="Attendees"/>
|
||||
</header>
|
||||
|
||||
<var:foreach list="authorativeEvent.participants"
|
||||
item="attendee">
|
||||
<var:if condition="attendee.delegatedTo" const:negate="YES">
|
||||
<md-list-item>
|
||||
<div layout="row" layout-align="start center">
|
||||
<div var:class="currentAttendeeClass"><!-- accepted/declided/tentative/delegated --></div>
|
||||
<div class="md-list-item-text">
|
||||
<p><a var:href="attendee.email"><var:string value="attendeeForDisplay"/></a></p>
|
||||
<p>(<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.length">, <var:string label:value="delegated from" /> <var:string value="attendee.delegatedFrom.rfc822Email" /></var:if>)</p>
|
||||
</div>
|
||||
</div>
|
||||
</md-list-item>
|
||||
</var:if>
|
||||
</var:foreach>
|
||||
|
||||
</md-list>
|
||||
|
||||
<var:if condition="authorativeEvent.comment.isNotEmpty">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Comment"/>
|
||||
</label>
|
||||
<div>
|
||||
<p>
|
||||
<var:string value="authorativeEvent.comment" const:insertBR="1" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</var:if>
|
||||
</div>
|
||||
|
||||
</var:if><!--if condition="couldParseCalendar" -->
|
||||
|
||||
</div>
|
||||
|
|
|
@ -291,6 +291,25 @@
|
|||
return Message.$$resource.post(this.$mailbox.$id(), 'addOrRemoveLabel', data);
|
||||
};
|
||||
|
||||
/**
|
||||
* @function $imipAction
|
||||
* @memberof Message.prototype
|
||||
* @desc Perform IMIP actions on the current message.
|
||||
* @param {string} path - the path of the IMIP calendar part
|
||||
* @param {string} action - the the IMIP action to perform
|
||||
* @param {object} data - the delegation info
|
||||
*/
|
||||
Message.prototype.$imipAction = function(path, action, data) {
|
||||
var _this = this;
|
||||
Message.$$resource.post([this.id, path].join('/'), action, data).then(function(data) {
|
||||
Message.$timeout(function() {
|
||||
_this.$reload();
|
||||
}, function() {
|
||||
// TODO: show toast
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @function $markAsFlaggedOrUnflagged
|
||||
* @memberof Message.prototype
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* sgIMIP - A directive to handle IMIP actions on emails
|
||||
* @memberof SOGo.MailerUI
|
||||
* @ngInject
|
||||
* @example:
|
||||
|
||||
*/
|
||||
function sgImip() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: link,
|
||||
controller: controller
|
||||
};
|
||||
|
||||
function link(scope, iElement, attrs, ctrl) {
|
||||
ctrl.pathToAttachment = attrs.sgImipPath;
|
||||
}
|
||||
|
||||
controller.$inject = ['$scope', 'User'];
|
||||
|
||||
function controller($scope, User) {
|
||||
var vm = this;
|
||||
$scope.delegateInvitation = false;
|
||||
$scope.delegatedTo = '';
|
||||
$scope.searchText = '';
|
||||
|
||||
$scope.userFilter = function($query) {
|
||||
return User.$filter($query);
|
||||
};
|
||||
|
||||
$scope.iCalendarAction = function(action) {
|
||||
|
||||
var data;
|
||||
|
||||
if (action == 'delegate') {
|
||||
data = {receiveUpdates: false,
|
||||
delegatedTo: $scope.delegatedTo.c_email};
|
||||
}
|
||||
|
||||
$scope.message.$imipAction(vm.pathToAttachment, action, data);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
angular
|
||||
.module('SOGo.MailerUI')
|
||||
.directive('sgImip', sgImip);
|
||||
})();
|
||||
|
|
@ -85,3 +85,28 @@
|
|||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
.sg-accepted {
|
||||
@extend .md-tile-left-accepted;
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
.sg-declined {
|
||||
@extend .md-tile-left-declined;
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
.sg-delegated {
|
||||
@extend .md-tile-left-delegated;
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
.sg-needs-action {
|
||||
@extend .md-tile-left-needs-action;
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
.sg-tentative {
|
||||
@extend .md-tile-left-tentative;
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
|
@ -99,3 +99,31 @@ div.md-tile-left {
|
|||
@extend .md-tile-left;
|
||||
content: "\f299";
|
||||
}
|
||||
.md-tile-left-accepted:before {
|
||||
@extend .md-tile-left;
|
||||
background-color: rgba(0, 255, 0, 0.3) !important;
|
||||
content: "\f299";
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.md-tile-left-declined:before {
|
||||
@extend .md-tile-left;
|
||||
background-color: rgba(255, 0, 0, 0.3) !important;
|
||||
content: "\f111";
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.md-tile-left-delegated:before {
|
||||
@extend .md-tile-left;
|
||||
background-color: rgba(192, 192, 192, 0.3) !important;
|
||||
content: "\f298";
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.md-tile-left-needs-action:before {
|
||||
@extend .md-tile-left;
|
||||
background-color: rgba(255, 255, 0, 0.3) !important;
|
||||
content: "?";
|
||||
}
|
||||
.md-tile-left-tentative:before {
|
||||
@extend .md-tile-left;
|
||||
background-color: rgba(255, 255, 0, 0.3) !important;
|
||||
content: "\f2d8";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue