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; setAllDay: (allday: boolean) => void;
repetition: RepetitionObject; repetition: RepetitionObject;
setRepetition: (repetition: RepetitionObject) => void; setRepetition: (repetition: RepetitionObject) => void;
typeOfAction?: "solo" | "all";
attendees: userAttendee[]; attendees: userAttendee[];
setAttendees: (attendees: userAttendee[]) => void; setAttendees: (attendees: userAttendee[]) => void;
alarm: string; alarm: string;
@@ -155,6 +156,7 @@ export default function EventFormFields({
setAllDay, setAllDay,
repetition, repetition,
setRepetition, setRepetition,
typeOfAction,
attendees, attendees,
setAttendees, setAttendees,
alarm, alarm,
@@ -343,12 +345,13 @@ export default function EventFormFields({
label="All day" label="All day"
/> />
<FormControlLabel <FormControlLabel
control={ control={
<Checkbox <Checkbox
checked={showRepeat} checked={showRepeat}
onChange={() => { disabled={typeOfAction === "solo"}
const newShowRepeat = !showRepeat; onChange={() => {
setShowRepeat(newShowRepeat); const newShowRepeat = !showRepeat;
setShowRepeat(newShowRepeat);
if (newShowRepeat) { if (newShowRepeat) {
setRepetition({ setRepetition({
freq: "daily", freq: "daily",
@@ -393,6 +396,7 @@ export default function EventFormFields({
repetition={repetition} repetition={repetition}
eventStart={new Date(start)} eventStart={new Date(start)}
setRepetition={setRepetition} setRepetition={setRepetition}
isOwn={true} /* Always editable when shown */
/> />
</FieldWithLabel> </FieldWithLabel>
)} )}
+2 -1
View File
@@ -24,7 +24,7 @@ import {
import AvatarGroup from "@mui/material/AvatarGroup"; import AvatarGroup from "@mui/material/AvatarGroup";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useAppDispatch, useAppSelector } from "../../app/hooks"; import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { deleteEventAsync, getEventAsync } from "../Calendars/CalendarSlice"; import { deleteEventAsync } from "../Calendars/CalendarSlice";
import { dlEvent } from "./EventApi"; import { dlEvent } from "./EventApi";
import EventDisplayModal from "./EventDisplay"; import EventDisplayModal from "./EventDisplay";
import EventUpdateModal from "./EventUpdateModal"; import EventUpdateModal from "./EventUpdateModal";
@@ -512,6 +512,7 @@ export default function EventPreviewModal({
onClose={() => setOpenUpdateModal(false)} onClose={() => setOpenUpdateModal(false)}
eventId={eventId} eventId={eventId}
calId={calId} calId={calId}
typeOfAction={typeOfAction}
/> />
</> </>
); );
+35 -11
View File
@@ -12,6 +12,8 @@ import {
putEventAsync, putEventAsync,
removeEvent, removeEvent,
moveEventAsync, moveEventAsync,
updateEventInstanceAsync,
updateSeriesAsync,
} from "../Calendars/CalendarSlice"; } from "../Calendars/CalendarSlice";
import { Calendars } from "../Calendars/CalendarTypes"; import { Calendars } from "../Calendars/CalendarTypes";
import { userAttendee } from "../User/userDataTypes"; import { userAttendee } from "../User/userDataTypes";
@@ -22,6 +24,8 @@ import EventFormFields, {
formatDateTimeInTimezone, formatDateTimeInTimezone,
} from "../../components/Event/EventFormFields"; } from "../../components/Event/EventFormFields";
import { getEvent } from "./EventApi"; import { getEvent } from "./EventApi";
import { refreshCalendars } from "../../components/Event/utils/eventUtils";
import { getCalendarRange } from "../../utils/dateUtils";
function EventUpdateModal({ function EventUpdateModal({
eventId, eventId,
@@ -29,12 +33,14 @@ function EventUpdateModal({
open, open,
onClose, onClose,
eventData, eventData,
typeOfAction,
}: { }: {
eventId: string; eventId: string;
calId: string; calId: string;
open: boolean; open: boolean;
onClose: (event: {}, reason: "backdropClick" | "escapeKeyDown") => void; onClose: (event: {}, reason: "backdropClick" | "escapeKeyDown") => void;
eventData?: CalendarEvent | null; eventData?: CalendarEvent | null;
typeOfAction?: "solo" | "all";
}) { }) {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@@ -340,23 +346,40 @@ function EventUpdateModal({
dispatch(removeEvent({ calendarUid: calId, eventUid: event.uid })); dispatch(removeEvent({ calendarUid: calId, eventUid: event.uid }));
} }
// Handle recurrence instances // Handle recurrence instances
const [baseId, recurrenceId] = event.uid.split("/"); const [, recurrenceId] = event.uid.split("/");
if (recurrenceId) {
Object.keys(targetCalendar.events).forEach((element) => {
if (element.split("/")[0] === baseId) {
dispatch(removeEvent({ calendarUid: calId, eventUid: element }));
}
});
}
// 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( dispatch(
putEventAsync({ putEventAsync({
cal: targetCalendar, cal: targetCalendar,
newEvent, newEvent,
}) })
); );
}
// Handle calendar change // Handle calendar change
if (newCalId !== calId) { if (newCalId !== calId) {
@@ -413,6 +436,7 @@ function EventUpdateModal({
setAllDay={setAllDay} setAllDay={setAllDay}
repetition={repetition} repetition={repetition}
setRepetition={setRepetition} setRepetition={setRepetition}
typeOfAction={typeOfAction}
attendees={attendees} attendees={attendees}
setAttendees={setAttendees} setAttendees={setAttendees}
alarm={alarm} alarm={alarm}
@@ -432,7 +456,7 @@ function EventUpdateModal({
showMore={showMore} showMore={showMore}
showDescription={showDescription} showDescription={showDescription}
setShowDescription={setShowDescription} setShowDescription={setShowDescription}
showRepeat={showRepeat} showRepeat={typeOfAction !== "solo" && showRepeat}
setShowRepeat={setShowRepeat} setShowRepeat={setShowRepeat}
userPersonnalCalendars={userPersonnalCalendars} userPersonnalCalendars={userPersonnalCalendars}
timezoneList={timezoneList} timezoneList={timezoneList}