Add button to iTip RSVP UI in mail view to open the calendar preview with an option to accept/decline the invitation from there (#3161)
This commit is contained in:
parent
7161b90e46
commit
09cf967ed5
9 changed files with 128 additions and 9 deletions
|
@ -309,10 +309,13 @@ class calendar extends rcube_plugin
|
|||
$view = get_input_value('view', RCUBE_INPUT_GPC);
|
||||
if (in_array($view, array('agendaWeek', 'agendaDay', 'month', 'table')))
|
||||
$this->rc->output->set_env('view', $view);
|
||||
|
||||
|
||||
if ($date = get_input_value('date', RCUBE_INPUT_GPC))
|
||||
$this->rc->output->set_env('date', $date);
|
||||
|
||||
if ($msgref = get_input_value('itip', RCUBE_INPUT_GPC))
|
||||
$this->rc->output->set_env('itip_events', $this->itip_events($msgref));
|
||||
|
||||
$this->rc->output->send("calendar.calendar");
|
||||
}
|
||||
|
||||
|
@ -1122,6 +1125,43 @@ class calendar extends rcube_plugin
|
|||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load event data from an iTip message attachment
|
||||
*/
|
||||
public function itip_events($msgref)
|
||||
{
|
||||
$path = explode('/', $msgref);
|
||||
$msg = array_pop($path);
|
||||
$mbox = join('/', $path);
|
||||
list($uid, $mime_id) = explode('#', $msg);
|
||||
$events = array();
|
||||
|
||||
if ($event = $this->lib->mail_get_itip_object($mbox, $uid, $mime_id, 'event')) {
|
||||
$partstat = 'NEEDS-ACTION';
|
||||
/*
|
||||
$user_emails = $this->lib->get_user_emails();
|
||||
foreach ($event['attendees'] as $attendee) {
|
||||
if (in_array($attendee['email'], $user_emails)) {
|
||||
$partstat = $attendee['status'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
$event['id'] = $event['uid'];
|
||||
$event['temporary'] = true;
|
||||
$event['readonly'] = true;
|
||||
$event['calendar'] = '--invitation--itip';
|
||||
$event['className'] = 'fc-invitation-' . strtolower($partstat);
|
||||
$event['_mbox'] = $mbox;
|
||||
$event['_uid'] = $uid;
|
||||
$event['_part'] = $mime_id;
|
||||
|
||||
$events[] = $this->_client_event($event, true);
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for keep-alive requests
|
||||
* This will check for updated data in active calendars and sync them to the client
|
||||
|
@ -2357,7 +2397,8 @@ class calendar extends rcube_plugin
|
|||
$ical_objects->method,
|
||||
$ical_objects->mime_id . ':' . $idx,
|
||||
'calendar',
|
||||
rcube_utils::anytodatetime($ical_objects->message_date)
|
||||
rcube_utils::anytodatetime($ical_objects->message_date),
|
||||
$this->rc->url(array('task' => 'calendar')) . '&view=agendaDay&date=' . $event['start']->format('U')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -2566,6 +2607,7 @@ class calendar extends rcube_plugin
|
|||
}
|
||||
|
||||
if ($success || $dontsave) {
|
||||
$metadata['calendar'] = $event['calendar'];
|
||||
$metadata['nosave'] = $dontsave;
|
||||
$metadata['rsvp'] = intval($metadata['rsvp']);
|
||||
$metadata['after_action'] = $this->rc->config->get('calendar_itip_after_action', $this->defaults['calendar_itip_after_action']);
|
||||
|
|
|
@ -599,7 +599,7 @@ function rcube_calendar_ui(settings)
|
|||
me.dialog_resize($dialog.get(0), $dialog.height(), 420);
|
||||
|
||||
// add link for "more options" drop-down
|
||||
if (!temp) {
|
||||
if (!temp && !event.temporary) {
|
||||
$('<a>')
|
||||
.attr('href', '#')
|
||||
.html(rcmail.gettext('eventoptions','calendar'))
|
||||
|
@ -2339,7 +2339,19 @@ function rcube_calendar_ui(settings)
|
|||
var submit_data = $.extend({}, me.selected_event, { source:null, comment:$('#reply-comment-event-rsvp').val() }),
|
||||
noreply = $('#noreply-event-rsvp:checked').length ? 1 : 0;
|
||||
|
||||
if (settings.invitation_calendars) {
|
||||
// import event from mail (temporary iTip event)
|
||||
if (submit_data._mbox && submit_data._uid) {
|
||||
me.saving_lock = rcmail.set_busy(true, 'calendar.savingdata');
|
||||
rcmail.http_post('mailimportitip', {
|
||||
_mbox: submit_data._mbox,
|
||||
_uid: submit_data._uid,
|
||||
_part: submit_data._part,
|
||||
_status: response,
|
||||
_noreply: noreply,
|
||||
_comment: submit_data.comment
|
||||
});
|
||||
}
|
||||
else if (settings.invitation_calendars) {
|
||||
update_event('rsvp', submit_data, { status:response, noreply:noreply });
|
||||
}
|
||||
else {
|
||||
|
@ -3089,6 +3101,25 @@ function rcube_calendar_ui(settings)
|
|||
return query;
|
||||
};
|
||||
|
||||
// callback after an iTip message event was imported
|
||||
this.itip_message_processed = function(data)
|
||||
{
|
||||
// remove temporary iTip source
|
||||
fc.fullCalendar('removeEventSource', this.calendars['--invitation--itip']);
|
||||
|
||||
$('#eventshow:ui-dialog').dialog('close');
|
||||
this.selected_event = null;
|
||||
|
||||
// refresh destination calendar source
|
||||
this.refresh({ source:data.calendar, refetch:true });
|
||||
|
||||
this.unlock_saving();
|
||||
|
||||
// process 'after_action' in mail task
|
||||
if (window.opener && window.opener.rcube_libcalendaring)
|
||||
window.opener.rcube_libcalendaring.itip_message_processed(data);
|
||||
};
|
||||
|
||||
// reload the calendar view by keeping the current date/view selection
|
||||
this.reload_view = function()
|
||||
{
|
||||
|
@ -3462,7 +3493,20 @@ function rcube_calendar_ui(settings)
|
|||
var viewdate = new Date();
|
||||
if (rcmail.env.date)
|
||||
viewdate.setTime(fromunixtime(rcmail.env.date));
|
||||
|
||||
|
||||
// add source with iTip event data for rendering
|
||||
if (rcmail.env.itip_events && rcmail.env.itip_events.length) {
|
||||
me.calendars['--invitation--itip'] = {
|
||||
events: rcmail.env.itip_events,
|
||||
className: 'fc-event-cal---invitation--itip',
|
||||
color: '#fff',
|
||||
textColor: '#333',
|
||||
editable: false,
|
||||
attendees: true
|
||||
};
|
||||
event_sources.push(me.calendars['--invitation--itip']);
|
||||
}
|
||||
|
||||
// initalize the fullCalendar plugin
|
||||
var fc = $('#calendar').fullCalendar($.extend({}, fullcalendar_defaults, {
|
||||
header: {
|
||||
|
@ -3940,6 +3984,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
rcmail.addEventListener('plugin.render_event_changelog', function(data){ cal.render_event_changelog(data); });
|
||||
rcmail.addEventListener('plugin.event_show_diff', function(data){ cal.event_show_diff(data); });
|
||||
rcmail.addEventListener('plugin.event_show_revision', function(data){ cal.event_show_dialog(data, null, true); });
|
||||
rcmail.addEventListener('plugin.itip_message_processed', function(data){ cal.itip_message_processed(data); });
|
||||
rcmail.addEventListener('requestrefresh', function(q){ return cal.before_refresh(q); });
|
||||
|
||||
// let's go
|
||||
|
|
|
@ -201,6 +201,7 @@ $labels['eventcancelled'] = 'The event has been cancelled';
|
|||
$labels['saveincalendar'] = 'save in';
|
||||
$labels['updatemycopy'] = 'Update in my calendar';
|
||||
$labels['savetocalendar'] = 'Save to calendar';
|
||||
$labels['openpreview'] = 'Check Calendar';
|
||||
|
||||
// resources
|
||||
$labels['resource'] = 'Resource';
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<script type="text/javascript" src="/functions.js"></script>
|
||||
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="./plugins/calendar/skins/classic/iehacks.css" /><![endif]-->
|
||||
</head>
|
||||
<body class="calendarmain">
|
||||
<roundcube:if condition="env:extwin" /><body class="calendarmain extwin"><roundcube:else /><body class="calendarmain"><roundcube:endif />
|
||||
|
||||
<roundcube:include file="/includes/taskbar.html" />
|
||||
<roundcube:include file="/includes/header.html" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Roundcube Calendar plugin styles for skin "Larry"
|
||||
*
|
||||
* Copyright (c) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
* Copyright (c) 2012-2014, Kolab Systems AG <contact@kolabsys.com>
|
||||
* Screendesign by FLINT / Büro für Gestaltung, bueroflint.com
|
||||
*
|
||||
* The contents are subject to the Creative Commons Attribution-ShareAlike
|
||||
|
@ -2016,9 +2016,15 @@ div.calendar-invitebox input.button {
|
|||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
div.calendar-invitebox input.button.preview {
|
||||
margin-left: 1em;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .folder-select {
|
||||
font-weight: 10px;
|
||||
margin-left: 1em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .rsvp-status {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<roundcube:include file="/includes/links.html" />
|
||||
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="/this/iehacks.css" /><![endif]-->
|
||||
</head>
|
||||
<body class="calendarmain">
|
||||
<roundcube:if condition="env:extwin" /><body class="calendarmain extwin"><roundcube:else /><body class="calendarmain"><roundcube:endif />
|
||||
|
||||
<roundcube:include file="/includes/header.html" />
|
||||
|
||||
|
|
|
@ -361,6 +361,7 @@ class libcalendaring_itip
|
|||
return array(
|
||||
'uid' => $event['uid'],
|
||||
'id' => asciiwords($event['uid'], true),
|
||||
'existing' => $existing ? true : false,
|
||||
'saved' => $existing ? true : false,
|
||||
'latest' => $latest,
|
||||
'status' => $status,
|
||||
|
@ -372,7 +373,7 @@ class libcalendaring_itip
|
|||
/**
|
||||
* Build inline UI elements for iTip messages
|
||||
*/
|
||||
public function mail_itip_inline_ui($event, $method, $mime_id, $task, $message_date = null)
|
||||
public function mail_itip_inline_ui($event, $method, $mime_id, $task, $message_date = null, $preview_url = null)
|
||||
{
|
||||
$buttons = array();
|
||||
$dom_id = asciiwords($event['uid'], true);
|
||||
|
@ -450,6 +451,17 @@ class libcalendaring_itip
|
|||
));
|
||||
}
|
||||
|
||||
// add button to open calendar/preview
|
||||
if (!empty($preview_url)) {
|
||||
$msgref = $this->lib->ical_message->folder . '/' . $this->lib->ical_message->uid . '#' . $mime_id;
|
||||
$rsvp_buttons .= html::tag('input', array(
|
||||
'type' => 'button',
|
||||
'class' => "button preview",
|
||||
'onclick' => "rcube_libcalendaring.open_itip_preview('" . JQ($preview_url) . "', '" . JQ($msgref) . "')",
|
||||
'value' => $this->gettext('openpreview'),
|
||||
));
|
||||
}
|
||||
|
||||
// 2. update the local copy with minor changes
|
||||
$update_button = html::tag('input', array(
|
||||
'type' => 'button',
|
||||
|
|
|
@ -892,6 +892,7 @@ rcube_libcalendaring.fetch_itip_object_status = function(p)
|
|||
rcube_libcalendaring.update_itip_object_status = function(p)
|
||||
{
|
||||
rcmail.env.rsvp_saved = p.saved;
|
||||
rcmail.env.itip_existing = p.existing;
|
||||
|
||||
// hide all elements first
|
||||
$('#itip-buttons-'+p.id+' > div').hide();
|
||||
|
@ -953,6 +954,17 @@ rcube_libcalendaring.itip_after_action = function(action)
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the calendar preview for the current iTip event
|
||||
*/
|
||||
rcube_libcalendaring.open_itip_preview = function(url, msgref)
|
||||
{
|
||||
if (!rcmail.env.itip_existing)
|
||||
url += '&itip=' + escape(msgref);
|
||||
|
||||
var win = rcmail.open_window(url);
|
||||
};
|
||||
|
||||
|
||||
// extend jQuery
|
||||
(function($){
|
||||
|
|
|
@ -134,6 +134,7 @@ $labels['outdatedinvitation'] = 'This invitation has been replaced by a newer ve
|
|||
$labels['importtocalendar'] = 'Save to my calendar';
|
||||
$labels['removefromcalendar'] = 'Remove from my calendar';
|
||||
$labels['updatemycopy'] = 'Update my copy';
|
||||
$labels['openpreview'] = 'Open Preview';
|
||||
|
||||
$labels['deleteobjectconfirm'] = 'Do you really want to delete this object?';
|
||||
$labels['declinedeleteconfirm'] = 'Do you also want to delete this declined object from your account?';
|
||||
|
|
Loading…
Add table
Reference in a new issue