feat: fetch using a start/end window rather than everything, use eventSources from FC.js
This commit is contained in:
parent
dca9888373
commit
4b2426960b
2 changed files with 41 additions and 46 deletions
|
@ -10,7 +10,7 @@
|
||||||
import frLocale from '@fullcalendar/core/locales/fr';
|
import frLocale from '@fullcalendar/core/locales/fr';
|
||||||
import EventModal from './EventModal.svelte';
|
import EventModal from './EventModal.svelte';
|
||||||
import FilterBar from './FilterBar.svelte';
|
import FilterBar from './FilterBar.svelte';
|
||||||
import { refreshEvents, calendarTree } from './calendar';
|
import { mkSource, calendarTree } from './calendar';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.css';
|
import 'bootstrap/dist/css/bootstrap.css';
|
||||||
|
@ -57,35 +57,19 @@
|
||||||
month: mobile ? 'numeric' : 'long',
|
month: mobile ? 'numeric' : 'long',
|
||||||
day: 'numeric'
|
day: 'numeric'
|
||||||
},
|
},
|
||||||
events: [],
|
eventSources: [],
|
||||||
themeSystem: 'bootstrap5'
|
themeSystem: 'bootstrap5'
|
||||||
});
|
});
|
||||||
|
|
||||||
let selectedCalendars;
|
let selectedCalendars = [];
|
||||||
let updateTimer;
|
|
||||||
|
|
||||||
async function reloadEvents(selectedCalendars) {
|
|
||||||
const evts = await refreshEvents(selectedCalendars);
|
|
||||||
return evts.flat();
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateEvents = debounce(calendars => {
|
const updateEvents = debounce(calendars => {
|
||||||
return reloadEvents(calendars).then(events => {
|
|
||||||
options.update(opts => ({
|
options.update(opts => ({
|
||||||
...opts,
|
...opts,
|
||||||
events
|
eventSources: selectedCalendars.map(mkSource).filter(x => !!x)
|
||||||
}));
|
}));
|
||||||
});
|
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
onMount(async () => {
|
|
||||||
const events = await reloadEvents(selectedCalendars);
|
|
||||||
options.update(opts => ({
|
|
||||||
...opts,
|
|
||||||
events
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
$: updateEvents(selectedCalendars);
|
$: updateEvents(selectedCalendars);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import ICAL from 'ical.js'
|
|
||||||
|
|
||||||
const clouds = {
|
const clouds = {
|
||||||
KLUB_RESEAU: 'klub-reseau',
|
KLUB_RESEAU: 'klub-reseau',
|
||||||
ELEVES_ENS: 'eleves-ens'
|
ELEVES_ENS: 'eleves-ens'
|
||||||
|
@ -29,6 +27,10 @@ const calendars = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calendarsByName = Object.fromEntries(
|
||||||
|
Object.entries(calendars).map(([id, {name}]) => ([name, id]))
|
||||||
|
);
|
||||||
|
|
||||||
export const calendarTree = {
|
export const calendarTree = {
|
||||||
'Clubs COF': {
|
'Clubs COF': {
|
||||||
'Club réseau': {},
|
'Club réseau': {},
|
||||||
|
@ -47,12 +49,17 @@ export const calendarTree = {
|
||||||
|
|
||||||
const calendarIds = Object.keys(calendars)
|
const calendarIds = Object.keys(calendars)
|
||||||
|
|
||||||
function mkCalendarUrl(id, { cloud }) {
|
function mkCalendarUrl(id, { cloud }, extra={}) {
|
||||||
return `/cal/${cloud}/${id}/?export&accept=jcal`
|
return `/cal/${cloud}/${id}/?` + new URLSearchParams({
|
||||||
|
...extra,
|
||||||
|
export: true,
|
||||||
|
expand: true,
|
||||||
|
accept: 'jcal'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchCalendar(id, cal) {
|
function fetchCalendar(id, cal, extra={}) {
|
||||||
return fetch(mkCalendarUrl(id, cal), { credentials: 'omit' })
|
return fetch(mkCalendarUrl(id, cal, extra), { credentials: 'omit' })
|
||||||
.then(resp => resp.json())
|
.then(resp => resp.json())
|
||||||
.catch(err => console.error(err))
|
.catch(err => console.error(err))
|
||||||
}
|
}
|
||||||
|
@ -125,25 +132,29 @@ function mkEventsFromCalendar(id, cal) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mkEvent(title, start, duration, ...rest) {
|
export function mkSource(name) {
|
||||||
start = new Date(start)
|
const calendarId = calendarsByName[name];
|
||||||
const end = new Date(start)
|
if (!calendarId) return null;
|
||||||
end.setMinutes(start.getMinutes() + duration)
|
const calendar = calendars[calendarId];
|
||||||
return {
|
|
||||||
title,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
...rest
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: move to FullCalendar custom fetcher to control start&end.
|
return {
|
||||||
export function refreshEvents(selectedCalendars) {
|
id: name,
|
||||||
return Promise.all(
|
...(calendar?.meta || {}),
|
||||||
calendarIds
|
success: calendarData => {
|
||||||
.filter(id =>
|
if (calendarData[0] !== 'vcalendar') return;
|
||||||
selectedCalendars ? selectedCalendars.includes(calendars[id].name) : true
|
const cal = new Calendar(calendarId, calendarData);
|
||||||
)
|
return cal.events.map(fcEventFromjCalEvent(cal));
|
||||||
.map(id => mkEventsFromCalendar(id, calendars[id]))
|
},
|
||||||
)
|
failure: error => {
|
||||||
|
console.error(`Fatal error during event source fetching of '${name}': ${error}`);
|
||||||
|
},
|
||||||
|
events: (info, successCallback, failureCallback) => {
|
||||||
|
const { start, end } = info;
|
||||||
|
fetchCalendar(calendarId, calendar, {
|
||||||
|
start: start.valueOf() / 1000,
|
||||||
|
end: end.valueOf() / 1000
|
||||||
|
})
|
||||||
|
.then(successCallback, failureCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue