Render preview agenda for iTip requests below RSVP buttons (#3161)
This commit is contained in:
parent
6b7fc6729d
commit
086e2b2e1f
6 changed files with 150 additions and 1 deletions
|
@ -2237,6 +2237,37 @@ class calendar extends rcube_plugin
|
|||
$response['select'] = html::tag('input', array('type' => 'hidden', 'name' => 'calendar', 'id' => 'itip-saveto', 'value' => ''));
|
||||
}
|
||||
|
||||
// render small agenda view for the respective day
|
||||
if ($data['method'] == 'REQUEST' && !empty($data['date']) && $response['action'] == 'rsvp') {
|
||||
$event_start = rcube_utils::anytodatetime($data['date']);
|
||||
$day_start = new Datetime(gmdate('Y-m-d 00:00', $data['date']), $this->lib->timezone);
|
||||
$day_end = new Datetime(gmdate('Y-m-d 23:59', $data['date']), $this->lib->timezone);
|
||||
|
||||
// get events on that day from the user's personal calendars
|
||||
$calendars = $this->driver->list_calendars(false, true);
|
||||
$events = $this->driver->load_events($day_start->format('U'), $day_end->format('U'), null, array_keys($calendars));
|
||||
usort($events, function($a, $b) { return $a['start'] > $b['start'] ? 1 : -1; });
|
||||
|
||||
$before = $after = array();
|
||||
foreach ($events as $event) {
|
||||
// TODO: skip events with free_busy == 'free' ?
|
||||
if ($event['uid'] == $data['uid'] || $event['end'] < $day_start || $event['start'] > $day_end)
|
||||
continue;
|
||||
else if ($event['start'] < $event_start)
|
||||
$before[] = $this->mail_agenda_event_row($event);
|
||||
else
|
||||
$after[] = $this->mail_agenda_event_row($event);
|
||||
}
|
||||
|
||||
$response['append'] = array(
|
||||
'selector' => '.calendar-agenda-preview',
|
||||
'replacements' => array(
|
||||
'%before%' => !empty($before) ? join("\n", array_slice($before, -3)) : html::div('event-row no-event', $this->gettext('noearlierevents')),
|
||||
'%after%' => !empty($after) ? join("\n", array_slice($after, 0, 3)) : html::div('event-row no-event', $this->gettext('nolaterevents')),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$this->rc->output->command('plugin.update_itip_object_status', $response);
|
||||
}
|
||||
|
||||
|
@ -2339,6 +2370,21 @@ class calendar extends rcube_plugin
|
|||
return html::tag('form', array('action' => $this->rc->url(array('task' => 'calendar', 'action' => 'attend')), 'method' => 'post', 'noclose' => true) + $attrib) . $hidden->show();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function mail_agenda_event_row($event, $class = '')
|
||||
{
|
||||
$time = $event['all-day'] ? $this->gettext('allday') :
|
||||
$this->rc->format_date($event['start'], $this->rc->config->get('time_format')) . ' - ' .
|
||||
$this->rc->format_date($event['end'], $this->rc->config->get('time_format'));
|
||||
|
||||
return html::div(rtrim('event-row ' . $class),
|
||||
html::span('event-date', $time) .
|
||||
html::span('event-title', Q($event['title']))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -2391,6 +2437,16 @@ class calendar extends rcube_plugin
|
|||
|
||||
// get prepared inline UI for this event object
|
||||
if ($ical_objects->method) {
|
||||
$append = '';
|
||||
|
||||
// prepare a small agenda preview to be filled with actual event data on async request
|
||||
if ($ical_objects->method == 'REQUEST') {
|
||||
$append = html::div('calendar-agenda-preview',
|
||||
html::tag('h3', 'preview-title', $this->gettext('agenda') . ' ' .
|
||||
html::span('date', $this->rc->format_date($event['start'], $this->rc->config->get('date_format')))
|
||||
) . '%before%' . $this->mail_agenda_event_row($event, 'current') . '%after%');
|
||||
}
|
||||
|
||||
$html .= html::div('calendar-invitebox',
|
||||
$this->itip->mail_itip_inline_ui(
|
||||
$event,
|
||||
|
@ -2399,7 +2455,7 @@ class calendar extends rcube_plugin
|
|||
'calendar',
|
||||
rcube_utils::anytodatetime($ical_objects->message_date),
|
||||
$this->rc->url(array('task' => 'calendar')) . '&view=agendaDay&date=' . $event['start']->format('U')
|
||||
)
|
||||
) . $append
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -202,6 +202,8 @@ $labels['saveincalendar'] = 'save in';
|
|||
$labels['updatemycopy'] = 'Update in my calendar';
|
||||
$labels['savetocalendar'] = 'Save to calendar';
|
||||
$labels['openpreview'] = 'Check Calendar';
|
||||
$labels['noearlierevents'] = 'No earlier events';
|
||||
$labels['nolaterevents'] = 'No later events';
|
||||
|
||||
// resources
|
||||
$labels['resource'] = 'Resource';
|
||||
|
|
|
@ -1688,6 +1688,42 @@ div.calendar-invitebox .rsvp-status.delegated {
|
|||
background-position: 2px -180px;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview {
|
||||
display: none;
|
||||
border-top: 1px solid #dfdfdf;
|
||||
margin-top: 1em;
|
||||
padding-top: 0.6em;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview h3.preview-title {
|
||||
margin: 0 0 0.5em 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview .event-row {
|
||||
color: #777;
|
||||
padding: 2px 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview .event-row.current {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview .event-row.no-event {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview .event-date {
|
||||
display: inline-block;
|
||||
min-width: 8em;
|
||||
margin-right: 1em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* iTIP attend reply page */
|
||||
|
||||
.calendaritipattend .centerbox {
|
||||
|
|
|
@ -2110,6 +2110,44 @@ div.calendar-invitebox .rsvp-status.needs-action {
|
|||
background-position: 2px 0;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview {
|
||||
display: none;
|
||||
border-top: 1px solid #dfdfdf;
|
||||
margin-top: 1em;
|
||||
padding-top: 0.6em;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview h3.preview-title {
|
||||
margin: 0 0 0.5em 0;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview .event-row {
|
||||
color: #777;
|
||||
padding: 2px 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview .event-row.current {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview .event-row.no-event {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .calendar-agenda-preview .event-date {
|
||||
display: inline-block;
|
||||
min-width: 8em;
|
||||
margin-right: 1em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
/* iTIP attend reply page */
|
||||
|
||||
.calendaritipattend .centerbox {
|
||||
|
|
|
@ -434,6 +434,9 @@ class libcalendaring_itip
|
|||
$emails = $this->lib->get_user_emails();
|
||||
$title = $event['sequence'] > 0 ? $this->gettext('itipupdate') : $this->gettext('itipinvitation');
|
||||
$metadata['rsvp'] = true;
|
||||
if (is_object($event['start'])) {
|
||||
$metadata['date'] = $event['start']->format('U');
|
||||
}
|
||||
|
||||
// check for X-KOLAB-INVITATIONTYPE property and only show accept/decline buttons
|
||||
if (self::get_custom_property($event, 'X-KOLAB-INVITATIONTYPE') == 'CONFIRMATION') {
|
||||
|
|
|
@ -912,6 +912,20 @@ rcube_libcalendaring.update_itip_object_status = function(p)
|
|||
|
||||
// show rsvp/import buttons (with calendar selector)
|
||||
$('#'+p.action+'-'+p.id).show().find('input.button').last().after(p.select);
|
||||
|
||||
// show itip box appendix after replacing the given placeholders
|
||||
if (p.append && p.append.selector) {
|
||||
var elem = $(p.append.selector);
|
||||
if (p.append.replacements) {
|
||||
$.each(p.append.replacements, function(k, html) {
|
||||
elem.html(elem.html().replace(k, html));
|
||||
});
|
||||
}
|
||||
else if (p.append.html) {
|
||||
elem.html(p.append.html)
|
||||
}
|
||||
elem.show();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue