Display my participant status in event show disalog and allow to reply again, even if RSVP=false

This commit is contained in:
Thomas Bruederli 2014-07-09 13:13:11 +02:00
parent 4b3283a26f
commit 4ec72a56c1
7 changed files with 116 additions and 6 deletions

View file

@ -293,6 +293,7 @@ class calendar extends rcube_plugin
$this->ui->init_templates();
$this->rc->output->add_label('lowest','low','normal','high','highest','delete','cancel','uploading','noemailwarning','close');
$this->rc->output->add_label('libcalendaring.itipaccepted','libcalendaring.itiptentative','libcalendaring.itipdeclined','libcalendaring.itipdelegated');
// initialize attendees autocompletion
rcube_autocomplete_init();

View file

@ -451,7 +451,7 @@ function rcube_calendar_ui(settings)
return (j - k);
});
var data, dispname, tooltip, organizer = false, rsvp = false, line, morelink, html = '',overflow = '';
var data, dispname, tooltip, organizer = false, rsvp = false, mystatus = null, line, morelink, html = '',overflow = '';
for (var j=0; j < event.attendees.length; j++) {
data = event.attendees[j];
dispname = Q(data.name || data.email);
@ -461,8 +461,11 @@ function rcube_calendar_ui(settings)
dispname = '<a href="mailto:' + data.email + '" class="mailtolink" data-cutype="' + data.cutype + '">' + dispname + '</a>';
if (data.role == 'ORGANIZER')
organizer = true;
else if ((data.status == 'NEEDS-ACTION' || data.status == 'TENTATIVE' || data.rsvp) && settings.identity.emails.indexOf(';'+data.email) >= 0)
rsvp = data.status.toLowerCase();
else if (settings.identity.emails.indexOf(';'+data.email) >= 0) {
mystatus = data.status.toLowerCase();
if (data.status == 'NEEDS-ACTION' || data.status == 'TENTATIVE' || data.rsvp)
rsvp = mystatus;
}
}
if (data['delegated-to'])
@ -502,9 +505,17 @@ function rcube_calendar_ui(settings)
})
}
}
if (mystatus && !rsvp) {
$('#event-partstat').show().children('.changersvp')
.removeClass('accepted tentative declined delegated needs-action')
.addClass(mystatus)
.children('.event-text')
.html(Q(rcmail.gettext('itip' + mystatus, 'libcalendaring')));
}
$('#event-rsvp')[(rsvp && !is_organizer(event) && event.status != 'CANCELLED' ? 'show' : 'hide')]();
$('#event-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+rsvp+']').prop('disabled', true);
$('#event-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+mystatus+']').prop('disabled', true);
$('#event-rsvp a.reply-comment-toggle').show();
$('#event-rsvp .itip-reply-comment textarea').hide().val('');
@ -3416,10 +3427,18 @@ function rcube_calendar_ui(settings)
$('<style type="text/css" id="workinghourscss"> td.offhours { opacity:0.3; filter:alpha(opacity=30) } </style>').appendTo('head');
});
$('#event-rsvp input.button').click(function(){
$('#event-rsvp input.button').click(function(e) {
event_rsvp($(this).attr('rel'))
});
$('#eventshow .changersvp').click(function(e) {
var d = $('#eventshow'),
h = $('#event-rsvp').show().height();
h -= $(this).closest('.event-line').toggle().height();
me.dialog_resize(d.get(0), d.height() + h, d.outerWidth() - 50);
return false;
})
$('#agenda-listrange').change(function(e){
settings['agenda_range'] = parseInt($(this).val());
fc.fullCalendar('option', 'listRange', settings['agenda_range']).fullCalendar('render');

View file

@ -63,6 +63,7 @@ $labels['free'] = 'Free';
$labels['busy'] = 'Busy';
$labels['outofoffice'] = 'Out of Office';
$labels['tentative'] = 'Tentative';
$labels['mystatus'] = 'My status';
$labels['status'] = 'Status';
$labels['confirmed'] = 'Confirmed';
$labels['cancelled'] = 'Cancelled';
@ -97,6 +98,7 @@ $labels['nrcalendarsfound'] = '$nr calendars found';
$labels['quickview'] = 'View only this calendar';
$labels['invitationspending'] = 'Pending invitations';
$labels['invitationsdeclined'] = 'Declined invitations';
$labels['changepartstat'] = 'Change participant status';
// agenda view
$labels['listrange'] = 'Range to display:';

View file

@ -568,6 +568,41 @@ a.miniColors-trigger {
margin-bottom: 0.3em;
}
#event-rsvp .itip-reply-controls {
margin-top: 0.5em;
}
#eventshow .itip-reply-controls label {
font-size: 1em;
color: #333;
}
#event-partstat .changersvp {
cursor: pointer;
color: #333;
text-decoration: none;
}
#event-partstat:hover .changersvp {
text-decoration: underline;
}
#event-partstat .changersvp.accepted {
color: #589b1e;
}
#event-partstat .changersvp.tentative {
color: #f0bb1d;
}
#event-partstat .changersvp.declined {
color: #ea0000;
}
#event-partstat .changersvp.delegated {
color: #018be9;
}
#eventedit {
position: relative;
padding: 0.5em 0.1em;
@ -1412,6 +1447,21 @@ span.spacer {
padding-right: 0.6em;
}
.fc-event-vert.fc-invitation-needs-action,
.fc-event-hori.fc-invitation-needs-action {
border: 1px dashed #5757c7 !important;
}
.fc-event-vert.fc-invitation-tentative,
.fc-event-hori.fc-invitation-tentative {
border: 1px dashed #eb8900 !important;
}
.fc-event-vert.fc-invitation-declined,
.fc-event-hori.fc-invitation-declined {
border: 1px dashed #c00 !important;
}
.fc-grid .fc-event-time {
font-weight: normal !important;
padding-right: 0.3em;

View file

@ -81,6 +81,12 @@
<h5 class="label"><roundcube:label name="calendar.tabattendees" /></h5>
<div class="event-text"></div>
</div>
<div class="event-line" id="event-partstat">
<label><roundcube:label name="calendar.mystatus" /></label>
<a href="#change" class="changersvp" title="<roundcube:label name='calendar.changepartstat' />">
<span class="event-text"></span>
</a>
</div>
<div class="event-line" id="event-calendar">
<label><roundcube:label name="calendar.calendar" /></label>
<span class="event-text">Default</span>

View file

@ -705,6 +705,26 @@ a.miniColors-trigger {
margin-bottom: 0.3em;
}
#eventshow div.event-line a.iconbutton {
margin-left: 0.5em;
line-height: 17px;
}
#event-partstat .changersvp {
cursor: pointer;
color: #333;
text-decoration: none;
}
#event-partstat .iconbutton {
visibility: hidden;
}
#event-partstat .changersvp:focus .iconbutton,
#event-partstat:hover .iconbutton {
visibility: visible;
}
#eventedit {
position: relative;
top: -1.5em;
@ -1832,6 +1852,7 @@ div.calendar-invitebox .rsvp-status.hint {
font-style: italic;
}
#event-partstat .changersvp,
div.calendar-invitebox .rsvp-status.declined,
div.calendar-invitebox .rsvp-status.tentative,
div.calendar-invitebox .rsvp-status.accepted,
@ -1841,18 +1862,22 @@ div.calendar-invitebox .rsvp-status.needs-action {
background: url(images/attendee-status.png) 2px -20px no-repeat;
}
#event-partstat .changersvp.declined,
div.calendar-invitebox .rsvp-status.declined {
background-position: 2px -40px;
}
#event-partstat .changersvp.tentative,
div.calendar-invitebox .rsvp-status.tentative {
background-position: 2px -60px;
}
#event-partstat .changersvp.delegated,
div.calendar-invitebox .rsvp-status.delegated {
background-position: 2px -180px;
}
#event-partstat .changersvp.needs-action,
div.calendar-invitebox .rsvp-status.needs-action {
background-position: 2px 0;
}

View file

@ -101,6 +101,13 @@
<h5 class="label"><roundcube:label name="calendar.tabattendees" /></h5>
<div class="event-text"></div>
</div>
<div class="event-line" id="event-partstat">
<label><roundcube:label name="calendar.mystatus" /></label>
<span class="changersvp" role="button" tabindex="0" title="<roundcube:label name='calendar.changepartstat' />">
<span class="event-text"></span>
<a class="iconbutton edit"><roundcube:label name='calendar.changepartstat' /></a>
</span>
</div>
<div class="event-line" id="event-calendar">
<label><roundcube:label name="calendar.calendar" /></label>
<span class="event-text">Default</span>