From fe64e05e48c11b809bde1a32161dcdce3e1e2ea3 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Mon, 16 Feb 2015 15:36:25 +0100 Subject: [PATCH] Render a menu to select the RSVP mode for recurring events instead of using radio buttons --- plugins/calendar/calendar_ui.js | 33 ++++++++++++++----- plugins/calendar/skins/larry/calendar.css | 20 ++--------- .../lib/libcalendaring_itip.php | 12 +++---- plugins/libcalendaring/libcalendaring.js | 33 +++++++++++++++++++ plugins/libcalendaring/localization/en_US.inc | 4 ++- 5 files changed, 67 insertions(+), 35 deletions(-) diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index ec83d1b0..fcd360ae 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 0fec69cb..fef16bd8 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 f56463c3..2eec27c8 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 a13ebf7e..cd59f66a 100644 --- a/plugins/libcalendaring/libcalendaring.js +++ b/plugins/libcalendaring/libcalendaring.js @@ -958,6 +958,39 @@ rcube_libcalendaring.itip_delegate_dialog = function(callback, selector) return dialog; }; +/** + * Show a menu for selecting the RSVP reply mode + */ +rcube_libcalendaring.itip_rsvp_recurring = function(btn, callback) +{ + var mnu = $('').addClass('popupmenu libcal-rsvp-replymode'); + + $.each(['all','current','future'], function(i, mode) { + $('
  • ' + rcmail.get_label('rsvpmode'+mode, 'libcalendaring') + '') + .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); +}; + /** * */ diff --git a/plugins/libcalendaring/localization/en_US.inc b/plugins/libcalendaring/localization/en_US.inc index 992113ad..ca7d1fd5 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 single occurrence out of a series of events'; $labels['itipfutureoccurrence'] = 'Refers to this and all future occurrences of a series of events';