Branch 'dev/recurring-invitations' - plugins/calendar plugins/libcalendaring
Thomas Brüderli
bruederli at kolabsys.com
Mon Feb 16 15:36:45 CET 2015
plugins/calendar/calendar_ui.js | 33 +++++++++++++++------
plugins/calendar/skins/larry/calendar.css | 20 +-----------
plugins/libcalendaring/lib/libcalendaring_itip.php | 12 ++-----
plugins/libcalendaring/libcalendaring.js | 33 +++++++++++++++++++++
plugins/libcalendaring/localization/en_US.inc | 4 +-
5 files changed, 67 insertions(+), 35 deletions(-)
New commits:
commit fe64e05e48c11b809bde1a32161dcdce3e1e2ea3
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Mon Feb 16 15:36:25 2015 +0100
Render a menu to select the RSVP mode for recurring events instead of using radio buttons
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index ec83d1b..fcd360a 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -557,11 +557,11 @@ function rcube_calendar_ui(settings)
if (event.recurrence && event.id) {
var sel = event._savemode || (event.thisandfuture ? 'future' : (event.isexception ? 'current' : 'all'));
- $('#event-rsvp input.rsvp-replymode[value="'+sel+'"]').prop('checked', true);
- $('#event-rsvp .rsvp-replymode-message').show();
+ $('#event-rsvp .rsvp-buttons').addClass('recurring');
+ }
+ else {
+ $('#event-rsvp .rsvp-buttons').removeClass('recurring');
}
- else
- $('#event-rsvp .rsvp-replymode-message').hide();
}
var buttons = [];
@@ -2378,14 +2378,31 @@ function rcube_calendar_ui(settings)
}
// when the user accepts or declines an event invitation
- var event_rsvp = function(response, delegate)
+ var event_rsvp = function(response, delegate, replymode)
{
+ var btn;
+ if (typeof response == 'object') {
+ btn = $(response);
+ response = btn.attr('rel')
+ }
+ else {
+ btn = $('#event-rsvp input.button[rel='+response+']');
+ }
+
+ // show menu to select rsvp reply mode (current or all)
+ if (me.selected_event && me.selected_event.recurrence && !replymode) {
+ rcube_libcalendaring.itip_rsvp_recurring(btn, function(resp, mode) {
+ event_rsvp(resp, null, mode);
+ });
+ return;
+ }
+
if (me.selected_event && me.selected_event.attendees && response) {
// bring up delegation dialog
if (response == 'delegated' && !delegate) {
rcube_libcalendaring.itip_delegate_dialog(function(data) {
data.rsvp = data.rsvp ? 1 : '';
- event_rsvp('delegated', data);
+ event_rsvp('delegated', data, replymode);
});
return;
}
@@ -2419,7 +2436,7 @@ function rcube_calendar_ui(settings)
}
// submit status change to server
- var submit_data = $.extend({}, me.selected_event, { source:null, comment:$('#reply-comment-event-rsvp').val(), _savemode: $('input.rsvp-replymode:checked').val() }, (delegate || {})),
+ var submit_data = $.extend({}, me.selected_event, { source:null, comment:$('#reply-comment-event-rsvp').val(), _savemode: replymode || 'all' }, (delegate || {})),
noreply = $('#noreply-event-rsvp:checked').length ? 1 : 0;
// import event from mail (temporary iTip event)
@@ -4163,7 +4180,7 @@ function rcube_calendar_ui(settings)
});
$('#event-rsvp input.button').click(function(e) {
- event_rsvp($(this).attr('rel'))
+ event_rsvp(this)
});
$('#eventedit input.edit-recurring-savemode').change(function(e) {
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index 0fec69c..fef16bd 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -1063,24 +1063,8 @@ td.topalign {
text-align: center;
}
-.event-dialog-message .rsvp-replymode-message {
- margin-top: 0.8em;
- margin-bottom: 0.6em;
-}
-
-.event-dialog-message .rsvp-replymode-message .replymode-select {
- padding-left: 22px;
-}
-
-.event-dialog-message .rsvp-replymode-message label {
- color: inherit;
- margin-right: 0.4em;
- white-space: nowrap;
- min-width: 4em;
-}
-
-.event-dialog-message .rsvp-replymode-message input.rsvp-replymode {
- margin-right: 0.4em;
+.libcal-rsvp-replymode li a {
+ cursor: default;
}
#event-rsvp,
diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php
index f56463c..2eec27c 100644
--- a/plugins/libcalendaring/lib/libcalendaring_itip.php
+++ b/plugins/libcalendaring/lib/libcalendaring_itip.php
@@ -677,20 +677,16 @@ class libcalendaring_itip
}
}
+ foreach (array('all','current','future') as $mode) {
+ $this->rc->output->command('add_label', "rsvpmode$mode", $this->gettext("rsvpmode$mode"));
+ }
+
$savemode_radio = new html_radiobutton(array('name' => '_rsvpmode', 'class' => 'rsvp-replymode'));
return html::div($attrib,
html::div('label', $this->gettext('acceptinvitation')) .
html::div('rsvp-buttons',
$buttons .
- html::div(array('class' => 'rsvp-replymode-message', 'style' => 'display:none'),
- html::div('message', html::span('ui-icon ui-icon-alert', '') . $this->gettext('rsvprecurringevent')) .
- html::div('replymode-select',
- html::label(null, $savemode_radio->show('all', array('value' => 'all')) . $this->gettext('allevents')) .
- html::label(null, $savemode_radio->show(null, array('value' => 'current')) . $this->gettext('currentevent')) .
- html::label(null, $savemode_radio->show(null, array('value' => 'future')) . $this->gettext('futurevents'))
- )
- ) .
html::div('itip-reply-controls', $this->itip_rsvp_options_ui($attrib['id']))
)
);
diff --git a/plugins/libcalendaring/libcalendaring.js b/plugins/libcalendaring/libcalendaring.js
index a13ebf7..cd59f66 100644
--- a/plugins/libcalendaring/libcalendaring.js
+++ b/plugins/libcalendaring/libcalendaring.js
@@ -959,6 +959,39 @@ rcube_libcalendaring.itip_delegate_dialog = function(callback, selector)
};
/**
+ * Show a menu for selecting the RSVP reply mode
+ */
+rcube_libcalendaring.itip_rsvp_recurring = function(btn, callback)
+{
+ var mnu = $('<ul></ul>').addClass('popupmenu libcal-rsvp-replymode');
+
+ $.each(['all','current','future'], function(i, mode) {
+ $('<li><a>' + rcmail.get_label('rsvpmode'+mode, 'libcalendaring') + '</a>')
+ .attr('rel', mode)
+ .appendTo(mnu);
+ });
+
+ var action = btn.attr('rel');
+
+ // open the mennu
+ mnu.menu({
+ select: function(event, ui) {
+ callback(action, ui.item.attr('rel'));
+ }
+ })
+ .appendTo(document.body)
+ .position({ my: 'left top', at: 'left bottom+2', of: btn })
+ .data('action', action);
+
+ setTimeout(function() {
+ $(document).one('click', function() {
+ mnu.menu('destroy');
+ mnu.remove();
+ });
+ }, 100);
+};
+
+/**
*
*/
rcube_libcalendaring.remove_from_itip = function(event, task, title)
diff --git a/plugins/libcalendaring/localization/en_US.inc b/plugins/libcalendaring/localization/en_US.inc
index 992113a..ca7d1fd 100644
--- a/plugins/libcalendaring/localization/en_US.inc
+++ b/plugins/libcalendaring/localization/en_US.inc
@@ -108,7 +108,9 @@ $labels['acceptinvitation'] = 'Do you accept this invitation?';
$labels['acceptattendee'] = 'Accept participant';
$labels['declineattendee'] = 'Decline participant';
$labels['declineattendeeconfirm'] = 'Enter a message to the declined participant (optional):';
-$labels['rsvprecurringevent'] = 'This is a series of events! Does your response apply to all, this occurrence only or this and future occurrences?';
+$labels['rsvpmodeall'] = 'The entire series';
+$labels['rsvpmodecurrent'] = 'This occurrence';
+$labels['rsvpmodefuture'] = 'This and future occurrences';
$labels['itipsingleoccurrence'] = 'This is a <em>single occurrence</em> out of a series of events';
$labels['itipfutureoccurrence'] = 'Refers to <em>this and all future occurrences</em> of a series of events';
More information about the commits
mailing list