refactor recurring event modification (#173)
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
import { api } from "../../utils/apiUtils";
|
||||
import { TIMEZONES } from "../../utils/timezone-data";
|
||||
import { CalendarEvent } from "./EventsTypes";
|
||||
import { calendarEventToJCal, parseCalendarEvent } from "./eventUtils";
|
||||
import {
|
||||
calendarEventToJCal,
|
||||
makeTimezone,
|
||||
makeVevent,
|
||||
parseCalendarEvent,
|
||||
} from "./eventUtils";
|
||||
import ICAL from "ical.js";
|
||||
|
||||
export async function getEvent(event: CalendarEvent) {
|
||||
export async function getEvent(event: CalendarEvent, isMaster?: boolean) {
|
||||
const response = await api.get(`dav${event.URL}`);
|
||||
const eventData = await response.text();
|
||||
const eventical = ICAL.parse(eventData);
|
||||
@@ -13,6 +19,9 @@ export async function getEvent(event: CalendarEvent) {
|
||||
event.calId,
|
||||
event.URL
|
||||
);
|
||||
if (isMaster) {
|
||||
return { ...event, ...eventjson };
|
||||
}
|
||||
return { ...eventjson, ...event };
|
||||
}
|
||||
|
||||
@@ -37,6 +46,107 @@ export async function putEvent(event: CalendarEvent, calOwnerEmail?: string) {
|
||||
return response;
|
||||
}
|
||||
|
||||
export async function putEventWithOverrides(
|
||||
updatedEvent: CalendarEvent,
|
||||
calOwnerEmail?: string
|
||||
) {
|
||||
const vevents = await getAllRecurrentEvent(updatedEvent);
|
||||
|
||||
const updatedVevent = makeVevent(
|
||||
updatedEvent,
|
||||
updatedEvent.timezone,
|
||||
calOwnerEmail,
|
||||
!updatedEvent.recurrenceId
|
||||
);
|
||||
let replaced = false;
|
||||
for (let i = 0; i < vevents.length; i++) {
|
||||
const ve = vevents[i];
|
||||
const recurrenceId = ve[1].find(([k]: string[]) => k === "recurrence-id");
|
||||
if (recurrenceId && recurrenceId[3] === updatedEvent.recurrenceId) {
|
||||
vevents[i] = updatedVevent; // replace
|
||||
replaced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!replaced && updatedEvent.recurrenceId) {
|
||||
vevents.push(updatedVevent); // add new override
|
||||
}
|
||||
|
||||
const timezoneData = TIMEZONES.zones[updatedEvent.timezone];
|
||||
const vtimezone = makeTimezone(timezoneData, updatedEvent);
|
||||
|
||||
const newJCal = ["vcalendar", [], [...vevents, vtimezone.component.jCal]];
|
||||
|
||||
return api(`dav${updatedEvent.URL}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(newJCal),
|
||||
headers: {
|
||||
"content-type": "text/calendar; charset=utf-8",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const deleteEventInstance = async (
|
||||
event: CalendarEvent,
|
||||
calOwnerEmail?: string
|
||||
) => {
|
||||
const seriesEvent = await getEvent(
|
||||
{
|
||||
...event,
|
||||
uid: event.uid.split("/")[0],
|
||||
},
|
||||
true
|
||||
);
|
||||
seriesEvent.exdates = [...(seriesEvent.exdates || []), event.start];
|
||||
delete seriesEvent.recurrenceId;
|
||||
|
||||
return putEvent(seriesEvent, calOwnerEmail);
|
||||
};
|
||||
|
||||
export const updateSeries = async (
|
||||
event: CalendarEvent,
|
||||
calOwnerEmail?: string
|
||||
) => {
|
||||
const vevents = await getAllRecurrentEvent(event);
|
||||
const masterIndex = vevents.findIndex(
|
||||
([, props]: [string, string[]]) =>
|
||||
!props.find(([k]) => k.toLowerCase() === "recurrence-id")
|
||||
);
|
||||
if (masterIndex === -1) {
|
||||
throw new Error("No master VEVENT found for this series");
|
||||
}
|
||||
const rrule = vevents[0][1].find(([k]: string[]) => k === "rrule");
|
||||
|
||||
const tzid = event.timezone;
|
||||
|
||||
const updatedMaster = makeVevent(event, tzid, calOwnerEmail, true);
|
||||
const newRrule = updatedMaster[1].find(([k]: string[]) => k === "rrule");
|
||||
if (!newRrule) {
|
||||
updatedMaster[1].push(rrule);
|
||||
}
|
||||
vevents[masterIndex] = updatedMaster;
|
||||
|
||||
const timezoneData = TIMEZONES.zones[event.timezone];
|
||||
const vtimezone = makeTimezone(timezoneData, event);
|
||||
|
||||
const newJCal = ["vcalendar", [], [...vevents, vtimezone.component.jCal]];
|
||||
return api(`dav${event.URL}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(newJCal),
|
||||
headers: {
|
||||
"content-type": "text/calendar; charset=utf-8",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
async function getAllRecurrentEvent(event: CalendarEvent) {
|
||||
const response = await api.get(`dav${event.URL}`);
|
||||
const eventData = await response.text();
|
||||
const jcal = ICAL.parse(eventData);
|
||||
const vevents = jcal[2].filter(([name]: string[]) => name === "vevent");
|
||||
return vevents;
|
||||
}
|
||||
|
||||
export async function moveEvent(event: CalendarEvent, newUrl: string) {
|
||||
const response = await api(`dav${event.URL}`, {
|
||||
method: "MOVE",
|
||||
|
||||
Reference in New Issue
Block a user