diff --git a/calendar/inc/class.calendar_ui.inc.php b/calendar/inc/class.calendar_ui.inc.php index 50576ea5fd..3c5ee71bd9 100644 --- a/calendar/inc/class.calendar_ui.inc.php +++ b/calendar/inc/class.calendar_ui.inc.php @@ -11,10 +11,10 @@ */ use EGroupware\Api; -use EGroupware\Api\Framework; -use EGroupware\Api\Egw; use EGroupware\Api\Acl; +use EGroupware\Api\Egw; use EGroupware\Api\Etemplate; +use EGroupware\Api\Framework; /** * Shared base-class of all calendar UserInterface classes @@ -667,7 +667,12 @@ class calendar_ui if(!$event || !$filter_match) { // Sending null will trigger a removal - $response->generic('data', array('uid' => 'calendar::'.$event_id, 'data' => null)); + $uid = 'calendar::' . $event_id; + if ($recurrence_date) + { + $uid .= ':' . $recurrence_date->getTimestamp(); + } + $response->generic('data', array('uid' => $uid, 'data' => null)); return false; } diff --git a/calendar/js/et2_widget_event.js b/calendar/js/et2_widget_event.js index e3ec118261..5e93143a0a 100644 --- a/calendar/js/et2_widget_event.js +++ b/calendar/js/et2_widget_event.js @@ -205,7 +205,7 @@ var et2_calendar_event = (function(){ "use strict"; return et2_valueWidget.exten } // Check for changing days in the grid view - if(!this._sameday_check(value)) + if(!this._sameday_check(value) || !this._status_check(value, app.calendar.getState().status_filter, parent.options.owner))) { // May need to update parent to remove out-of-view events parent.removeChild(this); @@ -835,6 +835,105 @@ var et2_calendar_event = (function(){ "use strict"; return et2_valueWidget.exten return false; }, + /** + * Check that the event passes the given status filter. + * Status filter is set in the sidebox and used when fetching several events, but if user changes their status + * for an event, it may no longer match and have to be removed. + * + * @param event + * @param filter + * @private + */ + _status_check: function(event, filter, owner) + { + if(!owner || !event) + { + return false; + } + + // If we're doing a bunch, just one passing is enough + if(typeof owner !== "string") + { + let pass = false; + for (let j = 0; j < owner.length && pass == false; j++) + { + pass = pass || this._status_check(event, filter, owner[j]); + } + return pass; + } + + // Show also events just owned by selected user + if(filter == 'owner') + { + return owner == event.owner; + } + + // Get the relevant participant + let participant = event.participants[owner]; + + // If filter says don't look in groups, skip it all + if(!participant && filter === 'no-enum-groups') + { + return false; + } + + // Couldn't find the current owner in the participant list, check groups & resources + if(!participant) + { + let options: any = null; + if(app.calendar && app.calendar.sidebox_et2 && app.calendar.sidebox_et2.getWidgetById('owner')) + { + options = app.calendar.sidebox_et2.getWidgetById('owner').taglist.getSelection(); + } + if((isNaN(parseInt(owner)) || parseInt(owner) < 0) && options && typeof options.find == "function") + { + let resource = options.find(function (element) + { + return element.id == owner; + }) || {}; + if(resource && resource.resources) + { + let matching_participant = resource.resources.filter(id => typeof event.participants[id] != "undefined"); + return this._status_check(event, filter, matching_participant); + } + } + } + + let status = et2_calendar_event.split_status(participant); + + switch (filter) + { + default: + case 'all': + return true; + case 'default': // Show all status, but rejected + return status !== 'R'; + case 'accepted': //Show only accepted events + return status === 'A' + case 'unknown': // Show only invitations, not yet accepted or rejected + return status === 'U'; + case 'tentative': // Show only tentative accepted events + return status === 'T'; + case 'delegated': // Show only delegated events + return status === 'D'; + case 'rejected': // Show only rejected events + return status === 'R'; + // Handled above + //case 'owner': // Show also events just owned by selected user + case 'hideprivate': // Show all events, as if they were private + // handled server-side + return true; + case 'showonlypublic': // Show only events flagged as public, -not checked as private + return event.public == '1'; + // Handled above + // case 'no-enum-groups': // Do not include events of group members + case 'not-unknown': // Show all status, but unknown + return status !== 'U'; + case 'deleted': // Show events that have been deleted + return event.deleted; + } + }, + attachToDOM: function() { this._super.apply(this, arguments);