Upgrade to fullcalendar 3.9.0 - Part I
Just started, still many issues, no printing, no elastic, no agenda view
This commit is contained in:
parent
618fbe9b35
commit
eb85d762c7
9 changed files with 21074 additions and 7809 deletions
|
@ -1323,12 +1323,21 @@ class calendar extends rcube_plugin
|
|||
*/
|
||||
function load_events()
|
||||
{
|
||||
$events = $this->driver->load_events(
|
||||
rcube_utils::get_input_value('start', rcube_utils::INPUT_GET),
|
||||
rcube_utils::get_input_value('end', rcube_utils::INPUT_GET),
|
||||
($query = rcube_utils::get_input_value('q', rcube_utils::INPUT_GET)),
|
||||
rcube_utils::get_input_value('source', rcube_utils::INPUT_GET)
|
||||
);
|
||||
$start = rcube_utils::get_input_value('start', rcube_utils::INPUT_GET);
|
||||
$end = rcube_utils::get_input_value('end', rcube_utils::INPUT_GET);
|
||||
$query = rcube_utils::get_input_value('q', rcube_utils::INPUT_GET);
|
||||
$sorce = rcube_utils::get_input_value('source', rcube_utils::INPUT_GET);
|
||||
|
||||
if (!is_numeric($start) || strpos($start, 'T')) {
|
||||
$start = new DateTime($start, $this->timezone);
|
||||
$start = $start->getTimestamp();
|
||||
}
|
||||
if (!is_numeric($end) || strpos($end, 'T')) {
|
||||
$end = new DateTime($end, $this->timezone);
|
||||
$end = $end->getTimestamp();
|
||||
}
|
||||
|
||||
$events = $this->driver->load_events($start, $end, $query, $source);
|
||||
echo $this->encode($events, !empty($query));
|
||||
exit;
|
||||
}
|
||||
|
@ -1767,8 +1776,6 @@ class calendar extends rcube_plugin
|
|||
// configuration
|
||||
$settings['default_calendar'] = $this->rc->config->get('calendar_default_calendar');
|
||||
$settings['default_view'] = (string)$this->rc->config->get('calendar_default_view', $this->defaults['calendar_default_view']);
|
||||
$settings['date_agenda'] = (string)$this->rc->config->get('calendar_date_agenda', $this->defaults['calendar_date_agenda']);
|
||||
|
||||
$settings['timeslots'] = (int)$this->rc->config->get('calendar_timeslots', $this->defaults['calendar_timeslots']);
|
||||
$settings['first_day'] = (int)$this->rc->config->get('calendar_first_day', $this->defaults['calendar_first_day']);
|
||||
$settings['first_hour'] = (int)$this->rc->config->get('calendar_first_hour', $this->defaults['calendar_first_hour']);
|
||||
|
@ -1889,24 +1896,31 @@ class calendar extends rcube_plugin
|
|||
$event['description'] = trim($h2t->get_text());
|
||||
}
|
||||
|
||||
// mapping url => vurl because of the fullcalendar client script
|
||||
// mapping url => vurl, allday => allDay because of the fullcalendar client script
|
||||
$event['vurl'] = $event['url'];
|
||||
$event['allDay'] = !empty($event['allday']);
|
||||
unset($event['url']);
|
||||
unset($event['allday']);
|
||||
|
||||
$event['className'] = $event['className'] ? explode(' ', $event['className']) : array();
|
||||
if ($addcss) {
|
||||
$event['className'][] = 'fc-event-cal-' . asciiwords($event['calendar'], true);
|
||||
}
|
||||
|
||||
if ($event['allDay']) {
|
||||
$event['end'] = $event['end']->add(new DateInterval('P1D'));
|
||||
}
|
||||
|
||||
return array(
|
||||
'_id' => $event['calendar'] . ':' . $event['id'], // unique identifier for fullcalendar
|
||||
'start' => $this->lib->adjust_timezone($event['start'], $event['allday'])->format('c'),
|
||||
'end' => $this->lib->adjust_timezone($event['end'], $event['allday'])->format('c'),
|
||||
'start' => $this->lib->adjust_timezone($event['start'], $event['allDay'])->format('c'),
|
||||
'end' => $this->lib->adjust_timezone($event['end'], $event['allDay'])->format('c'),
|
||||
// 'changed' might be empty for event recurrences (Bug #2185)
|
||||
'changed' => $event['changed'] ? $this->lib->adjust_timezone($event['changed'])->format('c') : null,
|
||||
'created' => $event['created'] ? $this->lib->adjust_timezone($event['created'])->format('c') : null,
|
||||
'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) .
|
||||
rtrim(' ' . $event['className']),
|
||||
'allDay' => ($event['allday'] == 1),
|
||||
) + $event;
|
||||
}
|
||||
|
||||
|
@ -2056,7 +2070,11 @@ class calendar extends rcube_plugin
|
|||
// convert dates into DateTime objects in user's current timezone
|
||||
$event['start'] = new DateTime($event['start'], $this->timezone);
|
||||
$event['end'] = new DateTime($event['end'], $this->timezone);
|
||||
$event['allday'] = (bool)$event['allday'];
|
||||
$event['allday'] = (bool) (isset($event['allDay']) ? $event['allDay'] : $event['allday']);
|
||||
|
||||
if ($event['allday']) {
|
||||
|
||||
}
|
||||
|
||||
// start/end is all we need for 'move' action (#1480)
|
||||
if ($action == 'move') {
|
||||
|
@ -2433,14 +2451,15 @@ class calendar extends rcube_plugin
|
|||
$skin_path = $this->local_skin_path();
|
||||
$this->include_stylesheet($skin_path . '/fullcalendar.css');
|
||||
$this->include_stylesheet($skin_path . '/print.css');
|
||||
|
||||
|
||||
// Add JS files to the page header
|
||||
$this->include_script('print.js');
|
||||
$this->include_script('lib/js/moment.js');
|
||||
$this->include_script('lib/js/fullcalendar.js');
|
||||
|
||||
|
||||
$this->register_handler('plugin.calendar_css', array($this->ui, 'calendar_css'));
|
||||
$this->register_handler('plugin.calendar_list', array($this->ui, 'calendar_list'));
|
||||
|
||||
|
||||
$this->rc->output->set_pagetitle($title);
|
||||
$this->rc->output->send("calendar.print");
|
||||
}
|
||||
|
|
|
@ -71,20 +71,6 @@ function rcube_calendar_ui(settings)
|
|||
var sensitivitylabels = { 'public':rcmail.gettext('public','calendar'), 'private':rcmail.gettext('private','calendar'), 'confidential':rcmail.gettext('confidential','calendar') };
|
||||
var ui_loading = rcmail.set_busy(true, 'loading');
|
||||
|
||||
// general datepicker settings
|
||||
var datepicker_settings = {
|
||||
// translate from fullcalendar format to datepicker format
|
||||
dateFormat: settings.date_format.replace(/M/g, 'm').replace(/mmmmm/, 'MM').replace(/mmm/, 'M').replace(/dddd/, 'DD').replace(/ddd/, 'D').replace(/yy/g, 'y'),
|
||||
firstDay: settings.first_day,
|
||||
// dayNamesMin: settings.days_short,
|
||||
monthNames: settings.months,
|
||||
monthNamesShort: settings.months,
|
||||
changeMonth: false,
|
||||
showWeek: settings.show_weekno >= 0,
|
||||
showOtherMonths: true,
|
||||
selectOtherMonths: true
|
||||
};
|
||||
|
||||
// global fullcalendar settings
|
||||
var fullcalendar_defaults = {
|
||||
aspectRatio: 1,
|
||||
|
@ -96,42 +82,52 @@ function rcube_calendar_ui(settings)
|
|||
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 + '}'
|
||||
views: {
|
||||
basic: {
|
||||
timeFormat: settings.time_format,
|
||||
},
|
||||
year: {
|
||||
columnFormat: settings.date_agenda,
|
||||
titleFormat: settings.dates_long,
|
||||
},
|
||||
month: {
|
||||
columnFormat: 'ddd', // Mon
|
||||
titleFormat: 'MMMM YYYY',
|
||||
},
|
||||
week: {
|
||||
columnFormat: 'ddd ' + settings.date_short, // Mon 9/7
|
||||
titleFormat: settings.dates_long,
|
||||
},
|
||||
day: {
|
||||
columnFormat: 'dddd ' + settings.date_short, // Monday 9/7
|
||||
titleFormat: 'dddd ' + settings.date_long,
|
||||
}
|
||||
},
|
||||
timeFormat: 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: 7, // advance one week 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'),
|
||||
weekNumbers: settings.show_weekno > 0,
|
||||
weekNumberTitle: rcmail.gettext('weekshort', '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')
|
||||
listYear: rcmail.gettext('agenda', 'calendar')
|
||||
},
|
||||
buttonIcons: {
|
||||
prev: 'left-single-arrow',
|
||||
next: 'right-single-arrow'
|
||||
},
|
||||
theme: false,
|
||||
/*
|
||||
listTexts: {
|
||||
until: rcmail.gettext('until', 'calendar'),
|
||||
past: rcmail.gettext('pastevents', 'calendar'),
|
||||
|
@ -144,6 +140,7 @@ function rcube_calendar_ui(settings)
|
|||
future: rcmail.gettext('futureevents', 'calendar'),
|
||||
week: rcmail.gettext('weekofyear', 'calendar')
|
||||
},
|
||||
*/
|
||||
currentTimeIndicator: settings.time_indicator,
|
||||
// event rendering
|
||||
eventRender: function(event, element, view) {
|
||||
|
@ -153,14 +150,15 @@ function rcube_calendar_ui(settings)
|
|||
}
|
||||
if (view.name != 'month') {
|
||||
if (event.location) {
|
||||
element.find('div.fc-event-title').after('<div class="fc-event-location">@ ' + Q(event.location) + '</div>');
|
||||
element.find('div.fc-title').after('<div class="fc-event-location">@ ' + Q(event.location) + '</div>');
|
||||
}
|
||||
var time_element = element.find('div.fc-time');
|
||||
if (event.sensitivity && event.sensitivity != 'public')
|
||||
element.find('div.fc-event-time').append('<i class="fc-icon-sensitive"></i>');
|
||||
time_element.append('<i class="fc-icon-sensitive"></i>');
|
||||
if (event.recurrence)
|
||||
element.find('div.fc-event-time').append('<i class="fc-icon-recurring"></i>');
|
||||
time_element.append('<i class="fc-icon-recurring"></i>');
|
||||
if (event.alarms || (event.valarms && event.valarms.length))
|
||||
element.find('div.fc-event-time').append('<i class="fc-icon-alarms"></i>');
|
||||
time_element.append('<i class="fc-icon-alarms"></i>');
|
||||
}
|
||||
if (event.status) {
|
||||
element.addClass('cal-event-status-' + String(event.status).toLowerCase());
|
||||
|
@ -175,7 +173,7 @@ function rcube_calendar_ui(settings)
|
|||
},
|
||||
// callback when a specific event is clicked
|
||||
eventClick: function(event, ev, view) {
|
||||
if (!event.temp && String(event.className).indexOf('fc-type-freebusy') < 0)
|
||||
if (!event.temp && (!event.className || event.className.indexOf('fc-type-freebusy') < 0))
|
||||
event_show_dialog(event, ev);
|
||||
}
|
||||
};
|
||||
|
@ -184,7 +182,6 @@ function rcube_calendar_ui(settings)
|
|||
var Q = this.quote_html;
|
||||
var text2html = this.text2html;
|
||||
var event_date_text = this.event_date_text;
|
||||
var parse_datetime = this.parse_datetime;
|
||||
var date2unixtime = this.date2unixtime;
|
||||
var fromunixtime = this.fromunixtime;
|
||||
var parseISO8601 = this.parseISO8601;
|
||||
|
@ -226,8 +223,8 @@ function rcube_calendar_ui(settings)
|
|||
// clone the given date object and optionally adjust time
|
||||
var clone_date = function(date, adjust)
|
||||
{
|
||||
var d = new Date(date.getTime());
|
||||
|
||||
var d = 'toDate' in date ? date.toDate() : new Date(date.getTime());
|
||||
|
||||
// set time to 00:00
|
||||
if (adjust == 1) {
|
||||
d.setHours(0);
|
||||
|
@ -238,7 +235,7 @@ function rcube_calendar_ui(settings)
|
|||
d.setHours(23);
|
||||
d.setMinutes(59);
|
||||
}
|
||||
|
||||
|
||||
return d;
|
||||
};
|
||||
|
||||
|
@ -256,6 +253,11 @@ function rcube_calendar_ui(settings)
|
|||
return date2servertime(date).replace(/[^0-9]/g, '').substr(0, (dateonly ? 8 : 14));
|
||||
}
|
||||
|
||||
var format_date = function(date, format)
|
||||
{
|
||||
return $.fullCalendar.formatDate('toDate' in date ? date : moment(date), format);
|
||||
};
|
||||
|
||||
var format_datetime = function(date, mode, voice)
|
||||
{
|
||||
return me.format_datetime(date, mode, voice);
|
||||
|
@ -633,11 +635,19 @@ function rcube_calendar_ui(settings)
|
|||
var priority = $('#edit-priority').val(event.priority);
|
||||
var sensitivity = $('#edit-sensitivity').val(event.sensitivity);
|
||||
var syncstart = $('#edit-recurrence-syncstart input');
|
||||
var duration = Math.round((event.end.getTime() - event.start.getTime()) / 1000);
|
||||
var startdate = $('#edit-startdate').val($.fullCalendar.formatDate(event.start, settings['date_format'])).data('duration', duration);
|
||||
var starttime = $('#edit-starttime').val($.fullCalendar.formatDate(event.start, settings['time_format'])).show();
|
||||
var enddate = $('#edit-enddate').val($.fullCalendar.formatDate(event.end, settings['date_format']));
|
||||
var endtime = $('#edit-endtime').val($.fullCalendar.formatDate(event.end, settings['time_format'])).show();
|
||||
var end = 'toDate' in event.end ? event.end : moment(event.end);
|
||||
var start = 'toDate' in event.start ? event.start : moment(event.start);
|
||||
var duration = Math.round((end.format('x') - start.format('x')) / 1000);
|
||||
|
||||
// Correct the fullCalendar end date for all-day events
|
||||
if (!end.hasTime()) {
|
||||
end.subtract(1, 'days');
|
||||
}
|
||||
|
||||
var startdate = $('#edit-startdate').val(format_date(start, settings.date_format)).data('duration', duration);
|
||||
var starttime = $('#edit-starttime').val(format_date(start, settings.time_format)).show();
|
||||
var enddate = $('#edit-enddate').val(format_date(end, settings.date_format));
|
||||
var endtime = $('#edit-endtime').val(format_date(end, settings.time_format)).show();
|
||||
var allday = $('#edit-allday').get(0);
|
||||
var notify = $('#edit-attendees-donotify').get(0);
|
||||
var invite = $('#edit-attendees-invite').get(0);
|
||||
|
@ -769,8 +779,8 @@ function rcube_calendar_ui(settings)
|
|||
// init dialog buttons
|
||||
var buttons = [],
|
||||
save_func = function() {
|
||||
var start = parse_datetime(allday.checked ? '12:00' : starttime.val(), startdate.val());
|
||||
var end = parse_datetime(allday.checked ? '13:00' : endtime.val(), enddate.val());
|
||||
var start = me.parse_datetime(allday.checked ? '12:00' : starttime.val(), startdate.val());
|
||||
var end = me.parse_datetime(allday.checked ? '13:00' : endtime.val(), enddate.val());
|
||||
|
||||
// basic input validatetion
|
||||
if (start.getTime() > end.getTime()) {
|
||||
|
@ -1146,11 +1156,14 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
// set form elements
|
||||
var allday = $('#edit-allday').get(0);
|
||||
var duration = Math.round((event.end.getTime() - event.start.getTime()) / 1000);
|
||||
freebusy_ui.startdate = $('#schedule-startdate').val($.fullCalendar.formatDate(event.start, settings['date_format'])).data('duration', duration);
|
||||
freebusy_ui.starttime = $('#schedule-starttime').val($.fullCalendar.formatDate(event.start, settings['time_format'])).show();
|
||||
freebusy_ui.enddate = $('#schedule-enddate').val($.fullCalendar.formatDate(event.end, settings['date_format']));
|
||||
freebusy_ui.endtime = $('#schedule-endtime').val($.fullCalendar.formatDate(event.end, settings['time_format'])).show();
|
||||
var end = 'toDate' in event.end ? event.end : moment(event.end);
|
||||
var start = 'toDate' in event.start ? event.start : moment(event.start);
|
||||
var duration = Math.round((end.format('x') - start.format('x')) / 1000);
|
||||
|
||||
freebusy_ui.startdate = $('#schedule-startdate').val(format_date(start, settings.date_format)).data('duration', duration);
|
||||
freebusy_ui.starttime = $('#schedule-starttime').val(format_date(start, settings.time_format)).show();
|
||||
freebusy_ui.enddate = $('#schedule-enddate').val(format_date(end, settings.date_format));
|
||||
freebusy_ui.endtime = $('#schedule-endtime').val(format_date(end, settings.time_format)).show();
|
||||
|
||||
if (allday.checked) {
|
||||
freebusy_ui.starttime.val("12:00").hide();
|
||||
|
@ -1319,16 +1332,16 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
for (var s = 0, t = freebusy_ui.start.getTime(); t < freebusy_ui.end.getTime(); s++) {
|
||||
curdate.setTime(t);
|
||||
datestr = fc.fullCalendar('formatDate', curdate, date_format);
|
||||
datestr = format_date(curdate, date_format);
|
||||
if (datestr != lastdate) {
|
||||
if (lastdate && !allday) break;
|
||||
dates_row += '<th colspan="' + dayslots + '" class="boxtitle date' + $.fullCalendar.formatDate(curdate, 'ddMMyyyy') + '">' + Q(datestr) + '</th>';
|
||||
dates_row += '<th colspan="' + dayslots + '" class="boxtitle date' + format_date(curdate, 'DDMMYYYY') + '">' + Q(datestr) + '</th>';
|
||||
lastdate = datestr;
|
||||
}
|
||||
|
||||
// set css class according to working hours
|
||||
css = is_weekend(curdate) || (freebusy_ui.interval <= 60 && !is_workinghour(curdate)) ? 'offhours' : 'workinghours';
|
||||
times_row += '<td class="' + times_css + css + '" id="t-' + Math.floor(t/1000) + '">' + Q(allday ? rcmail.gettext('all-day','calendar') : $.fullCalendar.formatDate(curdate, settings['time_format'])) + '</td>';
|
||||
times_row += '<td class="' + times_css + css + '" id="t-' + Math.floor(t/1000) + '">' + Q(allday ? rcmail.gettext('all-day','calendar') : format_date(curdate, settings.time_format)) + '</td>';
|
||||
slots_row += '<td class="' + css + '"> </td>';
|
||||
|
||||
t += interval * 60000;
|
||||
|
@ -1674,10 +1687,10 @@ function rcube_calendar_ui(settings)
|
|||
}
|
||||
me.selected_event.start = start;
|
||||
me.selected_event.end = end;
|
||||
freebusy_ui.startdate.val($.fullCalendar.formatDate(start, settings['date_format']));
|
||||
freebusy_ui.starttime.val($.fullCalendar.formatDate(start, settings['time_format']));
|
||||
freebusy_ui.enddate.val($.fullCalendar.formatDate(end, settings['date_format']));
|
||||
freebusy_ui.endtime.val($.fullCalendar.formatDate(end, settings['time_format']));
|
||||
freebusy_ui.startdate.val(format_date(start, settings.date_format));
|
||||
freebusy_ui.starttime.val(format_date(start, settings.time_format));
|
||||
freebusy_ui.enddate.val(format_date(end, settings.date_format));
|
||||
freebusy_ui.endtime.val(format_date(end, settings.time_format));
|
||||
freebusy_ui.needsupdate = true;
|
||||
};
|
||||
|
||||
|
@ -1793,8 +1806,8 @@ function rcube_calendar_ui(settings)
|
|||
if (me.selected_event) {
|
||||
var allday = $('#edit-allday').get(0);
|
||||
me.selected_event.allDay = allday.checked;
|
||||
me.selected_event.start = parse_datetime(allday.checked ? '12:00' : $('#edit-starttime').val(), $('#edit-startdate').val());
|
||||
me.selected_event.end = parse_datetime(allday.checked ? '13:00' : $('#edit-endtime').val(), $('#edit-enddate').val());
|
||||
me.selected_event.start = me.parse_datetime(allday.checked ? '12:00' : $('#edit-starttime').val(), $('#edit-startdate').val());
|
||||
me.selected_event.end = me.parse_datetime(allday.checked ? '13:00' : $('#edit-endtime').val(), $('#edit-enddate').val());
|
||||
if (event_attendees)
|
||||
freebusy_ui.needsupdate = true;
|
||||
$('#edit-startdate').data('duration', Math.round((me.selected_event.end.getTime() - me.selected_event.start.getTime()) / 1000));
|
||||
|
@ -2103,8 +2116,7 @@ function rcube_calendar_ui(settings)
|
|||
eventRender: function(event, element, view) {
|
||||
var title = rcmail.get_label(event.status, 'calendar');
|
||||
element.addClass('status-' + event.status);
|
||||
element.find('.fc-event-head').hide();
|
||||
element.find('.fc-event-title').text(title);
|
||||
element.find('.fc-title').text(title);
|
||||
element.attr('aria-label', me.event_date_text(event, true) + ': ' + title);
|
||||
}
|
||||
}));
|
||||
|
@ -2414,13 +2426,13 @@ function rcube_calendar_ui(settings)
|
|||
event_show_dialog(me.selected_event);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// add the given date to the RDATE list
|
||||
var add_rdate = function(date)
|
||||
{
|
||||
var li = $('<li>')
|
||||
.attr('data-value', date2servertime(date))
|
||||
.html('<span>' + Q($.fullCalendar.formatDate(date, settings['date_format'])) + '</span>')
|
||||
.append($('<span>').text(format_date(date, settings.date_format)))
|
||||
.appendTo('#edit-recurrence-rdates');
|
||||
|
||||
$('<a>').attr('href', '#del')
|
||||
|
@ -2459,19 +2471,20 @@ function rcube_calendar_ui(settings)
|
|||
{
|
||||
me.saving_lock = rcmail.set_busy(true, 'calendar.savingdata');
|
||||
rcmail.http_post('calendar/event', $.extend({ action:action, e:data }, (add || {})));
|
||||
|
||||
|
||||
// render event temporarily into the calendar
|
||||
if ((data.start && data.end) || data.id) {
|
||||
var event = data.id ? $.extend(fc.fullCalendar('clientEvents', function(e){ return e.id == data.id; })[0], data) : data;
|
||||
var event = data.id ? $.extend(fc.fullCalendar('clientEvents', data.id)[0], data) : data;
|
||||
if (data.start)
|
||||
event.start = data.start;
|
||||
if (data.end)
|
||||
event.end = data.end;
|
||||
if (data.allday !== undefined)
|
||||
event.allDay = data.allday;
|
||||
if (data.allDay !== undefined)
|
||||
event.allDay = data.allDay;
|
||||
event.editable = false;
|
||||
event.temp = true;
|
||||
event.className = 'fc-event-cal-'+data.calendar+' fc-event-temp';
|
||||
event.className = ['fc-event-cal-'+data.calendar, 'fc-event-temp'];
|
||||
|
||||
fc.fullCalendar(data.id ? 'updateEvent' : 'renderEvent', event);
|
||||
|
||||
// mark all recurring instances as temp
|
||||
|
@ -2480,7 +2493,7 @@ function rcube_calendar_ui(settings)
|
|||
$.each(fc.fullCalendar('clientEvents', function(e){ return e.id == base_id || e.recurrence_id == base_id; }), function(i,ev) {
|
||||
ev.temp = true;
|
||||
ev.editable = false;
|
||||
event.className += ' fc-event-temp';
|
||||
event.className.push('fc-event-temp');
|
||||
fc.fullCalendar('updateEvent', ev);
|
||||
});
|
||||
}
|
||||
|
@ -2632,7 +2645,7 @@ function rcube_calendar_ui(settings)
|
|||
fc.fullCalendar('refetchEvents');
|
||||
}
|
||||
}).addClass('event-update-confirm').show();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
// show regular confirm box when deleting
|
||||
|
@ -2643,7 +2656,7 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
// do update
|
||||
update_event(action, data);
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -2700,7 +2713,7 @@ function rcube_calendar_ui(settings)
|
|||
modal: true,
|
||||
width: 680,
|
||||
height: h,
|
||||
title: $.fullCalendar.formatDate(date, 'dddd ' + settings['date_long']),
|
||||
title: format_date(date, 'dddd ' + settings.date_long),
|
||||
buttons: [{
|
||||
text: rcmail.gettext('cancel', 'calendar'),
|
||||
'class': 'cancel',
|
||||
|
@ -2720,7 +2733,7 @@ function rcube_calendar_ui(settings)
|
|||
year: date.getFullYear(),
|
||||
eventSources: sources
|
||||
}));
|
||||
|
||||
|
||||
this.fisheye_date = date;
|
||||
};
|
||||
|
||||
|
@ -2839,7 +2852,7 @@ function rcube_calendar_ui(settings)
|
|||
this.print_calendars = function(view)
|
||||
{
|
||||
if (!view) view = fc.fullCalendar('getView').name;
|
||||
var date = fc.fullCalendar('getDate') || new Date();
|
||||
var date = fc.fullCalendar('getDate').toDate();
|
||||
var range = fc.fullCalendar('option', 'listRange');
|
||||
var sections = fc.fullCalendar('option', 'listSections');
|
||||
rcmail.open_window(rcmail.url('print', { view: view, date: date2unixtime(date), range: range, sections: sections, search: this.search_query }), true, true);
|
||||
|
@ -2849,9 +2862,7 @@ function rcube_calendar_ui(settings)
|
|||
this.add_event = function(templ) {
|
||||
if (this.selected_calendar) {
|
||||
var now = new Date();
|
||||
var date = fc.fullCalendar('getDate');
|
||||
if (typeof date != 'Date')
|
||||
date = now;
|
||||
var date = fc.fullCalendar('getDate').toDate();
|
||||
date.setHours(now.getHours()+1);
|
||||
date.setMinutes(0);
|
||||
var end = new Date(date.getTime());
|
||||
|
@ -2941,9 +2952,10 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
this.calendar_refresh_source = function(id)
|
||||
{
|
||||
// got race-conditions fc.currentFetchID when using refetchEvents,
|
||||
// got race-conditions fc.currentFetchID when using refetchEventSources,
|
||||
// so we remove and add the source instead
|
||||
// fc.fullCalendar('refetchEvents', me.calendars[id]);
|
||||
// fc.fullCalendar('refetchEventSources', me.calendars[id]);
|
||||
// TODO: Check it again with fullcalendar >= 3.9
|
||||
fc.fullCalendar('removeEventSource', me.calendars[id]);
|
||||
fc.fullCalendar('addEventSource', me.calendars[id]);
|
||||
};
|
||||
|
@ -3093,7 +3105,7 @@ function rcube_calendar_ui(settings)
|
|||
attachmt = $('#event-export-attachments').get(0).checked;
|
||||
|
||||
if (range == 'custom')
|
||||
start = date2unixtime(parse_datetime('00:00', $('#event-export-startdate').val()));
|
||||
start = date2unixtime(me.parse_datetime('00:00', $('#event-export-startdate').val()));
|
||||
else if (range > 0)
|
||||
start = 'today -' + range + ' months';
|
||||
|
||||
|
@ -3229,16 +3241,13 @@ function rcube_calendar_ui(settings)
|
|||
return false;
|
||||
}
|
||||
});
|
||||
fc.fullCalendar('refetchEvents', source, true);
|
||||
}
|
||||
else if (!source.active) {
|
||||
source.active = true;
|
||||
fc.fullCalendar('addEventSource', source);
|
||||
$('#rcmlical' + source.id + ' input').prop('checked', true);
|
||||
}
|
||||
else
|
||||
fc.fullCalendar('refetchEvents', source, true);
|
||||
|
||||
fc.fullCalendar('refetchEventSources', source);
|
||||
fetch_counts();
|
||||
}
|
||||
// add/update single event object
|
||||
|
@ -3261,7 +3270,7 @@ function rcube_calendar_ui(settings)
|
|||
}
|
||||
// refetch all calendars
|
||||
else if (p.refetch) {
|
||||
fc.fullCalendar('refetchEvents', undefined, true);
|
||||
fc.fullCalendar('refetchEvents');
|
||||
fetch_counts();
|
||||
}
|
||||
};
|
||||
|
@ -3271,8 +3280,8 @@ function rcube_calendar_ui(settings)
|
|||
{
|
||||
var view = fc.fullCalendar('getView');
|
||||
|
||||
query.start = date2unixtime(view.visStart);
|
||||
query.end = date2unixtime(view.visEnd);
|
||||
query.start = date2unixtime(view.start.toDate());
|
||||
query.end = date2unixtime(view.end.toDate());
|
||||
|
||||
if (this.search_query)
|
||||
query.q = this.search_query;
|
||||
|
@ -3327,7 +3336,7 @@ function rcube_calendar_ui(settings)
|
|||
var query = { view: fc.fullCalendar('getView').name },
|
||||
date = fc.fullCalendar('getDate');
|
||||
if (date)
|
||||
query.date = date2unixtime(date);
|
||||
query.date = date2unixtime(date.toDate());
|
||||
rcmail.redirect(rcmail.url('', query));
|
||||
}
|
||||
|
||||
|
@ -3337,7 +3346,7 @@ function rcube_calendar_ui(settings)
|
|||
var query = { view: current_view },
|
||||
date = fc.fullCalendar('getDate');
|
||||
if (date)
|
||||
query.date = date2unixtime(date);
|
||||
query.date = date2unixtime(date.toDate());
|
||||
|
||||
if (window.history.replaceState)
|
||||
window.history.replaceState({}, document.title, rcmail.url('', query).replace('&_action=', ''));
|
||||
|
@ -3388,9 +3397,10 @@ function rcube_calendar_ui(settings)
|
|||
this.search_query = q;
|
||||
|
||||
// change to list view
|
||||
fc.fullCalendar('option', 'listSections', 'month')
|
||||
.fullCalendar('option', 'listRange', Math.max(60, settings['agenda_range']))
|
||||
.fullCalendar('changeView', 'table');
|
||||
fc.fullCalendar('option', 'listSections', 'month');
|
||||
fc.fullCalendar('option', 'listRange', Math.max(60, settings.agenda_range));
|
||||
// TODO: fullcalendar 3.9 has dateOrRange argument here, shall we use it?
|
||||
fc.fullCalendar('changeView', 'listYear');
|
||||
|
||||
update_agenda_toolbar();
|
||||
|
||||
|
@ -3416,8 +3426,8 @@ function rcube_calendar_ui(settings)
|
|||
fc.find('.fc-list-content > .fc-listappend').hide();
|
||||
|
||||
// restore original event sources and view mode from fullcalendar
|
||||
fc.fullCalendar('option', 'listSections', settings['agenda_sections'])
|
||||
.fullCalendar('option', 'listRange', settings['agenda_range']);
|
||||
fc.fullCalendar('option', 'listSections', settings.agenda_sections);
|
||||
fc.fullCalendar('option', 'listRange', settings.agenda_range);
|
||||
|
||||
update_agenda_toolbar();
|
||||
|
||||
|
@ -3478,7 +3488,7 @@ function rcube_calendar_ui(settings)
|
|||
.append($('<span class="inner">').text(rcmail.gettext(elastic ? 'earlierevents' : 'searchearlierdates', 'calendar')))
|
||||
.appendTo(lc)
|
||||
.click(function() {
|
||||
fc.fullCalendar('incrementDate', 0, -1, 0);
|
||||
fc.fullCalendar('incrementDate', "-P1M");
|
||||
});
|
||||
|
||||
lc.append(" ");
|
||||
|
@ -3489,11 +3499,12 @@ function rcube_calendar_ui(settings)
|
|||
.click(function() {
|
||||
var range = fc.fullCalendar('option', 'listRange');
|
||||
if (range < 90) {
|
||||
fc.fullCalendar('option', 'listRange', fc.fullCalendar('option', 'listRange') + 30).fullCalendar('render');
|
||||
fc.fullCalendar('option', 'listRange', fc.fullCalendar('option', 'listRange') + 30);
|
||||
fc.fullCalendar('render');
|
||||
update_agenda_toolbar();
|
||||
}
|
||||
else
|
||||
fc.fullCalendar('incrementDate', 0, 1, 0);
|
||||
fc.fullCalendar('incrementDate', "P1M");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3532,7 +3543,7 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
me.calendars[id] = $.extend({
|
||||
url: rcmail.url('calendar/load_events', { source: id }),
|
||||
className: 'fc-event-cal-'+id,
|
||||
className: ['fc-event-cal-' + id],
|
||||
id: id
|
||||
}, cal);
|
||||
|
||||
|
@ -3767,7 +3778,7 @@ function rcube_calendar_ui(settings)
|
|||
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',
|
||||
className: ['fc-event-cal---invitation--itip'],
|
||||
color: '#fff',
|
||||
textColor: '#333',
|
||||
editable: false,
|
||||
|
@ -3782,7 +3793,7 @@ function rcube_calendar_ui(settings)
|
|||
header: {
|
||||
right: 'prev,next today',
|
||||
center: 'title',
|
||||
left: 'agendaDay,agendaWeek,month,table'
|
||||
left: 'agendaDay,agendaWeek,month,listYear'
|
||||
},
|
||||
date: viewdate.getDate(),
|
||||
month: viewdate.getMonth(),
|
||||
|
@ -3799,64 +3810,68 @@ function rcube_calendar_ui(settings)
|
|||
me.events_loaded($(this).fullCalendar('clientEvents').length);
|
||||
},
|
||||
// callback for date range selection
|
||||
select: function(start, end, allDay, e, view) {
|
||||
var range_select = (!allDay || start.getDate() != end.getDate())
|
||||
select: function(start, end, e, view) {
|
||||
var range_select = (start.hasTime() || start != end)
|
||||
if (dialog_check(e) && range_select)
|
||||
event_edit_dialog('new', { start:start, end:end, allDay:allDay, calendar:me.selected_calendar });
|
||||
event_edit_dialog('new', { start:start, end:end, allDay:!start.hasTime(), calendar:me.selected_calendar });
|
||||
if (range_select || ignore_click)
|
||||
view.calendar.unselect();
|
||||
},
|
||||
// callback for clicks in all-day box
|
||||
dayClick: function(date, allDay, e, view) {
|
||||
dayClick: function(date, e, view) {
|
||||
var now = new Date().getTime();
|
||||
if (now - day_clicked_ts < 400 && day_clicked == date.getTime()) { // emulate double-click on day
|
||||
var enddate = new Date(); enddate.setTime(date.getTime() + DAY_MS - 60000);
|
||||
return event_edit_dialog('new', { start:date, end:enddate, allDay:allDay, calendar:me.selected_calendar });
|
||||
if (now - day_clicked_ts < 400 && day_clicked == date.toDate().getTime()) { // emulate double-click on day
|
||||
var enddate = new Date();
|
||||
if (date.hasTime())
|
||||
enddate.setTime(date.toDate().getTime() + DAY_MS - 60000);
|
||||
return event_edit_dialog('new', { start:date, end:enddate, allDay:!date.hasTime(), calendar:me.selected_calendar });
|
||||
}
|
||||
|
||||
|
||||
if (!ignore_click) {
|
||||
view.calendar.gotoDate(date);
|
||||
if (day_clicked && new Date(day_clicked).getMonth() != date.getMonth())
|
||||
view.calendar.select(date, date, allDay);
|
||||
if (day_clicked && new Date(day_clicked).getMonth() != date.toDate().getMonth())
|
||||
view.calendar.select(date, date);
|
||||
}
|
||||
day_clicked = date.getTime();
|
||||
day_clicked = date.toDate().getTime();
|
||||
day_clicked_ts = now;
|
||||
},
|
||||
// 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()) {
|
||||
event.end = new Date(event.start.getTime() + (allDay ? DAY_MS : HOUR_MS));
|
||||
eventDrop: function(event, delta, revertFunc) {
|
||||
var allday = !event.start.hasTime();
|
||||
|
||||
if (!event.end || event.end.format('x') < event.start.format('x')) {
|
||||
event.end = new Date(event.start.format('x') + (allday ? DAY_MS : HOUR_MS));
|
||||
}
|
||||
// moved to all-day section: set times to 12:00 - 13:00
|
||||
if (allDay && !event.allDay) {
|
||||
event.start.setHours(12);
|
||||
event.start.setMinutes(0);
|
||||
event.start.setSeconds(0);
|
||||
event.end.setHours(13);
|
||||
event.end.setMinutes(0);
|
||||
event.end.setSeconds(0);
|
||||
if (allday && !event.allDay) {
|
||||
event.start.hours(12);
|
||||
event.start.minutes(0);
|
||||
event.start.seconds(0);
|
||||
event.end.hours(13);
|
||||
event.end.minutes(0);
|
||||
event.end.seconds(0);
|
||||
}
|
||||
// moved from all-day section: set times to working hours
|
||||
else if (event.allDay && !allDay) {
|
||||
var newstart = event.start.getTime();
|
||||
else if (event.allDay && !allday) {
|
||||
var newstart = event.start.format('x');
|
||||
revertFunc(); // revert to get original duration
|
||||
var numdays = Math.max(1, Math.round((event.end.getTime() - event.start.getTime()) / DAY_MS)) - 1;
|
||||
event.start = new Date(newstart);
|
||||
event.end = new Date(newstart + numdays * DAY_MS);
|
||||
event.end.setHours(settings['work_end'] || 18);
|
||||
event.end.setMinutes(0);
|
||||
|
||||
if (event.end.getTime() < event.start.getTime())
|
||||
var numdays = Math.max(1, Math.round((event.end.format('x') - event.start.format('x')) / DAY_MS)) - 1;
|
||||
event.start = moment(newstart);
|
||||
event.end = moment(newstart + numdays * DAY_MS);
|
||||
event.end.hours(settings.work_end || 18);
|
||||
event.end.minutes(0);
|
||||
|
||||
if (event.end.diff(event.start) < 0)
|
||||
event.end = new Date(newstart + HOUR_MS);
|
||||
}
|
||||
|
||||
|
||||
// send move request to server
|
||||
var data = {
|
||||
id: event.id,
|
||||
calendar: event.calendar,
|
||||
start: date2servertime(event.start),
|
||||
end: date2servertime(event.end),
|
||||
allday: allDay?1:0
|
||||
allDay: allday?1:0
|
||||
};
|
||||
update_event_confirm('move', event, data);
|
||||
},
|
||||
|
@ -3864,9 +3879,9 @@ function rcube_calendar_ui(settings)
|
|||
eventResize: function(event, delta) {
|
||||
// sanitize event dates
|
||||
if (event.allDay)
|
||||
event.start.setHours(12);
|
||||
if (!event.end || event.end.getTime() < event.start.getTime())
|
||||
event.end = new Date(event.start.getTime() + HOUR_MS);
|
||||
event.start.hours(12);
|
||||
if (!event.end || event.end.diff(event.start) < 0)
|
||||
event.end = new Date(event.start.format('x') + HOUR_MS);
|
||||
|
||||
// send resize request to server
|
||||
var data = {
|
||||
|
@ -3874,39 +3889,35 @@ function rcube_calendar_ui(settings)
|
|||
calendar: event.calendar,
|
||||
start: date2servertime(event.start),
|
||||
end: date2servertime(event.end),
|
||||
allday: event.allDay?1:0
|
||||
allDay: event.allDay?1:0
|
||||
};
|
||||
update_event_confirm('resize', event, data);
|
||||
},
|
||||
viewDisplay: function(view) {
|
||||
$('#agendaoptions')[view.name == 'table' ? 'show' : 'hide']();
|
||||
viewRender: function(view) {
|
||||
$('#agendaoptions')[view.name == 'listYear' ? 'show' : 'hide']();
|
||||
if (minical) {
|
||||
window.setTimeout(function(){ minical.datepicker('setDate', fc.fullCalendar('getDate')); }, exec_deferred);
|
||||
window.setTimeout(function(){ minical.datepicker('setDate', fc.fullCalendar('getDate').toDate()); }, exec_deferred);
|
||||
if (view.name != current_view)
|
||||
me.view_resize();
|
||||
current_view = view.name;
|
||||
me.update_state();
|
||||
}
|
||||
},
|
||||
viewRender: function(view) {
|
||||
if (fc && view.name == 'month')
|
||||
fc.fullCalendar('option', 'maxHeight', Math.floor((view.element.parent().height()-18) / 6) - 35);
|
||||
}
|
||||
}));
|
||||
|
||||
// if start date is changed, shift end date according to initial duration
|
||||
var shift_enddate = function(dateText) {
|
||||
var newstart = parse_datetime('0', dateText);
|
||||
var newstart = me.parse_datetime('0', dateText);
|
||||
var newend = new Date(newstart.getTime() + $('#edit-startdate').data('duration') * 1000);
|
||||
$('#edit-enddate').val($.fullCalendar.formatDate(newend, me.settings['date_format']));
|
||||
$('#edit-enddate').val(format_date(newend, me.settings.date_format));
|
||||
event_times_changed();
|
||||
};
|
||||
|
||||
// Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
|
||||
// Uses the default $.datepicker.iso8601Week() function but takes firstDay setting into account.
|
||||
// This is a temporary fix until http://bugs.jqueryui.com/ticket/8420 is resolved.
|
||||
var iso8601Week = datepicker_settings.calculateWeek = function(date) {
|
||||
var mondayOffset = Math.abs(1 - datepicker_settings.firstDay);
|
||||
var iso8601Week = me.datepicker_settings.calculateWeek = function(date) {
|
||||
var mondayOffset = Math.abs(1 - me.datepicker_settings.firstDay);
|
||||
return $.datepicker.iso8601Week(new Date(date.getTime() + mondayOffset * 86400000));
|
||||
};
|
||||
|
||||
|
@ -3921,14 +3932,15 @@ function rcube_calendar_ui(settings)
|
|||
};
|
||||
|
||||
// initialize small calendar widget using jQuery UI datepicker
|
||||
minical = $('#datepicker').datepicker($.extend(datepicker_settings, {
|
||||
minical = $('#datepicker').datepicker($.extend(me.datepicker_settings, {
|
||||
inline: true,
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
onSelect: function(dateText, inst) {
|
||||
ignore_click = true;
|
||||
var d = minical.datepicker('getDate'); //parse_datetime('0:0', dateText);
|
||||
fc.fullCalendar('gotoDate', d).fullCalendar('select', d, d, true);
|
||||
var d = minical.datepicker('getDate');
|
||||
fc.fullCalendar('gotoDate', d)
|
||||
fc.fullCalendar('select', d, d);
|
||||
setTimeout(function() { pretty_select($('select', minical)); }, 25);
|
||||
},
|
||||
onChangeMonthYear: function(year, month, inst) {
|
||||
|
@ -3936,9 +3948,13 @@ function rcube_calendar_ui(settings)
|
|||
setTimeout(function() { pretty_select($('select', minical)); }, 25);
|
||||
},
|
||||
beforeShowDay: function(date) {
|
||||
// TODO: this pretty_select() calls should be implemented in a different way
|
||||
setTimeout(function() { pretty_select($('select', minical)); }, 25);
|
||||
var view = fc.fullCalendar('getView');
|
||||
var active = view.visStart && date.getTime() >= view.visStart.getTime() && date.getTime() < view.visEnd.getTime();
|
||||
|
||||
var view = fc.fullCalendar('getView'),
|
||||
dt = moment(date).format('YYYYMMDD'),
|
||||
active = view.start && view.start.format('YYYYMMDD') <= dt && view.end.format('YYYYMMDD') > dt;
|
||||
|
||||
return [ true, (active ? 'ui-datepicker-activerange ui-datepicker-active-' + view.name : ''), ''];
|
||||
}
|
||||
})) // set event handler for clicks on calendar week cell of the datepicker widget
|
||||
|
@ -3951,7 +3967,7 @@ function rcube_calendar_ui(settings)
|
|||
if (minical.data('year'))
|
||||
base_date.setYear(minical.data('year'));
|
||||
base_date.setHours(12);
|
||||
base_date.setDate(base_date.getDate() - ((base_date.getDay() + 6) % 7) + datepicker_settings.firstDay);
|
||||
base_date.setDate(base_date.getDate() - ((base_date.getDay() + 6) % 7) + me.datepicker_settings.firstDay);
|
||||
var base_kw = iso8601Week(base_date),
|
||||
target_kw = parseInt(cell.html()),
|
||||
wdiff = target_kw - base_kw;
|
||||
|
@ -3960,9 +3976,10 @@ function rcube_calendar_ui(settings)
|
|||
else if (wdiff < -10)
|
||||
base_date.setYear(base_date.getFullYear() + 1);
|
||||
// select monday of the chosen calendar week
|
||||
var day_off = base_date.getDay() - datepicker_settings.firstDay,
|
||||
var day_off = base_date.getDay() - me.datepicker_settings.firstDay,
|
||||
date = new Date(base_date.getTime() - day_off * DAY_MS + wdiff * 7 * DAY_MS);
|
||||
fc.fullCalendar('gotoDate', date).fullCalendar('setDate', date).fullCalendar('changeView', 'agendaWeek');
|
||||
fc.fullCalendar('gotoDate', date)
|
||||
fc.fullCalendar('changeView', 'agendaWeek');
|
||||
minical.datepicker('setDate', date);
|
||||
setTimeout(function() { pretty_select($('select', minical)); }, 25);
|
||||
}
|
||||
|
@ -4011,11 +4028,11 @@ function rcube_calendar_ui(settings)
|
|||
$('#edit-recurrence-syncstart').hide();
|
||||
};
|
||||
|
||||
$('#eventedit:not([data-notabs])').tabs({activate: tab_change}); // Larry
|
||||
$('#eventedit a.nav-link').on('show.bs.tab', tab_change); // Elastic
|
||||
$('#eventedit:not([data-notabs])').tabs({activate: tab_change}); // Larry
|
||||
$('#eventedit a.nav-link').on('show.bs.tab', tab_change); // Elastic
|
||||
|
||||
$('#edit-enddate').datepicker(datepicker_settings);
|
||||
$('#edit-startdate').datepicker(datepicker_settings).datepicker('option', 'onSelect', shift_enddate).change(function(){ shift_enddate(this.value); });
|
||||
$('#edit-enddate').datepicker(me.datepicker_settings);
|
||||
$('#edit-startdate').datepicker(me.datepicker_settings).datepicker('option', 'onSelect', shift_enddate).change(function(){ shift_enddate(this.value); });
|
||||
$('#edit-enddate').datepicker('option', 'onSelect', event_times_changed).change(event_times_changed);
|
||||
$('#edit-allday').click(function(){ $('#edit-starttime, #edit-endtime')[(this.checked?'hide':'show')](); event_times_changed(); });
|
||||
|
||||
|
@ -4030,10 +4047,10 @@ function rcube_calendar_ui(settings)
|
|||
// adjust end time when changing start
|
||||
$('#edit-starttime').change(function(e) {
|
||||
var dstart = $('#edit-startdate'),
|
||||
newstart = parse_datetime(this.value, dstart.val()),
|
||||
newstart = me.parse_datetime(this.value, dstart.val()),
|
||||
newend = new Date(newstart.getTime() + dstart.data('duration') * 1000);
|
||||
$('#edit-endtime').val($.fullCalendar.formatDate(newend, me.settings['time_format']));
|
||||
$('#edit-enddate').val($.fullCalendar.formatDate(newend, me.settings['date_format']));
|
||||
$('#edit-endtime').val(format_date(newend, me.settings.time_format));
|
||||
$('#edit-enddate').val(format_date(newend, me.settings.date_format));
|
||||
event_times_changed();
|
||||
});
|
||||
|
||||
|
@ -4052,7 +4069,7 @@ function rcube_calendar_ui(settings)
|
|||
}
|
||||
});
|
||||
|
||||
$('#event-export-startdate').datepicker(datepicker_settings);
|
||||
$('#event-export-startdate').datepicker(me.datepicker_settings);
|
||||
|
||||
// init attendees autocompletion
|
||||
var ac_props;
|
||||
|
@ -4176,14 +4193,16 @@ function rcube_calendar_ui(settings)
|
|||
});
|
||||
|
||||
$('#agenda-listrange').change(function(e){
|
||||
settings['agenda_range'] = parseInt($(this).val());
|
||||
fc.fullCalendar('option', 'listRange', settings['agenda_range']).fullCalendar('render');
|
||||
settings.agenda_range = parseInt($(this).val());
|
||||
fc.fullCalendar('option', 'listRange', settings.agenda_range)
|
||||
fc.fullCalendar('render');
|
||||
// TODO: save new settings in prefs
|
||||
}).val(settings['agenda_range']);
|
||||
}).val(settings.agenda_range);
|
||||
|
||||
$('#agenda-listsections').change(function(e){
|
||||
settings['agenda_sections'] = $(this).val();
|
||||
fc.fullCalendar('option', 'listSections', settings['agenda_sections']).fullCalendar('render');
|
||||
settings.agenda_sections = $(this).val();
|
||||
fc.fullCalendar('option', 'listSections', settings.agenda_sections);
|
||||
fc.fullCalendar('render');
|
||||
// TODO: save new settings in prefs
|
||||
}).val(fc.fullCalendar('option', 'listSections'));
|
||||
|
||||
|
@ -4199,10 +4218,6 @@ function rcube_calendar_ui(settings)
|
|||
// fetch counts for some calendars
|
||||
fetch_counts();
|
||||
|
||||
// add proprietary css styles if not IE
|
||||
if (!bw.ie)
|
||||
$('div.fc-content').addClass('rcube-fc-content');
|
||||
|
||||
// Save-as-event dialog content
|
||||
if (rcmail.env.action == 'dialog-ui') {
|
||||
var date = new Date(), event = {allDay: false, calendar: me.selected_calendar};
|
||||
|
@ -4324,10 +4339,10 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
|
||||
// Elastic mods
|
||||
if ($('#calendar').data('elastic-mode')) {
|
||||
var selector = $('<div class="btn-group btn-group-toggle" role="group">').appendTo('.fc-header-left'),
|
||||
nav = $('<div class="btn-group btn-group-toggle" role="group">').appendTo('.fc-header-right');
|
||||
var selector = $('<div class="btn-group btn-group-toggle" role="group">').appendTo('.fc-header-toolbar > .fc-left'),
|
||||
nav = $('<div class="btn-group btn-group-toggle" role="group">').appendTo('.fc-header-toolbar > .fc-right');
|
||||
|
||||
$('.fc-header-left > span').each(function() {
|
||||
$('.fc-header-toolbar > .fc-left button').each(function() {
|
||||
var new_btn, cl = 'btn btn-secondary', btn = $(this),
|
||||
activate = function(button) {
|
||||
selector.children('.active').removeClass('active');
|
||||
|
@ -4352,19 +4367,19 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
});
|
||||
|
||||
$.each(['prev', 'today', 'next'], function() {
|
||||
var btn = $('.fc-header-right').find('.fc-button-' + this);
|
||||
var btn = $('.fc-header-toolbar > .fc-right').find('.fc-button-' + this);
|
||||
$('<button>').attr({'class': 'btn btn-secondary', type: 'button'})
|
||||
.text(btn.text()).appendTo(nav).on('click', function() { btn.click(); });
|
||||
});
|
||||
|
||||
$('#timezone-display').appendTo($('.fc-header-center')).removeClass('hidden');
|
||||
$('#timezone-display').appendTo($('.fc-header-toolbar > .fc-center')).removeClass('hidden');
|
||||
$('#agendaoptions').detach().insertAfter('table.fc-header');
|
||||
|
||||
$('.content-frame-navigation a.button.date').appendTo('.content > .searchbar');
|
||||
|
||||
// Mobile header title
|
||||
if (window.MutationObserver) {
|
||||
var title = $('.fc-header-title'),
|
||||
var title = $('.fc-header-toolbar > .fc-center h2'),
|
||||
mobile_header = $('#layout > .content > .header > .header-title'),
|
||||
callback = function() {
|
||||
var text = title.text();
|
||||
|
|
File diff suppressed because it is too large
Load diff
4511
plugins/calendar/lib/js/moment.js
Normal file
4511
plugins/calendar/lib/js/moment.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1585,7 +1585,7 @@ a.dropdown-link:after {
|
|||
top: 0;
|
||||
}
|
||||
|
||||
#resource-freebusy-calendar .fc-content .fc-event-bg {
|
||||
#resource-freebusy-calendar .fc-content .fc-bg {
|
||||
background: 0;
|
||||
}
|
||||
|
||||
|
@ -1636,32 +1636,16 @@ a.dropdown-link:after {
|
|||
|
||||
/* fullcalendar style overrides */
|
||||
|
||||
.rcube-fc-content {
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-content {
|
||||
position: absolute !important;
|
||||
top: 40px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
.calendarmain .fc-body {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.calendarmain.quickview-active .fc-content {
|
||||
.calendarmain.quickview-active .fc-body {
|
||||
background-image: url('images/focusview.png');
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#fish-eye-view .fc-content {
|
||||
top: 2px;
|
||||
bottom: 2px;
|
||||
}
|
||||
|
||||
#quickview-calendar {
|
||||
padding: 8px;
|
||||
overflow: hidden;
|
||||
|
@ -1704,15 +1688,12 @@ a.dropdown-link:after {
|
|||
margin-right: 0;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
.calendarmain #calendar .fc-left .fc-button {
|
||||
font-size: 10px;
|
||||
color: #555;
|
||||
min-width: 50px;
|
||||
max-width: 75px;
|
||||
height: 13px;
|
||||
height: 43px;
|
||||
line-height: 1em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
@ -1727,63 +1708,87 @@ a.dropdown-link:after {
|
|||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
outline: none;
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
-o-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button:focus {
|
||||
.calendarmain #calendar .fc-left .fc-button:focus {
|
||||
color: #fff;
|
||||
text-shadow: 0px 1px 1px #666;
|
||||
background-color: rgba(30,150,192, 0.5);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button.fc-state-active {
|
||||
.calendarmain #calendar .fc-left .fc-button::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-left .fc-button.fc-state-active {
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
text-shadow: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button-agendaDay {
|
||||
.calendarmain #calendar .fc-left .fc-agendaDay-button {
|
||||
background-position: center -120px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button-agendaDay.fc-state-active {
|
||||
.calendarmain #calendar .fc-left .fc-agendaDay-button.fc-state-active {
|
||||
background-position: center -160px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button-agendaWeek {
|
||||
.calendarmain #calendar .fc-left .fc-agendaWeek-button {
|
||||
background-position: center -200px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button-agendaWeek.fc-state-active {
|
||||
.calendarmain #calendar .fc-left .fc-agendaWeek-button.fc-state-active {
|
||||
background-position: center -240px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button-month {
|
||||
.calendarmain #calendar .fc-left .fc-month-button {
|
||||
background-position: center -280px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button-month.fc-state-active {
|
||||
.calendarmain #calendar .fc-left .fc-month-button.fc-state-active {
|
||||
background-position: center -320px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button-table {
|
||||
.calendarmain #calendar .fc-left .fc-listYear-button {
|
||||
background-position: center -360px;
|
||||
display: none; /* hide Agenda button for now */
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-left .fc-button-table.fc-state-active {
|
||||
.calendarmain #calendar .fc-left .fc-listYear.fc-state-active {
|
||||
background-position: center -400px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-right {
|
||||
padding-right: 252px;
|
||||
.calendarmain #calendar .fc-header-toolbar .fc-right {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-toolbar .fc-center {
|
||||
line-height: 2.5em;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-toolbar .fc-center h2 {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.calendarmain #calendar .fc-header-title {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#calendar .fc-toolbar.fc-header-toolbar {
|
||||
margin-bottom: 4px;
|
||||
margin-right: 250px;
|
||||
}
|
||||
|
||||
.fc-event {
|
||||
font-size: 1em !important;
|
||||
}
|
||||
|
@ -1791,18 +1796,6 @@ a.dropdown-link:after {
|
|||
.fc-event-hori.fc-type-freebusy,
|
||||
.fc-event-vert.fc-type-freebusy {
|
||||
opacity: 0.60;
|
||||
/*
|
||||
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;
|
||||
border-color: #444 !important;
|
||||
cursor: default !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;
|
||||
|
@ -1813,20 +1806,8 @@ a.dropdown-link:after {
|
|||
color: #999;
|
||||
}
|
||||
|
||||
.fc-event-hori.fc-type-freebusy .fc-event-skin,
|
||||
.fc-event-hori.fc-type-freebusy .fc-event-inner,
|
||||
.fc-event-vert.fc-type-freebusy .fc-event-skin,
|
||||
.fc-event-vert.fc-type-freebusy .fc-event-inner {
|
||||
/*
|
||||
background-color: transparent !important;
|
||||
border-color: #444 !important;
|
||||
color: #fff !important;
|
||||
text-shadow: 0 1px 1px #000;
|
||||
*/
|
||||
}
|
||||
|
||||
.fc-event-hori.fc-type-freebusy .fc-event-title,
|
||||
.fc-event-vert.fc-type-freebusy .fc-event-title {
|
||||
.fc-event-hori.fc-type-freebusy .fc-title,
|
||||
.fc-event-vert.fc-type-freebusy .fc-title {
|
||||
position: absolute;
|
||||
top: -5000px;
|
||||
}
|
||||
|
@ -1851,25 +1832,19 @@ a.dropdown-link:after {
|
|||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.fc-event-ns-other.fc-invitation-declined .fc-event-title {
|
||||
.fc-event-ns-other.fc-invitation-declined .fc-title {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.fc-event-vert.fc-invitation-tentative .fc-event-head,
|
||||
.fc-event-vert.fc-invitation-declined .fc-event-head,
|
||||
.fc-event-vert.fc-invitation-needs-action .fc-event-head {
|
||||
/* background-color: transparent !important; */
|
||||
}
|
||||
|
||||
.fc-event-vert.fc-invitation-tentative .fc-event-bg {
|
||||
.fc-event-vert.fc-invitation-tentative .fc-bg {
|
||||
background: url(data:image/gif;base64,R0lGODlhCAAIAPABAOuJAP///yH/C1hNUCBEYXRhWE1QAT8AIfkEBQAAAQAsAAAAAAgACAAAAg4Egmipx+ZaDPCtVPFNBQA7) 0 0 repeat #fff;
|
||||
}
|
||||
|
||||
.fc-event-vert.fc-invitation-needs-action .fc-event-bg {
|
||||
.fc-event-vert.fc-invitation-needs-action .fc-bg {
|
||||
background: url(data:image/gif;base64,R0lGODlhCAAIAPABAFdXx////yH/C1hNUCBEYXRhWE1QAT8AIfkEBQAAAQAsAAAAAAgACAAAAg4Egmipx+ZaDPCtVPFNBQA7) 0 0 repeat #fff;
|
||||
}
|
||||
|
||||
.fc-event-vert.fc-invitation-declined .fc-event-bg {
|
||||
.fc-event-vert.fc-invitation-declined .fc-bg {
|
||||
background: url(data:image/gif;base64,R0lGODlhCAAIAPABAMwAAP///yH/C1hNUCBEYXRhWE1QAT8AIfkEBQAAAQAsAAAAAAgACAAAAg4Egmipx+ZaDPCtVPFNBQA7) 0 0 repeat #fff;
|
||||
}
|
||||
|
||||
|
@ -1879,9 +1854,9 @@ a.dropdown-link:after {
|
|||
color: #888;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-invitation-tentative td.fc-event-title,
|
||||
.fc-view-table tr.fc-invitation-declined td.fc-event-title,
|
||||
.fc-view-table tr.fc-invitation-needs-action td.fc-event-title {
|
||||
.fc-view-table tr.fc-invitation-tentative td.fc-title,
|
||||
.fc-view-table tr.fc-invitation-declined td.fc-title,
|
||||
.fc-view-table tr.fc-invitation-needs-action td.fc-title {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
@ -1898,7 +1873,8 @@ a.dropdown-link:after {
|
|||
-o-box-shadow: 0 0 2px 3px rgba(71,135,177, 0.6);
|
||||
box-shadow: 0 0 2px 3px rgba(71,135,177, 0.6);
|
||||
}
|
||||
.fc-event-title {
|
||||
|
||||
.fc-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
@ -1908,36 +1884,36 @@ a.dropdown-link:after {
|
|||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.cal-event-status-cancelled .fc-event-title {
|
||||
.cal-event-status-cancelled .fc-title {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.fc-event-hori .fc-event-title {
|
||||
.fc-event-hori .fc-title {
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc-event-hori .fc-event-time {
|
||||
.fc-event-hori .fc-time {
|
||||
white-space: nowrap;
|
||||
font-weight: normal !important;
|
||||
font-size: 10px;
|
||||
padding-right: 0.6em;
|
||||
}
|
||||
|
||||
.fc-grid .fc-event-time {
|
||||
.fc-grid .fc-time {
|
||||
font-weight: normal !important;
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
|
||||
.calendarmain .fc-event-vert .fc-event-inner {
|
||||
.calendarmain .fc-event-vert .fc-inner {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.fc-event-cateories {
|
||||
font-style:italic;
|
||||
.fc-event-categories {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.fc-event-location {
|
||||
.fc-event-location {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
@ -2049,10 +2025,6 @@ div.fc-event-location {
|
|||
width: 25%;
|
||||
}
|
||||
|
||||
.fc-view-table table.fc-list-smart {
|
||||
/* table-layout: auto; */
|
||||
}
|
||||
|
||||
.fc-listappend {
|
||||
text-align: center;
|
||||
margin: 1em 0;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -45,13 +45,14 @@ function rcube_libcalendaring(settings)
|
|||
var client_timezone = new Date().getTimezoneOffset();
|
||||
|
||||
// general datepicker settings
|
||||
var datepicker_settings = {
|
||||
this.datepicker_settings = {
|
||||
// translate from fullcalendar format to datepicker format
|
||||
dateFormat: settings.date_format.replace(/M/g, 'm').replace(/mmmmm/, 'MM').replace(/mmm/, 'M').replace(/dddd/, 'DD').replace(/ddd/, 'D').replace(/yy/g, 'y'),
|
||||
dateFormat: settings.date_format.replace(/M/g, 'm').replace(/mmmmm/, 'MM').replace(/mmm/, 'M').replace(/dddd/, 'DD').replace(/ddd/, 'D').replace(/DD/, 'dd').replace(/Y/g, 'y').replace(/yyyy/g, 'yy'),
|
||||
firstDay : settings.first_day,
|
||||
dayNamesMin: settings.days_short,
|
||||
monthNames: settings.months,
|
||||
monthNamesShort: settings.months,
|
||||
showWeek: settings.show_weekno >= 0,
|
||||
changeMonth: false,
|
||||
showOtherMonths: true,
|
||||
selectOtherMonths: true
|
||||
|
@ -76,19 +77,27 @@ function rcube_libcalendaring(settings)
|
|||
if (!event.end)
|
||||
event.end = event.start;
|
||||
|
||||
var fromto, duration = event.end.getTime() / 1000 - event.start.getTime() / 1000,
|
||||
// Support Moment.js objects
|
||||
var start = 'toDate' in event.start ? event.start.toDate() : event.start,
|
||||
end = 'toDate' in event.end ? event.end.toDate() : event.end;
|
||||
|
||||
var fromto, duration = end.getTime() / 1000 - start.getTime() / 1000,
|
||||
until = voice ? ' ' + rcmail.gettext('until','libcalendaring') + ' ' : ' — ';
|
||||
|
||||
if (event.allDay) {
|
||||
fromto = this.format_datetime(event.start, 1, voice)
|
||||
+ (duration > 86400 || event.start.getDay() != event.end.getDay() ? until + this.format_datetime(event.end, 1, voice) : '');
|
||||
// fullcalendar end dates of all-day events are exclusive
|
||||
end = new Date(end.getTime() - 1000*60*60*24*1);
|
||||
duration = end.getTime() / 1000 - start.getTime() / 1000;
|
||||
fromto = this.format_datetime(start, 1, voice)
|
||||
+ (duration > 86400 || start.getDay() != end.getDay() ? until + this.format_datetime(end, 1, voice) : '');
|
||||
}
|
||||
else if (duration < 86400 && event.start.getDay() == event.end.getDay()) {
|
||||
fromto = this.format_datetime(event.start, 0, voice)
|
||||
+ (duration > 0 ? until + this.format_datetime(event.end, 2, voice) : '');
|
||||
else if (duration < 86400 && start.getDay() == end.getDay()) {
|
||||
fromto = this.format_datetime(start, 0, voice)
|
||||
+ (duration > 0 ? until + this.format_datetime(end, 2, voice) : '');
|
||||
}
|
||||
else {
|
||||
fromto = this.format_datetime(event.start, 0, voice)
|
||||
+ (duration > 0 ? until + this.format_datetime(event.end, 0, voice) : '');
|
||||
fromto = this.format_datetime(start, 0, voice)
|
||||
+ (duration > 0 ? until + this.format_datetime(end, 0, voice) : '');
|
||||
}
|
||||
|
||||
return fromto;
|
||||
|
@ -154,7 +163,7 @@ function rcube_libcalendaring(settings)
|
|||
this.parse_datetime = function(time, date)
|
||||
{
|
||||
// we use the utility function from datepicker to parse dates
|
||||
var date = date ? $.datepicker.parseDate(datepicker_settings.dateFormat, date, datepicker_settings) : new Date();
|
||||
var date = date ? $.datepicker.parseDate(this.datepicker_settings.dateFormat, date, this.datepicker_settings) : new Date();
|
||||
|
||||
var time_arr = time.replace(/\s*[ap][.m]*/i, '').replace(/0([0-9])/g, '$1').split(/[:.]/);
|
||||
if (!isNaN(time_arr[0])) {
|
||||
|
@ -229,6 +238,9 @@ function rcube_libcalendaring(settings)
|
|||
*/
|
||||
this.date2ISO8601 = function(date)
|
||||
{
|
||||
if ('toDate' in date)
|
||||
return date.format('YYYY-MM-DD[T]HH:mm:ss'); // MomentJS
|
||||
|
||||
var zeropad = function(num) { return (num < 10 ? '0' : '') + num; };
|
||||
|
||||
return date.getFullYear() + '-' + zeropad(date.getMonth()+1) + '-' + zeropad(date.getDate())
|
||||
|
@ -242,7 +254,7 @@ function rcube_libcalendaring(settings)
|
|||
{
|
||||
var res = '';
|
||||
if (!mode || mode == 1) {
|
||||
res += $.datepicker.formatDate(voice ? 'MM d yy' : datepicker_settings.dateFormat, date, datepicker_settings);
|
||||
res += $.datepicker.formatDate(voice ? 'MM d yy' : this.datepicker_settings.dateFormat, date, this.datepicker_settings);
|
||||
}
|
||||
if (!mode) {
|
||||
res += voice ? ' ' + rcmail.gettext('at','libcalendaring') + ' ' : ' ';
|
||||
|
@ -299,8 +311,10 @@ function rcube_libcalendaring(settings)
|
|||
*/
|
||||
this.date2unixtime = function(date)
|
||||
{
|
||||
var dst_offset = (client_timezone - date.getTimezoneOffset()) * 60; // adjust DST offset
|
||||
return Math.round(date.getTime()/1000 + gmt_offset * 3600 + dst_offset);
|
||||
var dt = 'toDate' in date ? date.toDate() : date,
|
||||
dst_offset = (client_timezone - dt.getTimezoneOffset()) * 60; // adjust DST offset
|
||||
|
||||
return Math.round(dt.getTime()/1000 + gmt_offset * 3600 + dst_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -396,7 +410,7 @@ function rcube_libcalendaring(settings)
|
|||
parent.find('.edit-alarm-related')[val === '@' ? 'hide' : 'show']();
|
||||
});
|
||||
|
||||
$(prefix+' .edit-alarm-date').removeClass('hasDatepicker').removeAttr('id').datepicker(datepicker_settings);
|
||||
$(prefix+' .edit-alarm-date').removeClass('hasDatepicker').removeAttr('id').datepicker(this.datepicker_settings);
|
||||
|
||||
if (rcmail.env.action != 'print')
|
||||
this.init_time_autocomplete($(prefix+' .edit-alarm-time')[0], {});
|
||||
|
@ -847,9 +861,9 @@ function rcube_libcalendaring(settings)
|
|||
return false;
|
||||
});
|
||||
|
||||
$('#edit-recurrence-enddate').datepicker(datepicker_settings).click(function(){ $("#edit-recurrence-repeat-until").prop('checked', true) });
|
||||
$('#edit-recurrence-enddate').datepicker(this.datepicker_settings).click(function(){ $("#edit-recurrence-repeat-until").prop('checked', true) });
|
||||
$('#edit-recurrence-repeat-times').change(function(e){ $('#edit-recurrence-repeat-count').prop('checked', true); });
|
||||
$('#edit-recurrence-rdate-input').datepicker(datepicker_settings);
|
||||
$('#edit-recurrence-rdate-input').datepicker(this.datepicker_settings);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -857,7 +871,7 @@ function rcube_libcalendaring(settings)
|
|||
*/
|
||||
this.set_recurrence_edit = function(rec)
|
||||
{
|
||||
var recurrence = $('#edit-recurrence-frequency').val(rec.recurrence ? rec.recurrence.FREQ || (rec.recurrence.RDATE ? 'RDATE' : '') : '').change(),
|
||||
var date, recurrence = $('#edit-recurrence-frequency').val(rec.recurrence ? rec.recurrence.FREQ || (rec.recurrence.RDATE ? 'RDATE' : '') : '').change(),
|
||||
interval = $('.recurrence-form select.edit-recurrence-interval').val(rec.recurrence ? rec.recurrence.INTERVAL || 1 : 1),
|
||||
rrtimes = $('#edit-recurrence-repeat-times').val(rec.recurrence ? rec.recurrence.COUNT || 1 : 1),
|
||||
rrenddate = $('#edit-recurrence-enddate').val(rec.recurrence && rec.recurrence.UNTIL ? this.format_datetime(this.parseISO8601(rec.recurrence.UNTIL), 1) : '');
|
||||
|
@ -887,13 +901,15 @@ function rcube_libcalendaring(settings)
|
|||
$('input.edit-recurrence-'+section+'-mode').val(['BYDAY']);
|
||||
}
|
||||
else if (rec.start) {
|
||||
$('#edit-recurrence-monthly-byday').val(weekdays[rec.start.getDay()]);
|
||||
date = 'toDate' in rec.start ? rec.start.toDate() : rec.start;
|
||||
$('#edit-recurrence-monthly-byday').val(weekdays[date.getDay()]);
|
||||
}
|
||||
if (rec.recurrence && rec.recurrence.BYMONTH) {
|
||||
$('input.edit-recurrence-yearly-bymonth').val(String(rec.recurrence.BYMONTH).split(','));
|
||||
}
|
||||
else if (rec.start) {
|
||||
$('input.edit-recurrence-yearly-bymonth').val([String(rec.start.getMonth()+1)]);
|
||||
date = 'toDate' in rec.start ? rec.start.toDate() : rec.start;
|
||||
$('input.edit-recurrence-yearly-bymonth').val([String(date.getMonth()+1)]);
|
||||
}
|
||||
if (rec.recurrence && rec.recurrence.RDATE) {
|
||||
$.each(rec.recurrence.RDATE, function(i,rdate){
|
||||
|
|
|
@ -207,14 +207,16 @@ class libcalendaring extends rcube_plugin
|
|||
$this->date_format_defaults();
|
||||
|
||||
$settings = array();
|
||||
$keys = array('date_format', 'time_format', 'date_short', 'date_long');
|
||||
$keys = array('date_format', 'time_format', 'date_short', 'date_long', 'date_agenda');
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$settings[$key] = (string)$this->rc->config->get('calendar_' . $key, $this->defaults['calendar_' . $key]);
|
||||
$settings[$key] = str_replace('Y', 'y', $settings[$key]);
|
||||
$settings[$key] = str_replace('y', 'Y', $settings[$key]);
|
||||
$settings[$key] = preg_replace('/(?<!d)dd(?!d)/', 'DD', $settings[$key]);
|
||||
$settings[$key] = preg_replace('/(?<!d)d(?!d)/', 'D', $settings[$key]);
|
||||
}
|
||||
|
||||
$settings['dates_long'] = str_replace(' yyyy', '[ yyyy]', $settings['date_long']) . "{ '—' " . $settings['date_long'] . '}';
|
||||
$settings['dates_long'] = $settings['date_long'];// . " - " . $settings['date_long'];
|
||||
$settings['first_day'] = (int)$this->rc->config->get('calendar_first_day', $this->defaults['calendar_first_day']);
|
||||
$settings['timezone'] = $this->timezone_offset;
|
||||
$settings['dst'] = $this->dst_active;
|
||||
|
|
|
@ -87,19 +87,6 @@ function rcube_tasklist_ui(settings)
|
|||
var task_attendees = [];
|
||||
var attendees_list;
|
||||
var me = this;
|
||||
|
||||
// general datepicker settings
|
||||
var datepicker_settings = {
|
||||
// translate from PHP format to datepicker format
|
||||
dateFormat: settings.date_format.replace(/M/g, 'm').replace(/mmmmm/, 'MM').replace(/mmm/, 'M').replace(/dddd/, 'DD').replace(/ddd/, 'D').replace(/yy/g, 'y'),
|
||||
firstDay : settings.first_day,
|
||||
// dayNamesMin: settings.days_short,
|
||||
// monthNames: settings.months,
|
||||
// monthNamesShort: settings.months,
|
||||
changeMonth: false,
|
||||
showOtherMonths: true,
|
||||
selectOtherMonths: true
|
||||
};
|
||||
var extended_datepicker_settings;
|
||||
|
||||
/* public members */
|
||||
|
@ -127,10 +114,6 @@ function rcube_tasklist_ui(settings)
|
|||
/* imports */
|
||||
var Q = this.quote_html;
|
||||
var text2html = this.text2html;
|
||||
var event_date_text = this.event_date_text;
|
||||
var parse_datetime = this.parse_datetime;
|
||||
var date2unixtime = this.date2unixtime;
|
||||
var fromunixtime = this.fromunixtime;
|
||||
var render_message_links = this.render_message_links;
|
||||
|
||||
/**
|
||||
|
@ -639,7 +622,7 @@ function rcube_tasklist_ui(settings)
|
|||
});
|
||||
}, 1);
|
||||
}
|
||||
}, datepicker_settings);
|
||||
}, me.datepicker_settings);
|
||||
|
||||
rcmail.addEventListener('kolab-tags-search', filter_tasks)
|
||||
.addEventListener('kolab-tags-drop-data', function(e) { return listdata[e.id]; })
|
||||
|
@ -743,7 +726,7 @@ function rcube_tasklist_ui(settings)
|
|||
me.init_alarms_edit('#taskedit-alarms');
|
||||
me.init_recurrence_edit('#eventedit');
|
||||
|
||||
$('#taskedit-date, #taskedit-startdate').datepicker(datepicker_settings);
|
||||
$('#taskedit-date, #taskedit-startdate').datepicker(me.datepicker_settings);
|
||||
|
||||
$('a.edit-nodate').click(function(){
|
||||
var sel = $(this).attr('rel');
|
||||
|
@ -2594,8 +2577,8 @@ function rcube_tasklist_ui(settings)
|
|||
return false;
|
||||
}
|
||||
else if (data.startdate && data.date) {
|
||||
var startdate = $.datepicker.parseDate(datepicker_settings.dateFormat, data.startdate, datepicker_settings);
|
||||
var duedate = $.datepicker.parseDate(datepicker_settings.dateFormat, data.date, datepicker_settings);
|
||||
var startdate = $.datepicker.parseDate(me.datepicker_settings.dateFormat, data.startdate, me.datepicker_settings);
|
||||
var duedate = $.datepicker.parseDate(me.datepicker_settings.dateFormat, data.date, me.datepicker_settings);
|
||||
if (startdate > duedate) {
|
||||
rcmail.alert_dialog(rcmail.gettext('invalidstartduedates', 'tasklist'));
|
||||
return false;
|
||||
|
|
Loading…
Add table
Reference in a new issue