Calendar: Fix events from group invitations did not always show up when viewing calendar of a group member

Fixed by pre-fetching the group members before trying to display events so they're there when we check
This commit is contained in:
nathan 2023-03-23 13:08:52 -06:00
parent 86067045c9
commit 7128736bbd
2 changed files with 98 additions and 28 deletions

View File

@ -57,6 +57,8 @@ import {tapAndSwipe} from "../../api/js/tapandswipe";
import {CalendarOwner} from "./CalendarOwner";
import {et2_IInput} from "../../api/js/etemplate/et2_core_interfaces";
import {Et2DateTime} from "../../api/js/etemplate/Et2Date/Et2DateTime";
import {Et2Select} from "../../api/js/etemplate/Et2Select/Et2Select";
import type {SelectOption} from "../../api/js/etemplate/Et2Select/FindSelectOptions";
/**
* UI for calendar
@ -3743,6 +3745,60 @@ export class CalendarApp extends EgwApp
);
}
/**
* Pre-fetch the members of any group participants
*
* This is done to avoid rewriting since group fetching is async. We fetch missing group members in advance,
* then hold the data in the sidebox select options for immediate access when checking if an event should be displayed
* in a particular calendar.
*
* @param event
* @return Promise
*/
async _fetch_group_members(event) : Promise<any>
{
let groups = [];
let option_owner = null;
let options : SelectOption[];
if(app.calendar && app.calendar.sidebox_et2 && app.calendar.sidebox_et2.getWidgetById('owner'))
{
option_owner = app.calendar.sidebox_et2.getWidgetById('owner');
}
else
{
option_owner = parent.getArrayMgr("sel_options").getRoot().getEntry('owner');
}
options = option_owner.select_options;
for(const id of Object.keys(event.participants))
{
if(parseInt(id) >= 0)
{
continue;
}
let resource = options.find((o) => o.value === id);
if(!resource || resource && !resource.resources)
{
groups.push(parseInt(id));
}
}
// Find missing groups
if(groups.length)
{
return this.egw.request("calendar.calendar_owner_etemplate_widget.ajax_owner", [groups]).then((data) =>
{
options = options.concat(Object.values(data));
option_owner.select_options = options;
});
}
else
{
return Promise.resolve();
}
}
/**
* We have a list of calendar UIDs of events that need updating.
* Public wrapper for _update_events so we can call it from server

View File

@ -370,39 +370,53 @@ export class et2_calendar_daycol extends et2_valueWidget implements et2_IDetache
_data_callback( event_ids)
{
const events = [];
if(event_ids == null || typeof event_ids.length == 'undefined') event_ids = [];
for(let i = 0; i < event_ids.length; i++)
const waitForGroups = [];
if(event_ids == null || typeof event_ids.length == 'undefined')
{
let event : any = egw.dataGetUIDdata('calendar::'+event_ids[i]);
event = event && event.data || false;
if(event && event.date && et2_calendar_event.owner_check(event, this) && (
event.date === this.options.date ||
// Accept multi-day events
new Date(event.start) <= this.date //&& new Date(event.end) >= this.date
))
{
events.push(event);
}
else if (event)
{
// Got an ID that doesn't belong
event_ids.splice(i--,1);
}
event_ids = [];
}
if(!this.div.is(":visible"))
for(let i = 0; i < event_ids.length; i++)
{
// Not visible, defer the layout or it all winds up at the top
// Cancel any existing listener & bind
jQuery(this.getInstanceManager().DOMContainer.parentNode)
.off('show.'+CalendarApp._daywise_cache_id(this.options.date, this.options.owner))
.one('show.'+CalendarApp._daywise_cache_id(this.options.date, this.options.owner), function() {
this._update_events(events)
}.bind(this));
return;
let event : any = egw.dataGetUIDdata('calendar::' + event_ids[i]);
event = event && event.data || false;
waitForGroups.push((<CalendarApp>app.calendar)._fetch_group_members(event).then(() =>
{
if(event && event.date && et2_calendar_event.owner_check(event, this) && (
event.date === this.options.date ||
// Accept multi-day events
new Date(event.start) <= this.date //&& new Date(event.end) >= this.date
))
{
events.push(event);
}
else if(event)
{
// Got an ID that doesn't belong
event_ids.splice(i--, 1);
}
}));
}
if(!this.getParent().disabled)
this._update_events(events);
Promise.all(waitForGroups).then(() =>
{
if(!this.div.is(":visible"))
{
// Not visible, defer the layout or it all winds up at the top
// Cancel any existing listener & bind
jQuery(this.getInstanceManager().DOMContainer.parentNode)
.off('show.' + CalendarApp._daywise_cache_id(this.options.date, this.options.owner))
.one('show.' + CalendarApp._daywise_cache_id(this.options.date, this.options.owner), function()
{
this._update_events(events)
}.bind(this));
return;
}
if(!this.getParent().disabled)
{
this._update_events(events);
}
});
}
set_label( label)