[#4] event url is now stored and reused when updating event to prevent duplication

This commit is contained in:
Camille Moussu
2025-08-25 09:47:43 +02:00
parent 4e31b2666c
commit 684fd82027
5 changed files with 39 additions and 33 deletions
@@ -26,9 +26,9 @@ export default function CalendarSelection({
return ( return (
<div> <div>
<p className="calendarListHeader"> <span className="calendarListHeader">
<h3>Personnal Calendars</h3> <h3>Personnal Calendars</h3>
</p> </span>
{personnalCalendars.map((id) => { {personnalCalendars.map((id) => {
return ( return (
<div key={id}> <div key={id}>
@@ -46,9 +46,9 @@ export default function CalendarSelection({
})} })}
{delegatedCalendars.length > 0 && ( {delegatedCalendars.length > 0 && (
<> <>
<p className="calendarListHeader"> <span className="calendarListHeader">
<h3>Delegated Calendars</h3> <h3>Delegated Calendars</h3>
</p> </span>
{delegatedCalendars.map((id) => ( {delegatedCalendars.map((id) => (
<div key={id}> <div key={id}>
<label> <label>
@@ -66,9 +66,9 @@ export default function CalendarSelection({
)} )}
{sharedCalendars.length > 0 && ( {sharedCalendars.length > 0 && (
<> <>
<p className="calendarListHeader"> <span className="calendarListHeader">
<h3>Shared Calendars</h3> <h3>Shared Calendars</h3>
</p> </span>
{sharedCalendars.map((id) => ( {sharedCalendars.map((id) => (
<div key={id}> <div key={id}>
<label> <label>
+13 -6
View File
@@ -54,8 +54,9 @@ export const getCalendarDetailAsync = createAsyncThunk<
const events: CalendarEvent[] = calendar._embedded["dav:item"].flatMap( const events: CalendarEvent[] = calendar._embedded["dav:item"].flatMap(
(eventdata: any) => { (eventdata: any) => {
const vevents = eventdata.data[2] as any[][]; // array of ['vevent', RawEntry[], []] const vevents = eventdata.data[2] as any[][]; // array of ['vevent', RawEntry[], []]
const eventURL = eventdata._links.self.href;
return vevents.map((vevent: any[]) => { return vevents.map((vevent: any[]) => {
return parseCalendarEvent(vevent[1], color, calId); return parseCalendarEvent(vevent[1], color, calId, eventURL);
}); });
} }
); );
@@ -67,7 +68,7 @@ export const putEventAsync = createAsyncThunk<
{ calId: string; events: CalendarEvent[] }, // Return type { calId: string; events: CalendarEvent[] }, // Return type
{ cal: Calendars; newEvent: CalendarEvent } // Arg type { cal: Calendars; newEvent: CalendarEvent } // Arg type
>("calendars/putEvent", async ({ cal, newEvent }) => { >("calendars/putEvent", async ({ cal, newEvent }) => {
const response = await putEvent(cal, newEvent); const response = await putEvent(newEvent);
const calEvents = (await getCalendar(cal.id, { const calEvents = (await getCalendar(cal.id, {
start: formatDateToYYYYMMDDTHHMMSS(new Date(newEvent.start)), start: formatDateToYYYYMMDDTHHMMSS(new Date(newEvent.start)),
end: formatDateToYYYYMMDDTHHMMSS( end: formatDateToYYYYMMDDTHHMMSS(
@@ -77,8 +78,9 @@ export const putEventAsync = createAsyncThunk<
const events: CalendarEvent[] = calEvents._embedded["dav:item"].flatMap( const events: CalendarEvent[] = calEvents._embedded["dav:item"].flatMap(
(eventdata: any) => { (eventdata: any) => {
const vevents = eventdata.data[2] as any[][]; const vevents = eventdata.data[2] as any[][];
const eventURL = eventdata._links.self.href;
return vevents.map((vevent: any[]) => { return vevents.map((vevent: any[]) => {
return parseCalendarEvent(vevent[1], cal.color ?? "", cal.id); return parseCalendarEvent(vevent[1], cal.color ?? "", cal.id, eventURL);
}); });
} }
); );
@@ -91,9 +93,9 @@ export const putEventAsync = createAsyncThunk<
export const deleteEventAsync = createAsyncThunk< export const deleteEventAsync = createAsyncThunk<
{ calId: string; eventId: string }, // Return type { calId: string; eventId: string }, // Return type
{ calId: string; eventId: string } // Arg type { calId: string; eventId: string; eventURL: string } // Arg type
>("calendars/delEvent", async ({ calId, eventId }) => { >("calendars/delEvent", async ({ calId, eventId, eventURL }) => {
const response = await deleteEvent(calId, eventId); const response = await deleteEvent(eventURL);
return { calId, eventId }; return { calId, eventId };
}); });
@@ -118,6 +120,11 @@ const CalendarSlice = createSlice({
} }
state.list[action.payload.calendarUid].events[action.payload.event.uid] = state.list[action.payload.calendarUid].events[action.payload.event.uid] =
action.payload.event; action.payload.event;
state.list[action.payload.calendarUid].events[
action.payload.event.uid
].URL = `dav/calendars/${action.payload.calendarUid}/${
action.payload.event.uid.split("/")[0]
}.isc`;
}, },
removeEvent: ( removeEvent: (
state, state,
+16 -20
View File
@@ -1,28 +1,24 @@
import { api } from "../../utils/apiUtils"; import { api } from "../../utils/apiUtils";
import { Calendars } from "../Calendars/CalendarTypes";
import { CalendarEvent } from "./EventsTypes"; import { CalendarEvent } from "./EventsTypes";
import { calendarEventToJCal } from "./eventUtils"; import { calendarEventToJCal } from "./eventUtils";
export async function putEvent(cal: Calendars, event: CalendarEvent) { export async function putEvent(event: CalendarEvent) {
const response = await api( const response = await api(`dav${event.URL}`, {
`dav/calendars/${cal.id}/${event.uid.split("/")[0]}.isc`, method: "PUT",
{ body: JSON.stringify(calendarEventToJCal(event)),
method: "PUT", headers: {
body: JSON.stringify(calendarEventToJCal(event)), "content-type": "text/calendar; charset=utf-8",
headers: { },
"content-type": "text/calendar; charset=utf-8", });
}, if (response.status === 201) {
} console.log("PUT :", response.url);
).json(); }
return response; return await response.json();
} }
export async function deleteEvent(calId: string, eventId: string) { export async function deleteEvent(eventURL: string) {
const response = await api( const response = await api(eventURL, {
`dav/calendars/${calId}/${eventId.split("/")[0]}.isc`, method: "DELETE",
{ }).json();
method: "DELETE",
}
).json();
return response; return response;
} }
+1
View File
@@ -1,6 +1,7 @@
import { userAttendee, userOrganiser } from "../User/userDataTypes"; import { userAttendee, userOrganiser } from "../User/userDataTypes";
export interface CalendarEvent { export interface CalendarEvent {
URL: string;
calId: string; calId: string;
uid: string; uid: string;
transp?: string; transp?: string;
+3 -1
View File
@@ -8,7 +8,8 @@ type RawEntry = [string, Record<string, string>, string, any];
export function parseCalendarEvent( export function parseCalendarEvent(
data: RawEntry[], data: RawEntry[],
color: string, color: string,
calendarid: string calendarid: string,
eventURL: string
): CalendarEvent { ): CalendarEvent {
const event: Partial<CalendarEvent> = { color, attendee: [] }; const event: Partial<CalendarEvent> = { color, attendee: [] };
let recurrenceId; let recurrenceId;
@@ -75,6 +76,7 @@ export function parseCalendarEvent(
event.uid = `${event.uid}/${recurrenceId}`; event.uid = `${event.uid}/${recurrenceId}`;
} }
event.URL = eventURL;
if (!event.uid || !event.start) { if (!event.uid || !event.start) {
console.error( console.error(
`missing crucial event param in calendar ${calendarid} `, `missing crucial event param in calendar ${calendarid} `,