Support free/busy types (e.g. tentative, out-of-office)
This commit is contained in:
parent
4555108baa
commit
be0e774998
6 changed files with 41 additions and 13 deletions
|
@ -29,6 +29,7 @@ class calendar extends rcube_plugin
|
|||
const FREEBUSY_UNKNOWN = 0;
|
||||
const FREEBUSY_FREE = 1;
|
||||
const FREEBUSY_BUSY = 2;
|
||||
const FREEBUSY_TENTATIVE = 3;
|
||||
const FREEBUSY_OOF = 4;
|
||||
|
||||
public $task = '?(?!login|logout).*';
|
||||
|
@ -1206,6 +1207,7 @@ class calendar extends rcube_plugin
|
|||
if (!$start) $start = time();
|
||||
if (!$end) $end = $start + 3600;
|
||||
|
||||
$fbtypemap = array(calendar::FREEBUSY_FREE => 'FREE', calendar::FREEBUSY_BUSY => 'BUSY', calendar::FREEBUSY_TENTATIVE => 'TENTATIVE', calendar::FREEBUSY_OOF => 'OUT-OF-OFFICE');
|
||||
$status = 'UNKNOWN';
|
||||
|
||||
// if the backend has free-busy information
|
||||
|
@ -1214,9 +1216,9 @@ class calendar extends rcube_plugin
|
|||
$status = 'FREE';
|
||||
|
||||
foreach ($fblist as $slot) {
|
||||
list($from, $to) = $slot;
|
||||
list($from, $to, $type) = $slot;
|
||||
if ($from <= $end && $to > $start) {
|
||||
$status = 'BUSY';
|
||||
$status = $type && $fbtypemap[$type] ? $fbtypemap[$type] : 'BUSY';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1256,9 +1258,9 @@ class calendar extends rcube_plugin
|
|||
if (is_array($fblist)) {
|
||||
$status = self::FREEBUSY_FREE;
|
||||
foreach ($fblist as $slot) {
|
||||
list($from, $to) = $slot;
|
||||
list($from, $to, $type) = $slot;
|
||||
if ($from <= $t_end && $to > $t) {
|
||||
$status = self::FREEBUSY_BUSY;
|
||||
$status = isset($type) ? $type : self::FREEBUSY_BUSY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ function rcube_calendar_ui(settings)
|
|||
var attendees_list;
|
||||
var freebusy_ui = {};
|
||||
var freebusy_data = {};
|
||||
var freebusy_needsupdate;
|
||||
|
||||
// general datepicker settings
|
||||
var datepicker_settings = {
|
||||
|
@ -330,6 +331,7 @@ function rcube_calendar_ui(settings)
|
|||
var $dialog = $("#eventedit");
|
||||
var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:action=='new' };
|
||||
me.selected_event = event;
|
||||
freebusy_needsupdate = false;
|
||||
|
||||
// reset dialog first, enable/disable fields according to editable state
|
||||
$('#eventtabs').get(0).reset();
|
||||
|
@ -799,8 +801,8 @@ function rcube_calendar_ui(settings)
|
|||
var allday = $('#edit-allday').get(0);
|
||||
me.selected_event.start = parse_datetime(allday.checked ? '00:00' : $('#edit-starttime').val(), $('#edit-startdate').val());
|
||||
me.selected_event.end = parse_datetime(allday.checked ? '23:59' : $('#edit-endtime').val(), $('#edit-enddate').val());
|
||||
if (me.selected_event.attendees)
|
||||
update_freebusy_status(me.selected_event);
|
||||
if (event_attendees)
|
||||
freebusy_needsupdate = true;
|
||||
$('#edit-startdate').data('duration', Math.round((me.selected_event.end.getTime() - me.selected_event.start.getTime()) / 1000));
|
||||
}
|
||||
};
|
||||
|
@ -902,10 +904,12 @@ function rcube_calendar_ui(settings)
|
|||
var update_freebusy_status = function(event)
|
||||
{
|
||||
var icons = attendees_list.find('img.availabilityicon');
|
||||
for (var i=0; i < event.attendees.length; i++) {
|
||||
if (icons.get(i) && event.attendees[i].email && event.attendees[i].status != 'ACCEPTED')
|
||||
check_freebusy_status(icons.get(i), event.attendees[i].email, event);
|
||||
for (var i=0; i < event_attendees.length; i++) {
|
||||
if (icons.get(i) && event_attendees[i].email && event_attendees[i].status != 'ACCEPTED')
|
||||
check_freebusy_status(icons.get(i), event_attendees[i].email, event);
|
||||
}
|
||||
|
||||
freebusy_needsupdate = false;
|
||||
};
|
||||
|
||||
// load free-busy status from server and update icon accordingly
|
||||
|
@ -1563,8 +1567,11 @@ function rcube_calendar_ui(settings)
|
|||
// init event dialog
|
||||
$('#eventtabs').tabs({
|
||||
show: function(event, ui) {
|
||||
if (ui.panel.id == 'event-tab-3')
|
||||
if (ui.panel.id == 'event-tab-3') {
|
||||
$('#edit-attendee-name').select();
|
||||
if (freebusy_needsupdate && me.selected_event)
|
||||
update_freebusy_status(me.selected_event);
|
||||
}
|
||||
}
|
||||
});
|
||||
$('#edit-enddate, input.edit-alarm-date').datepicker(datepicker_settings);
|
||||
|
|
|
@ -693,9 +693,19 @@ class kolab_driver extends calendar_driver
|
|||
if (empty($email)/* || $end < time()*/)
|
||||
return false;
|
||||
|
||||
// map vcalendar fbtypes to internal values
|
||||
$fbtypemap = array(
|
||||
'FREE' => calendar::FREEBUSY_FREE,
|
||||
'BUSY-TENTATIVE' => calendar::FREEBUSY_TENTATIVE,
|
||||
'X-OUT-OF-OFFICE' => calendar::FREEBUSY_OOF,
|
||||
'OOF' => calendar::FREEBUSY_OOF);
|
||||
|
||||
// ask kolab server first
|
||||
$fbdata = @file_get_contents(rcube_kolab::get_freebusy_url($email));
|
||||
|
||||
|
||||
if (!$fbdata)
|
||||
$fbdata = file_get_contents('http://localhost/roundcube/kolab/sample.ifb');
|
||||
|
||||
// get free-busy url from contacts
|
||||
if (!$fbdata) {
|
||||
$fburl = null;
|
||||
|
@ -722,10 +732,12 @@ class kolab_driver extends calendar_driver
|
|||
$fbcal->parsevCalendar($fbdata);
|
||||
if ($fb = $fbcal->findComponent('vfreebusy')) {
|
||||
$result = array();
|
||||
$params = $fb->getExtraParams();
|
||||
foreach ($fb->getBusyPeriods() as $from => $to) {
|
||||
if ($to == null) // no information, assume free
|
||||
break;
|
||||
$result[] = array($from, $to);
|
||||
$type = $params[$from]['FBTYPE'];
|
||||
$result[] = array($from, $to, isset($fbtypemap[$type]) ? $fbtypemap[$type] : calendar::FREEBUSY_BUSY);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
|
|
@ -95,6 +95,7 @@ $labels['roleresource'] = 'Resource';
|
|||
$labels['availfree'] = 'Free';
|
||||
$labels['availbusy'] = 'Busy';
|
||||
$labels['availunknown'] = 'Unknown';
|
||||
$labels['availtentative'] = 'Tentative';
|
||||
$labels['availoutofoffice'] = 'Out of Office';
|
||||
$labels['scheduletime'] = 'Available times';
|
||||
$labels['sendnotifications'] = 'Send notifications';
|
||||
|
|
|
@ -566,7 +566,7 @@ td.topalign {
|
|||
}
|
||||
|
||||
.availability img.availabilityicon.loading {
|
||||
background: url('images/loading-small.gif') top left no-repeat;
|
||||
background: url('images/loading-small.gif') middle middle no-repeat;
|
||||
}
|
||||
|
||||
#schedule-freebusy-times td.unknown,
|
||||
|
@ -584,6 +584,11 @@ td.topalign {
|
|||
background: #c00;
|
||||
}
|
||||
|
||||
#schedule-freebusy-times td.tentative,
|
||||
.availability img.availabilityicon.tentative {
|
||||
background: #66d;
|
||||
}
|
||||
|
||||
#schedule-freebusy-times td.out-of-office,
|
||||
.availability img.availabilityicon.out-of-office {
|
||||
background: #f0b400;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<div id="edit-attendees-legend" class="availability">
|
||||
<span class="legend"><img class="availabilityicon free" src="./program/blank.gif" /> <roundcube:label name="calendar.availfree" /></span>
|
||||
<span class="legend"><img class="availabilityicon busy" src="./program/blank.gif" /> <roundcube:label name="calendar.availbusy" /></span>
|
||||
<span class="legend"><img class="availabilityicon tentative" src="./program/blank.gif" /> <roundcube:label name="calendar.availtentative" /></span>
|
||||
<span class="legend"><img class="availabilityicon out-of-office" src="./program/blank.gif" /> <roundcube:label name="calendar.availoutofoffice" /></span>
|
||||
<span class="legend"><img class="availabilityicon unknown" src="./program/blank.gif" /> <roundcube:label name="calendar.availunknown" /></span>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue