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:
committed by
Benoit TELLIER
parent
9ff8354950
commit
474ff22cab
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user