From 21c4b6a5bb3908bc48e88e6c7599cd49ff82fd53 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 16 Mar 2018 09:22:42 +0100 Subject: [PATCH] Elastic: Partial support for calendar plugin --- plugins/calendar/calendar.php | 11 +- plugins/calendar/calendar_ui.js | 487 +++++------ plugins/calendar/composer.json | 2 +- .../calendar/drivers/kolab/kolab_driver.php | 71 +- plugins/calendar/lib/calendar_ui.php | 81 +- plugins/calendar/localization/en_US.inc | 1 + plugins/calendar/skins/larry/calendar.css | 22 +- .../calendar/skins/larry/print.iehacks.css | 25 - .../skins/larry/templates/calendar.html | 6 +- .../skins/larry/templates/kolabacl.html | 26 - .../calendar/skins/larry/templates/print.html | 1 - plugins/libkolab/js/audittrail.js | 2 +- .../skins/elastic/include/calendar.less | 797 ++++++++++++++++++ .../skins/elastic/include/libcalendaring.less | 70 ++ .../skins/elastic/include/tasklist.less | 11 + plugins/libkolab/skins/elastic/libkolab.less | 36 +- 16 files changed, 1221 insertions(+), 428 deletions(-) delete mode 100644 plugins/calendar/skins/larry/print.iehacks.css delete mode 100644 plugins/calendar/skins/larry/templates/kolabacl.html diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 9b342c54..cbf8b0ee 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -320,7 +320,11 @@ class calendar extends rcube_plugin $this->rc->output->set_env('timezone', $this->timezone->getName()); $this->rc->output->set_env('calendar_driver', $this->rc->config->get('calendar_driver'), false); $this->rc->output->set_env('calendar_resources', (bool)$this->rc->config->get('calendar_resources_driver')); - $this->rc->output->set_env('identities-selector', $this->ui->identity_select(array('id' => 'edit-identities-list', 'aria-label' => $this->gettext('roleorganizer')))); + $this->rc->output->set_env('identities-selector', $this->ui->identity_select(array( + 'id' => 'edit-identities-list', + 'aria-label' => $this->gettext('roleorganizer'), + 'class' => 'form-control', + ))); $view = rcube_utils::get_input_value('view', rcube_utils::INPUT_GPC); if (in_array($view, array('agendaWeek', 'agendaDay', 'month', 'table'))) @@ -2665,8 +2669,8 @@ class calendar extends rcube_plugin // render small agenda view for the respective day if ($data['method'] == 'REQUEST' && !empty($data['date']) && $response['action'] == 'rsvp') { $event_start = rcube_utils::anytodatetime($data['date']); - $day_start = new Datetime(gmdate('Y-m-d 00:00', $data['date']), $this->lib->timezone); - $day_end = new Datetime(gmdate('Y-m-d 23:59', $data['date']), $this->lib->timezone); + $day_start = new Datetime(gmdate('Y-m-d 00:00', $data['date']), $this->lib->timezone); + $day_end = new Datetime(gmdate('Y-m-d 23:59', $data['date']), $this->lib->timezone); // get events on that day from the user's personal calendars $calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL); @@ -2675,6 +2679,7 @@ class calendar extends rcube_plugin $before = $after = array(); foreach ($events as $event) { + // TODO: skip events with free_busy == 'free' ? if ($event['uid'] == $data['uid'] || $event['end'] < $day_start || $event['start'] > $day_end) continue; diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index 5b3f596f..fd431f3e 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -66,7 +66,7 @@ function rcube_calendar_ui(settings) var freebusy_data = {}; var current_view = null; var count_sources = []; - var exec_deferred = bw.ie6 ? 5 : 1; + var exec_deferred = 1; 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'); @@ -548,6 +548,7 @@ function rcube_calendar_ui(settings) if (!temp && calendar.editable && event.editable !== false) { buttons.push({ text: rcmail.gettext('edit', 'calendar'), + 'class': 'edit mainaction', click: function() { event_edit_dialog('edit', event); } @@ -567,7 +568,8 @@ function rcube_calendar_ui(settings) if (!buttons.length) { buttons.push({ text: rcmail.gettext('close', 'calendar'), - click: function(){ + 'class': 'cancel', + click: function() { $dialog.dialog('close'); } }); @@ -575,9 +577,9 @@ function rcube_calendar_ui(settings) // open jquery UI dialog $dialog.dialog({ - modal: false, - resizable: !bw.ie6, - closeOnEscape: (!bw.ie6 && !bw.ie7), // disable for performance reasons + modal: true, + resizable: true, + closeOnEscape: true, title: me.event_date_text(event), open: function() { $dialog.attr('aria-hidden', 'false'); @@ -585,17 +587,19 @@ function rcube_calendar_ui(settings) $dialog.parent().find('.ui-button:not(.ui-dialog-titlebar-close)').first().focus(); }, 5); }, - close: function() { + beforeClose: function(e) { + rcmail.command('menu-close', 'eventoptionsmenu', null, e); + }, + close: function(e) { $dialog.dialog('destroy').attr('aria-hidden', 'true').hide(); - rcmail.command('menu-close','eventoptionsmenu'); $('.libcal-rsvp-replymode').hide(); }, - dragStart: function() { - rcmail.command('menu-close','eventoptionsmenu'); + dragStart: function(e) { + rcmail.command('menu-close', 'eventoptionsmenu', null, e); $('.libcal-rsvp-replymode').hide(); }, - resizeStart: function() { - rcmail.command('menu-close','eventoptionsmenu'); + resizeStart: function(e) { + rcmail.command('menu-close', 'eventoptionsmenu', null, e); $('.libcal-rsvp-replymode').hide(); }, buttons: buttons, @@ -616,9 +620,8 @@ function rcube_calendar_ui(settings) // add link for "more options" drop-down if (!temp && !event.temporary && event.calendar != '_resource') { $('') - .attr('href', '#') - .html(rcmail.gettext('eventoptions','calendar')) - .addClass('dropdown-link') + .attr({href: '#', 'class': 'dropdown-link btn btn-link options', 'data-popup-pos': 'top'}) + .text(rcmail.gettext('eventoptions','calendar')) .click(function(e) { return rcmail.command('menu-open','eventoptionsmenu', this, e) }) @@ -818,7 +821,7 @@ function rcube_calendar_ui(settings) // save action buttons.push({ text: rcmail.gettext('save', 'calendar'), - 'class': 'mainaction', + 'class': 'save mainaction', click: 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()); @@ -919,6 +922,7 @@ function rcube_calendar_ui(settings) buttons.push({ text: rcmail.gettext('cancel', 'calendar'), + 'class': 'cancel', click: function() { $dialog.dialog("close"); } @@ -941,7 +945,7 @@ function rcube_calendar_ui(settings) // open jquery UI dialog $dialog.dialog({ modal: true, - resizable: (!bw.ie6 && !bw.ie7), // disable for performance reasons + resizable: true, closeOnEscape: false, title: rcmail.gettext((action == 'edit' ? 'edit_event' : 'new_event'), 'calendar'), open: function() { @@ -1129,10 +1133,11 @@ function rcube_calendar_ui(settings) $('.event-date', $dialog).hide(); }); - var buttons = {}; - buttons[rcmail.gettext('close', 'calendar')] = function() { - $dialog.dialog('close'); - }; + var buttons = [{ + text: rcmail.gettext('close', 'calendar'), + 'class': 'cancel', + click: function() { $dialog.dialog('close'); } + }]; // open jquery UI dialog $dialog.dialog({ @@ -1265,47 +1270,50 @@ function rcube_calendar_ui(settings) }); // enable/disable buttons - $('#shedule-find-prev').button('option', 'disabled', (fb_start.getTime() < now.getTime())); + $('#schedule-find-prev').button('option', 'disabled', (fb_start.getTime() < now.getTime())); // dialog buttons - var buttons = {}; - - buttons[rcmail.gettext('select', 'calendar')] = function() { - $('#edit-startdate').val(freebusy_ui.startdate.val()); - $('#edit-starttime').val(freebusy_ui.starttime.val()); - $('#edit-enddate').val(freebusy_ui.enddate.val()); - $('#edit-endtime').val(freebusy_ui.endtime.val()); - - // write role changes back to main dialog - $('select.edit-attendee-role').each(function(i, elem){ - if (event_attendees[i] && freebusy_ui.attendees[i]) { - event_attendees[i].role = freebusy_ui.attendees[i].role; - $(elem).val(event_attendees[i].role); + var buttons = [ + { + text: rcmail.gettext('select', 'calendar'), + 'class': 'save mainaction', + click: function() { + $('#edit-startdate').val(freebusy_ui.startdate.val()); + $('#edit-starttime').val(freebusy_ui.starttime.val()); + $('#edit-enddate').val(freebusy_ui.enddate.val()); + $('#edit-endtime').val(freebusy_ui.endtime.val()); + + // write role changes back to main dialog + $('select.edit-attendee-role').each(function(i, elem){ + if (event_attendees[i] && freebusy_ui.attendees[i]) { + event_attendees[i].role = freebusy_ui.attendees[i].role; + $(elem).val(event_attendees[i].role); + } + }); + + if (freebusy_ui.needsupdate) + update_freebusy_status(me.selected_event); + freebusy_ui.needsupdate = false; + $dialog.dialog("close"); } - }); - - if (freebusy_ui.needsupdate) - update_freebusy_status(me.selected_event); - freebusy_ui.needsupdate = false; - $dialog.dialog("close"); - }; - - buttons[rcmail.gettext('cancel', 'calendar')] = function() { - $dialog.dialog("close"); - }; - + }, + { + text: rcmail.gettext('cancel', 'calendar'), + 'class': 'cancel', + click: function() { $dialog.dialog("close"); } + } + ]; + $dialog.dialog({ modal: true, resizable: true, - closeOnEscape: (!bw.ie6 && !bw.ie7), + closeOnEscape: true, title: rcmail.gettext('scheduletime', 'calendar'), open: function() { rcmail.ksearch_blur(); - $dialog.attr('aria-hidden', 'false').find('#shedule-find-next, #shedule-find-prev').not(':disabled').first().focus(); + $dialog.attr('aria-hidden', 'false').find('#schedule-find-next, #schedule-find-prev').not(':disabled').first().focus(); }, close: function() { - if (bw.ie6) - $("#edit-attendees-table").css('visibility','visible'); $dialog.dialog("destroy").attr('aria-hidden', 'true').hide(); // TODO: focus opener button }, @@ -1317,10 +1325,6 @@ function rcube_calendar_ui(settings) width: 850 }).show(); - // hide edit dialog on IE6 because of drop-down elements - if (bw.ie6) - $("#edit-attendees-table").css('visibility','hidden'); - // adjust dialog size to fit grid without scrolling var gridw = $('#schedule-freebusy-times').width(); var overflow = gridw - $('#attendees-freebusy-table td.times').width(); @@ -1804,7 +1808,7 @@ function rcube_calendar_ui(settings) render_freebusy_overlay(); var now = new Date(); - $('#shedule-find-prev').button('option', 'disabled', (event.start.getTime() < now.getTime())); + $('#schedule-find-prev').button('option', 'disabled', (event.start.getTime() < now.getTime())); // speak new selection rcmail.display_message(rcmail.gettext('suggestedslot', 'calendar') + ': ' + me.event_date_text(event, true), 'voice'); @@ -1895,15 +1899,14 @@ function rcube_calendar_ui(settings) opts['CHAIR'] = rcmail.gettext('calendar.rolechair'); if (organizer && !readonly) - dispname = rcmail.env['identities-selector']; - - var select = ''; for (var r in opts) select += ''; select += ''; - - // availability - var avail = data.email ? 'loading' : 'unknown'; // delete icon var icon = rcmail.env.deleteicon ? '' : rcmail.gettext('delete'); @@ -1919,6 +1922,8 @@ function rcube_calendar_ui(settings) tooltip = rcmail.gettext('libcalendaring.delegatedto') + ' ' + data['delegated-to']; else if (data['delegated-from']) tooltip = rcmail.gettext('libcalendaring.delegatedfrom') + ' ' + data['delegated-from']; + else if (!status && organizer) + tooltip = rcmail.gettext('statusorganizer', 'libcalendaring'); else if (status) tooltip = status_label; @@ -1928,15 +1933,18 @@ function rcube_calendar_ui(settings) rcmail.gettext('expandattendeegroup','libcalendaring') + ''; } + var avail = data.email ? 'loading' : 'unknown'; + var table = rcmail.env.calendar_resources && data.cutype == 'RESOURCE' ? resources_list : attendees_list; var img_src = rcmail.assets_path('program/resources/blank.gif'); + var elastic = $(table).parents('.no-img').length > 0; + var avail_tag = elastic ? ('' + '' + dispname + '' + - '' + - '' + Q(status ? status_label : '') + '' + + '' + avail_tag + ' data-email="' + data.email + '" />' + + '' + Q(status && !elastic ? status_label : '') + '' + (data.cutype != 'RESOURCE' ? '' + (organizer || readonly || !invbox ? '' : invbox) + '' : '') + '' + (organizer || readonly ? '' : dellink) + ''; - var table = rcmail.env.calendar_resources && data.cutype == 'RESOURCE' ? resources_list : attendees_list; var tr = $('') .addClass(String(data.role).toLowerCase()) .html(html); @@ -1960,7 +1968,7 @@ function rcube_calendar_ui(settings) // check free-busy status if (avail == 'loading') { - check_freebusy_status(tr.find('img.availabilityicon'), data.email, me.selected_event); + check_freebusy_status(tr.find('.availability > *:first'), data.email, me.selected_event); } event_attendees.push(data); @@ -1970,7 +1978,7 @@ function rcube_calendar_ui(settings) // iterate over all attendees and update their free-busy status display var update_freebusy_status = function(event) { - attendees_list.find('img.availabilityicon').each(function(i,v) { + attendees_list.find('.availability > *').each(function(i,v) { var email, icon = $(this); if (email = icon.attr('data-email')) check_freebusy_status(icon, email, event); @@ -1997,10 +2005,10 @@ function rcube_calendar_ui(settings) data: { email:email, start:date2servertime(clone_date(event.start, event.allDay?1:0)), end:date2servertime(clone_date(event.end, event.allDay?2:0)), _remote: 1 }, success: function(status){ var avail = String(status).toLowerCase(); - icon.removeClass('loading').addClass(avail).attr('alt', rcmail.gettext('avail' + avail, 'calendar')); + icon.removeClass('loading').addClass(avail).attr('title', rcmail.gettext('avail' + avail, 'calendar')); }, error: function(){ - icon.removeClass('loading').addClass('unknown').attr('alt', rcmail.gettext('availunknown', 'calendar')); + icon.removeClass('loading').addClass('unknown').attr('title', rcmail.gettext('availunknown', 'calendar')); } }); }; @@ -2019,17 +2027,20 @@ function rcube_calendar_ui(settings) if ($dialog.is(':ui-dialog')) $dialog.dialog('close'); - + // dialog buttons - var buttons = {}; - - buttons[rcmail.gettext('addresource', 'calendar')] = function() { - rcmail.command('add-resource'); - }; - - buttons[rcmail.gettext('close')] = function() { - $dialog.dialog("close"); - }; + var buttons = [ + { + text: rcmail.gettext('addresource', 'calendar'), + 'class': 'mainaction create', + click: function() { rcmail.command('add-resource'); } + }, + { + text: rcmail.gettext('close'), + 'class': 'cancel', + click: function() { $dialog.dialog("close"); } + } + ]; // open jquery UI dialog $dialog.dialog({ @@ -2597,6 +2608,7 @@ function rcube_calendar_ui(settings) if (!event.recurrence) { buttons.push({ text: rcmail.gettext((action == 'remove' ? 'delete' : 'save'), 'calendar'), + 'class': action == 'remove' ? 'delete mainaction' : 'save mainaction', click: function() { data._notify = notify && $dialog.find('input.confirm-attendees-donotify:checked').length ? 1 : 0; data._decline = decline && $dialog.find('input.confirm-attendees-decline:checked').length ? 1 : 0; @@ -2608,6 +2620,7 @@ function rcube_calendar_ui(settings) buttons.push({ text: rcmail.gettext('cancel', 'calendar'), + 'class': 'cancel', click: function() { $(this).dialog("close"); } @@ -2699,6 +2712,11 @@ function rcube_calendar_ui(settings) width: 680, height: h, title: $.fullCalendar.formatDate(date, 'dddd ' + settings['date_long']), + buttons: [{ + text: rcmail.gettext('cancel', 'calendar'), + 'class': 'cancel', + click: function() { $(this).dialog("close"); } + }], close: function(){ dialog.dialog("destroy"); me.fisheye_date = null; @@ -2858,88 +2876,60 @@ function rcube_calendar_ui(settings) // show confirm dialog for recurring events, use jquery UI dialog return update_event_confirm('remove', event, { id:event.id, calendar:event.calendar, attendees:event.attendees }); }; - + // opens a jquery UI dialog with event properties (or empty for creating a new calendar) this.calendar_edit_dialog = function(calendar) { - // close show dialog first - var $dialog = $("#calendarform"); - if ($dialog.is(':ui-dialog')) - $dialog.dialog('close'); - if (!calendar) calendar = { name:'', color:'cc0000', editable:true, showalarms:true }; - - var form, name, color, alarms; - - $dialog.html(rcmail.get_label('loading')); - $.ajax({ - type: 'GET', - dataType: 'html', - url: rcmail.url('calendar'), - data: { action:(calendar.id ? 'form-edit' : 'form-new'), c:{ id:calendar.id } }, - success: function(data) { - $dialog.html(data); - // resize and reposition dialog window - form = $('#calendarpropform'); - me.dialog_resize('#calendarform', form.height(), form.width()); - name = $('#calendar-name').prop('disabled', !calendar.editable).val(calendar.editname || calendar.name); - color = $('#calendar-color').val(calendar.color).minicolors($.extend(rcmail.env.minicolors_config || {}, {value: calendar.color})); - alarms = $('#calendar-showalarms').prop('checked', calendar.showalarms).get(0); - name.select(); - } + + var title = rcmail.gettext((calendar.id ? 'editcalendar' : 'createcalendar'), 'calendar'), + params = {action: calendar.id ? 'form-edit' : 'form-new', c: {id: calendar.id}, _framed: 1}, + $dialog = $('