fix: properly handle recurring events in EventUpdateModal

- Fix handling of solo vs. all event updates for recurring events
- Add calendar refresh for update all events
- Disable repeat option when editing a single occurrence (solo mode)
- Fix event recurrence editing in modals to match main branch
- Properly link EventDisplayPreview with EventUpdateModal for typeOfAction
This commit is contained in:
lenhanphung
2025-10-09 11:50:37 +07:00
committed by Benoit TELLIER
parent 9ff8354950
commit 474ff22cab
3 changed files with 47 additions and 18 deletions
+10 -6
View File
@@ -101,6 +101,7 @@ interface EventFormFieldsProps {
setAllDay: (allday: boolean) => void;
repetition: RepetitionObject;
setRepetition: (repetition: RepetitionObject) => void;
typeOfAction?: "solo" | "all";
attendees: userAttendee[];
setAttendees: (attendees: userAttendee[]) => void;
alarm: string;
@@ -155,6 +156,7 @@ export default function EventFormFields({
setAllDay,
repetition,
setRepetition,
typeOfAction,
attendees,
setAttendees,
alarm,
@@ -343,12 +345,13 @@ export default function EventFormFields({
label="All day"
/>
<FormControlLabel
control={
<Checkbox
checked={showRepeat}
onChange={() => {
const newShowRepeat = !showRepeat;
setShowRepeat(newShowRepeat);
control={
<Checkbox
checked={showRepeat}
disabled={typeOfAction === "solo"}
onChange={() => {
const newShowRepeat = !showRepeat;
setShowRepeat(newShowRepeat);
if (newShowRepeat) {
setRepetition({
freq: "daily",
@@ -393,6 +396,7 @@ export default function EventFormFields({
repetition={repetition}
eventStart={new Date(start)}
setRepetition={setRepetition}
isOwn={true} /* Always editable when shown */
/>
</FieldWithLabel>
)}
+2 -1
View File
@@ -24,7 +24,7 @@ import {
import AvatarGroup from "@mui/material/AvatarGroup";
import { useEffect, useState } from "react";
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { deleteEventAsync, getEventAsync } from "../Calendars/CalendarSlice";
import { deleteEventAsync } from "../Calendars/CalendarSlice";
import { dlEvent } from "./EventApi";
import EventDisplayModal from "./EventDisplay";
import EventUpdateModal from "./EventUpdateModal";
@@ -512,6 +512,7 @@ export default function EventPreviewModal({
onClose={() => setOpenUpdateModal(false)}
eventId={eventId}
calId={calId}
typeOfAction={typeOfAction}
/>
</>
);
+35 -11
View File
@@ -12,6 +12,8 @@ import {
putEventAsync,
removeEvent,
moveEventAsync,
updateEventInstanceAsync,
updateSeriesAsync,
} from "../Calendars/CalendarSlice";
import { Calendars } from "../Calendars/CalendarTypes";
import { userAttendee } from "../User/userDataTypes";
@@ -22,6 +24,8 @@ import EventFormFields, {
formatDateTimeInTimezone,
} from "../../components/Event/EventFormFields";
import { getEvent } from "./EventApi";
import { refreshCalendars } from "../../components/Event/utils/eventUtils";
import { getCalendarRange } from "../../utils/dateUtils";
function EventUpdateModal({
eventId,
@@ -29,12 +33,14 @@ function EventUpdateModal({
open,
onClose,
eventData,
typeOfAction,
}: {
eventId: string;
calId: string;
open: boolean;
onClose: (event: {}, reason: "backdropClick" | "escapeKeyDown") => void;
eventData?: CalendarEvent | null;
typeOfAction?: "solo" | "all";
}) {
const dispatch = useAppDispatch();
@@ -340,23 +346,40 @@ function EventUpdateModal({
dispatch(removeEvent({ calendarUid: calId, eventUid: event.uid }));
}
// Handle recurrence instances
const [baseId, recurrenceId] = event.uid.split("/");
if (recurrenceId) {
Object.keys(targetCalendar.events).forEach((element) => {
if (element.split("/")[0] === baseId) {
dispatch(removeEvent({ calendarUid: calId, eventUid: element }));
}
});
}
// Handle recurrence instances
const [, recurrenceId] = event.uid.split("/");
// Execute API calls in background
// Execute API calls in background based on typeOfAction
if (recurrenceId) {
if (typeOfAction === "solo") {
// Update just this instance
dispatch(
updateEventInstanceAsync({
cal: targetCalendar,
event: { ...newEvent, recurrenceId },
})
);
} else if (typeOfAction === "all") {
// Update all instances
dispatch(
updateSeriesAsync({
cal: targetCalendar,
event: { ...newEvent, recurrenceId },
})
);
// Refresh calendars to ensure all instances are updated
const calendarRange = getCalendarRange(new Date(start));
await refreshCalendars(dispatch, Object.values(calendarsList), calendarRange);
}
} else {
// Non-recurring event
dispatch(
putEventAsync({
cal: targetCalendar,
newEvent,
})
);
}
// Handle calendar change
if (newCalId !== calId) {
@@ -413,6 +436,7 @@ function EventUpdateModal({
setAllDay={setAllDay}
repetition={repetition}
setRepetition={setRepetition}
typeOfAction={typeOfAction}
attendees={attendees}
setAttendees={setAttendees}
alarm={alarm}
@@ -432,7 +456,7 @@ function EventUpdateModal({
showMore={showMore}
showDescription={showDescription}
setShowDescription={setShowDescription}
showRepeat={showRepeat}
showRepeat={typeOfAction !== "solo" && showRepeat}
setShowRepeat={setShowRepeat}
userPersonnalCalendars={userPersonnalCalendars}
timezoneList={timezoneList}