Implement quickview for calendars, showing free-busy data for other user's calendars (#3043)
This commit is contained in:
parent
30c6840269
commit
ab43057b1f
7 changed files with 289 additions and 157 deletions
|
@ -3,12 +3,11 @@
|
|||
/**
|
||||
* Calendar plugin for Roundcube webmail
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Lazlo Westerhof <hello@lazlo.me>
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2010, Lazlo Westerhof <hello@lazlo.me>
|
||||
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
* Copyright (C) 2014, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
@ -1397,7 +1396,9 @@ class calendar extends rcube_plugin
|
|||
'title' => strval($event['title']),
|
||||
'description' => strval($event['description']),
|
||||
'location' => strval($event['location']),
|
||||
'className' => ($addcss ? 'fc-event-cal-'.asciiwords($event['calendar'], true).' ' : '') . 'fc-event-cat-' . asciiwords(strtolower(join('-', (array)$event['categories'])), true),
|
||||
'className' => ($addcss ? 'fc-event-cal-'.asciiwords($event['calendar'], true).' ' : '') .
|
||||
'fc-event-cat-' . asciiwords(strtolower(join('-', (array)$event['categories'])), true) .
|
||||
rtrim(' ' . $event['className']),
|
||||
'allDay' => ($event['allday'] == 1),
|
||||
) + $event;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* JavaScript code in this file.
|
||||
*
|
||||
* Copyright (C) 2010, Lazlo Westerhof <hello@lazlo.me>
|
||||
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
* Copyright (C) 2014, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
@ -83,6 +83,78 @@ function rcube_calendar_ui(settings)
|
|||
selectOtherMonths: true
|
||||
};
|
||||
|
||||
// global fullcalendar settings
|
||||
var fullcalendar_defaults = {
|
||||
aspectRatio: 1,
|
||||
ignoreTimezone: true, // will treat the given date strings as in local (browser's) timezone
|
||||
monthNames : settings.months,
|
||||
monthNamesShort : settings.months_short,
|
||||
dayNames : settings.days,
|
||||
dayNamesShort : settings.days_short,
|
||||
firstDay : settings.first_day,
|
||||
firstHour : settings.first_hour,
|
||||
slotMinutes : 60/settings.timeslots,
|
||||
timeFormat: {
|
||||
'': settings.time_format,
|
||||
agenda: settings.time_format + '{ - ' + settings.time_format + '}',
|
||||
list: settings.time_format + '{ - ' + settings.time_format + '}',
|
||||
table: settings.time_format + '{ - ' + settings.time_format + '}'
|
||||
},
|
||||
axisFormat : settings.time_format,
|
||||
columnFormat: {
|
||||
month: 'ddd', // Mon
|
||||
week: 'ddd ' + settings.date_short, // Mon 9/7
|
||||
day: 'dddd ' + settings.date_short, // Monday 9/7
|
||||
table: settings.date_agenda
|
||||
},
|
||||
titleFormat: {
|
||||
month: 'MMMM yyyy',
|
||||
week: settings.dates_long,
|
||||
day: 'dddd ' + settings['date_long'],
|
||||
table: settings.dates_long
|
||||
},
|
||||
listPage: 1, // advance one day in agenda view
|
||||
listRange: settings.agenda_range,
|
||||
listSections: settings.agenda_sections,
|
||||
tableCols: ['handle', 'date', 'time', 'title', 'location'],
|
||||
defaultView: rcmail.env.view || settings.default_view,
|
||||
allDayText: rcmail.gettext('all-day', 'calendar'),
|
||||
buttonText: {
|
||||
prev: ' ◄ ',
|
||||
next: ' ► ',
|
||||
today: settings['today'],
|
||||
day: rcmail.gettext('day', 'calendar'),
|
||||
week: rcmail.gettext('week', 'calendar'),
|
||||
month: rcmail.gettext('month', 'calendar'),
|
||||
table: rcmail.gettext('agenda', 'calendar')
|
||||
},
|
||||
listTexts: {
|
||||
until: rcmail.gettext('until', 'calendar'),
|
||||
past: rcmail.gettext('pastevents', 'calendar'),
|
||||
today: rcmail.gettext('today', 'calendar'),
|
||||
tomorrow: rcmail.gettext('tomorrow', 'calendar'),
|
||||
thisWeek: rcmail.gettext('thisweek', 'calendar'),
|
||||
nextWeek: rcmail.gettext('nextweek', 'calendar'),
|
||||
thisMonth: rcmail.gettext('thismonth', 'calendar'),
|
||||
nextMonth: rcmail.gettext('nextmonth', 'calendar'),
|
||||
future: rcmail.gettext('futureevents', 'calendar'),
|
||||
week: rcmail.gettext('weekofyear', 'calendar')
|
||||
},
|
||||
currentTimeIndicator: settings.time_indicator,
|
||||
// event rendering
|
||||
eventRender: fc_event_render,
|
||||
// render element indicating more (invisible) events
|
||||
overflowRender: function(data, element) {
|
||||
element.html(rcmail.gettext('andnmore', 'calendar').replace('$nr', data.count))
|
||||
.click(function(e){ me.fisheye_view(data.date); });
|
||||
},
|
||||
// callback when a specific event is clicked
|
||||
eventClick: function(event, ev, view) {
|
||||
if (!event.temp && String(event.className).indexOf('fc-type-freebusy') < 0)
|
||||
event_show_dialog(event, ev);
|
||||
}
|
||||
};
|
||||
|
||||
/*** imports ***/
|
||||
var Q = this.quote_html;
|
||||
var text2html = this.text2html;
|
||||
|
@ -1598,25 +1670,13 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
// initialize resource calendar display
|
||||
var resource_cal = $(rcmail.gui_objects.resourceinfocalendar);
|
||||
resource_cal.fullCalendar({
|
||||
resource_cal.fullCalendar($.extend({}, fullcalendar_defaults, {
|
||||
header: { left: '', center: '', right: '' },
|
||||
height: resource_cal.height() + 4,
|
||||
defaultView: 'agendaWeek',
|
||||
ignoreTimezone: true,
|
||||
eventSources: [],
|
||||
monthNames: settings['months'],
|
||||
monthNamesShort: settings['months_short'],
|
||||
dayNames: settings['days'],
|
||||
dayNamesShort : settings['days_short'],
|
||||
firstDay: settings['first_day'],
|
||||
firstHour: settings['first_hour'],
|
||||
slotMinutes: 60,
|
||||
allDaySlot: false,
|
||||
timeFormat: { '': settings['time_format'] },
|
||||
axisFormat: settings['time_format'],
|
||||
columnFormat: { day: 'dddd ' + settings['date_short'] },
|
||||
titleFormat: { day: 'dddd ' + settings['date_long'] },
|
||||
currentTimeIndicator: settings.time_indicator,
|
||||
eventRender: function(event, element, view) {
|
||||
var title = rcmail.get_label(event.status, 'calendar');
|
||||
element.addClass('status-' + event.status);
|
||||
|
@ -1624,7 +1684,7 @@ function rcube_calendar_ui(settings)
|
|||
element.find('.fc-event-title').text(title);
|
||||
element.attr('aria-label', me.event_date_text(event, true) + ': ' + title);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
$('#resource-calendar-prev').click(function(){
|
||||
resource_cal.fullCalendar('prev');
|
||||
|
@ -2107,37 +2167,69 @@ function rcube_calendar_ui(settings)
|
|||
me.fisheye_date = null;
|
||||
}
|
||||
})
|
||||
.fullCalendar({
|
||||
.fullCalendar($.extend({}, fullcalendar_defaults, {
|
||||
header: { left: '', center: '', right: '' },
|
||||
height: h - 50,
|
||||
defaultView: 'agendaDay',
|
||||
date: date.getDate(),
|
||||
month: date.getMonth(),
|
||||
year: date.getFullYear(),
|
||||
ignoreTimezone: true, /* will treat the given date strings as in local (browser's) timezone */
|
||||
eventSources: sources,
|
||||
monthNames : settings['months'],
|
||||
monthNamesShort : settings['months_short'],
|
||||
dayNames : settings['days'],
|
||||
dayNamesShort : settings['days_short'],
|
||||
firstDay : settings['first_day'],
|
||||
firstHour : settings['first_hour'],
|
||||
slotMinutes : 60/settings['timeslots'],
|
||||
timeFormat: { '': settings['time_format'] },
|
||||
axisFormat : settings['time_format'],
|
||||
columnFormat: { day: 'dddd ' + settings['date_short'] },
|
||||
titleFormat: { day: 'dddd ' + settings['date_long'] },
|
||||
allDayText: rcmail.gettext('all-day', 'calendar'),
|
||||
currentTimeIndicator: settings.time_indicator,
|
||||
eventRender: fc_event_render,
|
||||
eventClick: function(event, ev, view) {
|
||||
event_show_dialog(event, ev);
|
||||
}
|
||||
});
|
||||
eventSources: sources
|
||||
}));
|
||||
|
||||
this.fisheye_date = date;
|
||||
};
|
||||
|
||||
// opens the given calendar in a popup dialog
|
||||
this.quickview = function(id)
|
||||
{
|
||||
$('#quickview-calendar:ui-dialog').dialog('close');
|
||||
|
||||
var dialog, src, cal = this.calendars[id], date = fc.fullCalendar('getDate'),
|
||||
h = $(window).height() - 50,
|
||||
me = this;
|
||||
|
||||
// clone and modify calendar properties
|
||||
src = $.extend({}, cal);
|
||||
src.editable = false;
|
||||
src.url += '&_quickview=1';
|
||||
|
||||
dialog = $('<div>')
|
||||
.attr('id', 'quickview-calendar')
|
||||
.dialog({
|
||||
modal: true,
|
||||
width: Math.min(1000, $(window).width() - 100),
|
||||
height: h,
|
||||
title: cal.name.replace('»', '»').replace(' ', ' '),
|
||||
open: function() {
|
||||
setTimeout(function() { dialog.find('.fc-button-next').first().focus(); }, 10);
|
||||
},
|
||||
close: function() {
|
||||
dialog.dialog('destroy').fullCalendar('destroy').remove();
|
||||
me.quickview_active = null;
|
||||
},
|
||||
resize: function(e) {
|
||||
// adjust height when dialog resizes
|
||||
dialog.fullCalendar('option', 'height', dialog.height() + 8);
|
||||
}
|
||||
})
|
||||
.fullCalendar($.extend({}, fullcalendar_defaults, {
|
||||
header: {
|
||||
left: 'agendaDay,agendaWeek,month,table',
|
||||
center: 'title',
|
||||
right: 'prev,next today'
|
||||
},
|
||||
height: h - 50,
|
||||
defaultView: fc.fullCalendar('getView').name || fullcalendar_defaults.defaultView,
|
||||
date: date.getDate(),
|
||||
month: date.getMonth(),
|
||||
year: date.getFullYear(),
|
||||
slotMinutes: 60,
|
||||
eventSources: [ src ]
|
||||
}));
|
||||
|
||||
me.quickview_active = id;
|
||||
};
|
||||
|
||||
//public method to show the print dialog.
|
||||
this.print_calendars = function(view)
|
||||
{
|
||||
|
@ -2464,6 +2556,22 @@ function rcube_calendar_ui(settings)
|
|||
{
|
||||
var source = me.calendars[p.source];
|
||||
|
||||
// helper function to update the given fullcalendar view
|
||||
function update_view(view, event, source) {
|
||||
var existing = view.fullCalendar('clientEvents', event._id);
|
||||
if (existing.length) {
|
||||
$.extend(existing[0], event);
|
||||
view.fullCalendar('updateEvent', existing[0]);
|
||||
// remove old recurrence instances
|
||||
if (event.recurrence && !event.recurrence_id)
|
||||
view.fullCalendar('removeEvents', function(e){ return e._id.indexOf(event._id+'-') == 0; });
|
||||
}
|
||||
else {
|
||||
event.source = source; // link with source
|
||||
view.fullCalendar('renderEvent', event);
|
||||
}
|
||||
}
|
||||
|
||||
if (source && (p.refetch || (p.update && !source.active))) {
|
||||
// activate event source if new event was added to an invisible calendar
|
||||
if (!source.active) {
|
||||
|
@ -2473,31 +2581,31 @@ function rcube_calendar_ui(settings)
|
|||
}
|
||||
else
|
||||
fc.fullCalendar('refetchEvents', source);
|
||||
|
||||
if (this.quickview_active)
|
||||
$('#quickview-calendar').fullCalendar('refetchEvents');
|
||||
}
|
||||
// add/update single event object
|
||||
else if (source && p.update) {
|
||||
var event = p.update;
|
||||
event.temp = false;
|
||||
|
||||
// update quickview
|
||||
if (this.quickview_active)
|
||||
update_view($('#quickview-calendar'), event, source);
|
||||
// update fish-eye view
|
||||
if (this.fisheye_date)
|
||||
update_view($('#fish-eye-view'), event, source);
|
||||
|
||||
// update main view
|
||||
event.editable = source.editable;
|
||||
var existing = fc.fullCalendar('clientEvents', event._id);
|
||||
if (existing.length) {
|
||||
$.extend(existing[0], event);
|
||||
fc.fullCalendar('updateEvent', existing[0]);
|
||||
// remove old recurrence instances
|
||||
if (event.recurrence && !event.recurrence_id)
|
||||
fc.fullCalendar('removeEvents', function(e){ return e._id.indexOf(event._id+'-') == 0; });
|
||||
}
|
||||
else {
|
||||
event.source = source; // link with source
|
||||
fc.fullCalendar('renderEvent', event);
|
||||
}
|
||||
// refresh fish-eye view
|
||||
if (me.fisheye_date)
|
||||
me.fisheye_view(me.fisheye_date);
|
||||
update_view(fc, event, source);
|
||||
}
|
||||
// refetch all calendars
|
||||
else if (p.refetch) {
|
||||
fc.fullCalendar('refetchEvents');
|
||||
if (this.quickview_active)
|
||||
$('#quickview-calendar').fullCalendar('refetchEvents');
|
||||
}
|
||||
|
||||
// remove temp events
|
||||
|
@ -2811,6 +2919,18 @@ function rcube_calendar_ui(settings)
|
|||
else
|
||||
rcmail.display_message(rcmail.gettext('nocalendarsfound','calendar'), 'info');
|
||||
});
|
||||
calendars_list.addEventListener('click-item', function(event) {
|
||||
// handle clicks on quickview icon: temprarily add this source and open in quickview
|
||||
if ($(event.target).hasClass('quickview') && event.data) {
|
||||
if (!me.calendars[event.data.id]) {
|
||||
event.data.readonly = true;
|
||||
event.data.active = false;
|
||||
event.data.subscribed = false;
|
||||
add_calendar_source(event.data);
|
||||
}
|
||||
me.quickview(event.data.id);
|
||||
}
|
||||
});
|
||||
|
||||
// init (delegate) event handler on calendar list checkboxes
|
||||
$(rcmail.gui_objects.calendarslist).on('click', 'input[type=checkbox]', function(e){
|
||||
|
@ -2839,6 +2959,14 @@ function rcube_calendar_ui(settings)
|
|||
calendars_list.select(this.value);
|
||||
return rcube_event.cancel(e);
|
||||
}
|
||||
})
|
||||
// init (delegate) event handler on quickview links
|
||||
.on('click', 'a.quickview', function(e) {
|
||||
var id = $(this).closest('li').attr('id').replace(/^rcmlical/, '');
|
||||
if (me.calendars[id])
|
||||
me.quickview(id);
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
// register dbl-click handler to open calendar edit dialog
|
||||
|
@ -2859,75 +2987,19 @@ function rcube_calendar_ui(settings)
|
|||
viewdate.setTime(fromunixtime(rcmail.env.date));
|
||||
|
||||
// initalize the fullCalendar plugin
|
||||
var fc = $('#calendar').fullCalendar({
|
||||
var fc = $('#calendar').fullCalendar($.extend({}, fullcalendar_defaults, {
|
||||
header: {
|
||||
right: 'prev,next today',
|
||||
center: 'title',
|
||||
left: 'agendaDay,agendaWeek,month,table'
|
||||
},
|
||||
aspectRatio: 1,
|
||||
date: viewdate.getDate(),
|
||||
month: viewdate.getMonth(),
|
||||
year: viewdate.getFullYear(),
|
||||
ignoreTimezone: true, // will treat the given date strings as in local (browser's) timezone
|
||||
height: $('#calendar').height(),
|
||||
eventSources: event_sources,
|
||||
monthNames : settings['months'],
|
||||
monthNamesShort : settings['months_short'],
|
||||
dayNames : settings['days'],
|
||||
dayNamesShort : settings['days_short'],
|
||||
firstDay : settings['first_day'],
|
||||
firstHour : settings['first_hour'],
|
||||
slotMinutes : 60/settings['timeslots'],
|
||||
timeFormat: {
|
||||
'': settings['time_format'],
|
||||
agenda: settings['time_format'] + '{ - ' + settings['time_format'] + '}',
|
||||
list: settings['time_format'] + '{ - ' + settings['time_format'] + '}',
|
||||
table: settings['time_format'] + '{ - ' + settings['time_format'] + '}'
|
||||
},
|
||||
axisFormat : settings['time_format'],
|
||||
columnFormat: {
|
||||
month: 'ddd', // Mon
|
||||
week: 'ddd ' + settings['date_short'], // Mon 9/7
|
||||
day: 'dddd ' + settings['date_short'], // Monday 9/7
|
||||
table: settings['date_agenda']
|
||||
},
|
||||
titleFormat: {
|
||||
month: 'MMMM yyyy',
|
||||
week: settings['dates_long'],
|
||||
day: 'dddd ' + settings['date_long'],
|
||||
table: settings['dates_long']
|
||||
},
|
||||
listPage: 1, // advance one day in agenda view
|
||||
listRange: settings['agenda_range'],
|
||||
listSections: settings['agenda_sections'],
|
||||
tableCols: ['handle', 'date', 'time', 'title', 'location'],
|
||||
defaultView: rcmail.env.view || settings['default_view'],
|
||||
allDayText: rcmail.gettext('all-day', 'calendar'),
|
||||
buttonText: {
|
||||
prev: (bw.ie6 ? ' << ' : ' ◄ '),
|
||||
next: (bw.ie6 ? ' >> ' : ' ► '),
|
||||
today: settings['today'],
|
||||
day: rcmail.gettext('day', 'calendar'),
|
||||
week: rcmail.gettext('week', 'calendar'),
|
||||
month: rcmail.gettext('month', 'calendar'),
|
||||
table: rcmail.gettext('agenda', 'calendar')
|
||||
},
|
||||
listTexts: {
|
||||
until: rcmail.gettext('until', 'calendar'),
|
||||
past: rcmail.gettext('pastevents', 'calendar'),
|
||||
today: rcmail.gettext('today', 'calendar'),
|
||||
tomorrow: rcmail.gettext('tomorrow', 'calendar'),
|
||||
thisWeek: rcmail.gettext('thisweek', 'calendar'),
|
||||
nextWeek: rcmail.gettext('nextweek', 'calendar'),
|
||||
thisMonth: rcmail.gettext('thismonth', 'calendar'),
|
||||
nextMonth: rcmail.gettext('nextmonth', 'calendar'),
|
||||
future: rcmail.gettext('futureevents', 'calendar'),
|
||||
week: rcmail.gettext('weekofyear', 'calendar')
|
||||
},
|
||||
selectable: true,
|
||||
selectHelper: false,
|
||||
currentTimeIndicator: settings.time_indicator,
|
||||
loading: function(isLoading) {
|
||||
me.is_loading = isLoading;
|
||||
this._rc_loading = rcmail.set_busy(isLoading, 'loading', this._rc_loading);
|
||||
|
@ -2935,13 +3007,6 @@ function rcube_calendar_ui(settings)
|
|||
if (!isLoading)
|
||||
me.events_loaded($(this).fullCalendar('clientEvents').length);
|
||||
},
|
||||
// event rendering
|
||||
eventRender: fc_event_render,
|
||||
// render element indicating more (invisible) events
|
||||
overflowRender: function(data, element) {
|
||||
element.html(rcmail.gettext('andnmore', 'calendar').replace('$nr', data.count))
|
||||
.click(function(e){ me.fisheye_view(data.date); });
|
||||
},
|
||||
// callback for date range selection
|
||||
select: function(start, end, allDay, e, view) {
|
||||
var range_select = (!allDay || start.getDate() != end.getDate())
|
||||
|
@ -2966,11 +3031,6 @@ function rcube_calendar_ui(settings)
|
|||
day_clicked = date.getTime();
|
||||
day_clicked_ts = now;
|
||||
},
|
||||
// callback when a specific event is clicked
|
||||
eventClick: function(event, ev, view) {
|
||||
if (!event.temp)
|
||||
event_show_dialog(event, ev);
|
||||
},
|
||||
// callback when an event was dragged and finally dropped
|
||||
eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc) {
|
||||
if (event.end == null || event.end.getTime() < event.start.getTime()) {
|
||||
|
@ -3040,7 +3100,7 @@ function rcube_calendar_ui(settings)
|
|||
if (fc && view.name == 'month')
|
||||
fc.fullCalendar('option', 'maxHeight', Math.floor((view.element.parent().height()-18) / 6) - 35);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
// format time string
|
||||
var formattime = function(hour, minutes, start) {
|
||||
|
|
|
@ -210,8 +210,10 @@ class kolab_user_calendar extends kolab_calendar
|
|||
}
|
||||
}
|
||||
|
||||
// get events from the user's free/busy feed
|
||||
// get events from the user's free/busy feed (for quickview only)
|
||||
if (!empty($_REQUEST['_quickview']) && empty($search)) {
|
||||
$this->fetch_freebusy($limit_changed);
|
||||
}
|
||||
|
||||
$events = array();
|
||||
foreach ($this->events as $id => $event) {
|
||||
|
@ -281,7 +283,7 @@ class kolab_user_calendar extends kolab_calendar
|
|||
|
||||
// console('_fetch_freebusy', kolab_storage::get_freebusy_url($this->userdata['mail']), $fbdata);
|
||||
|
||||
// parse free-busy information using Horde classes
|
||||
// parse free-busy information
|
||||
$count = 0;
|
||||
if ($fbdata) {
|
||||
$ical = $this->cal->get_ical();
|
||||
|
@ -304,6 +306,7 @@ class kolab_user_calendar extends kolab_calendar
|
|||
'start' => $from,
|
||||
'end' => $to,
|
||||
'free_busy' => $statusmap[$type] ?: 'busy',
|
||||
'className' => 'fc-type-freebusy',
|
||||
'organizer' => array(
|
||||
'email' => $this->userdata['mail'],
|
||||
'name' => $this->userdata['displayname'],
|
||||
|
|
|
@ -308,6 +308,7 @@ class calendar_ui
|
|||
html::span(array('class' => 'calname', 'id' => $label_id, 'title' => $title), $prop['editname'] ? Q($prop['editname']) : $prop['listname']) .
|
||||
($prop['virtual'] ? '' :
|
||||
html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active'], 'aria-labelledby' => $label_id), '') .
|
||||
html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->cal->gettext('quickview'), 'role' => 'checkbox', 'aria-checked' => 'false'), '') .
|
||||
(isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->cal->gettext('calendarsubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') : '') .
|
||||
html::span(array('class' => 'handle', 'style' => "background-color: #" . ($prop['color'] ?: 'f00')), ' ')
|
||||
)
|
||||
|
|
|
@ -94,6 +94,7 @@ $labels['calsearchresults'] = 'Available Calendars';
|
|||
$labels['calendarsubscribe'] = 'List permanently';
|
||||
$labels['nocalendarsfound'] = 'No calendars found';
|
||||
$labels['nrcalendarsfound'] = '$nr calendars found';
|
||||
$labels['quickview'] = 'View only this calendar';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Range to display:';
|
||||
|
|
|
@ -219,11 +219,11 @@ pre {
|
|||
|
||||
#calendars .treelist li span.calname {
|
||||
display: block;
|
||||
padding: 0px 30px 2px 2px;
|
||||
padding: 0px 18px 2px 2px;
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 38px;
|
||||
right: 40px;
|
||||
right: 60px;
|
||||
cursor: default;
|
||||
background: url(images/calendars.png) right 20px no-repeat;
|
||||
overflow: hidden;
|
||||
|
@ -240,7 +240,7 @@ pre {
|
|||
|
||||
#calendars .treelist.flat li span.calname {
|
||||
left: 24px;
|
||||
right: 22px;
|
||||
right: 42px;
|
||||
}
|
||||
|
||||
#calendars .treelist li span.handle {
|
||||
|
@ -288,6 +288,29 @@ pre {
|
|||
background-position: -16px -110px;
|
||||
}
|
||||
|
||||
#calendars .treelist li a.quickview {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 42px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 0;
|
||||
background: url(images/calendars.png) -100px 0 no-repeat;
|
||||
overflow: hidden;
|
||||
text-indent: -5000px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#calendars .treelist div > a.quickview:focus,
|
||||
#calendars .treelist li div:hover > a.quickview {
|
||||
background-position: 0 -128px;
|
||||
}
|
||||
|
||||
#calendars .treelist li div.focusview > a.quickview {
|
||||
background-position: -18px -128px;
|
||||
}
|
||||
|
||||
#calendars .treelist li input {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
|
@ -1316,9 +1339,26 @@ a.dropdown-link:after {
|
|||
bottom: 2px;
|
||||
}
|
||||
|
||||
#quickview-calendar {
|
||||
padding: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.calendarmain .fc-button,
|
||||
.calendarmain .fc-button.fc-state-default,
|
||||
.calendarmain .fc-button.fc-state-hover {
|
||||
background-color: #f5f5f5;
|
||||
background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
|
||||
background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
|
||||
background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
|
||||
background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-button,
|
||||
.calendarmain #calendar .fc-button.fc-state-default,
|
||||
.calendarmain #calendar .fc-button.fc-state-hover {
|
||||
margin: 0 0 0 0;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
|
@ -1338,22 +1378,15 @@ a.dropdown-link:after {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.calendarmain .fc-button.fc-state-disabled {
|
||||
.calendarmain #calendar .fc-button.fc-state-disabled {
|
||||
color: #999;
|
||||
background: #d8d8d8;
|
||||
}
|
||||
|
||||
.calendarmain .fc-button.fc-state-down {
|
||||
margin: 0;
|
||||
background: #bababa;
|
||||
background: -moz-linear-gradient(top, #bababa 0%, #d8d8d8 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#bababa), color-stop(100%,#d8d8d8));
|
||||
background: -o-linear-gradient(top, #bababa 0%, #d8d8d8 100%);
|
||||
background: -ms-linear-gradient(top, #bababa 0%, #d8d8d8 100%);
|
||||
background: linear-gradient(top, #bababa 0%, #d8d8d8 100%);
|
||||
}
|
||||
|
||||
.calendarmain .fc-button.fc-state-active {
|
||||
.calendarmain .fc-button.fc-state-active,
|
||||
.calendarmain .fc-button.fc-state-down,
|
||||
.calendarmain #calendar .fc-button.fc-state-active,
|
||||
.calendarmain #calendar .fc-button.fc-state-down {
|
||||
color: #333;
|
||||
background: #bababa;
|
||||
background: -moz-linear-gradient(top, #bababa 0%, #d8d8d8 100%);
|
||||
|
@ -1363,12 +1396,12 @@ a.dropdown-link:after {
|
|||
background: linear-gradient(top, #bababa 0%, #d8d8d8 100%);
|
||||
}
|
||||
|
||||
.calendarmain .fc-header .fc-button {
|
||||
.calendarmain #calendar .fc-header .fc-button {
|
||||
margin-left: -1px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button {
|
||||
.calendarmain #calendar .fc-header-left .fc-button {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
|
@ -1393,58 +1426,58 @@ a.dropdown-link:after {
|
|||
outline: none;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button:focus {
|
||||
.calendarmain #calendar .fc-header-left .fc-button:focus {
|
||||
color: #fff;
|
||||
text-shadow: 0px 1px 1px #666;
|
||||
background-color: rgba(30,150,192, 0.5);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button.fc-state-active {
|
||||
.calendarmain #calendar .fc-header-left .fc-button.fc-state-active {
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
text-shadow: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button-agendaDay {
|
||||
.calendarmain #calendar .fc-header-left .fc-button-agendaDay {
|
||||
background-position: center -120px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button-agendaDay.fc-state-active {
|
||||
.calendarmain #calendar .fc-header-left .fc-button-agendaDay.fc-state-active {
|
||||
background-position: center -160px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button-agendaWeek {
|
||||
.calendarmain #calendar .fc-header-left .fc-button-agendaWeek {
|
||||
background-position: center -200px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button-agendaWeek.fc-state-active {
|
||||
.calendarmain #calendar .fc-header-left .fc-button-agendaWeek.fc-state-active {
|
||||
background-position: center -240px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button-month {
|
||||
.calendarmain #calendar .fc-header-left .fc-button-month {
|
||||
background-position: center -280px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button-month.fc-state-active {
|
||||
.calendarmain #calendar .fc-header-left .fc-button-month.fc-state-active {
|
||||
background-position: center -320px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button-table {
|
||||
.calendarmain #calendar .fc-header-left .fc-button-table {
|
||||
background-position: center -360px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left .fc-button-table.fc-state-active {
|
||||
.calendarmain #calendar .fc-header-left .fc-button-table.fc-state-active {
|
||||
background-position: center -400px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-right {
|
||||
.calendarmain #calendar .fc-header-right {
|
||||
padding-right: 252px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.fc-header-title {
|
||||
.calendarmain #calendar .fc-header-title {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
|
@ -1452,6 +1485,39 @@ a.dropdown-link:after {
|
|||
font-size: 1em !important;
|
||||
}
|
||||
|
||||
.fc-type-freebusy {
|
||||
opacity: 0.55;
|
||||
color: #fff !important;
|
||||
|
||||
background: rgba(80,80,80,0.85) !important;
|
||||
background: -moz-linear-gradient(top, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.9) 100%) !important;
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(80,80,80,0.85)), color-stop(100%,rgba(48,48,48,0.9))) !important;
|
||||
background: -webkit-linear-gradient(top, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.85) 100%) !important;
|
||||
background: -o-linear-gradient(top, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.85) 100%) !important;
|
||||
background: -ms-linear-gradient(top, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.85) 100%) !important;
|
||||
background: linear-gradient(to bottom, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.85) 100%) !important;
|
||||
|
||||
-moz-box-shadow: inset 0px 1px 0 0px #888;
|
||||
-webkit-box-shadow: inset 0px 1px 0 0px #888;
|
||||
-o-box-shadow: inset 0px 1px 0 0px #888;
|
||||
box-shadow: inset 0px 1px 0 0px #888;
|
||||
|
||||
border-color: #444 !important;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
.fc-type-freebusy .fc-event-skin,
|
||||
.fc-type-freebusy .fc-event-inner {
|
||||
background-color: transparent !important;
|
||||
border-color: #444 !important;
|
||||
color: #fff !important;
|
||||
text-shadow: 0 1px 1px #000;
|
||||
}
|
||||
|
||||
.fc-type-freebusy .fc-event-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.calendarmain .fc-event:focus {
|
||||
outline: 1px solid rgba(71,135,177, 0.4);
|
||||
-webkit-box-shadow: 0 0 2px 3px rgba(71,135,177, 0.6);
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.6 KiB |
Loading…
Add table
Reference in a new issue