[#446] removed direct state update (#468)

This commit is contained in:
Camille Moussu
2026-01-21 15:17:49 +01:00
committed by GitHub
parent 23d50f250d
commit 00742119be
38 changed files with 119 additions and 1366 deletions
@@ -1,4 +1,3 @@
import { Calendar } from "@/features/Calendars/CalendarTypes";
import { userData } from "@/features/User/userDataTypes";
import { Box, Typography } from "@linagora/twake-mui";
import { Dispatch, SetStateAction } from "react";
@@ -8,7 +7,6 @@ import { RSVPButton } from "./RSVPButton";
interface AttendanceValidationProps {
contextualizedEvent: ContextualizedEvent;
calendarList: Calendar[];
user: userData | undefined;
setAfterChoiceFunc: Dispatch<SetStateAction<Function | undefined>>;
setOpenEditModePopup: Dispatch<SetStateAction<string | null>>;
@@ -16,7 +14,6 @@ interface AttendanceValidationProps {
export function AttendanceValidation({
contextualizedEvent,
calendarList,
user,
setAfterChoiceFunc,
setOpenEditModePopup,
@@ -36,7 +33,6 @@ export function AttendanceValidation({
const commonButtonProps = {
contextualizedEvent,
user,
calendarList,
setAfterChoiceFunc,
setOpenEditModePopup,
};
@@ -1,5 +1,4 @@
import { useAppDispatch } from "@/app/hooks";
import { Calendar } from "@/features/Calendars/CalendarTypes";
import { PartStat } from "@/features/User/models/attendee";
import { userData } from "@/features/User/userDataTypes";
import { Button } from "@linagora/twake-mui";
@@ -20,7 +19,6 @@ interface RSVPButtonProps {
rsvpValue: PartStat;
contextualizedEvent: ContextualizedEvent;
user: userData | undefined;
calendarList: Calendar[];
setAfterChoiceFunc: Dispatch<SetStateAction<Function | undefined>>;
setOpenEditModePopup: Dispatch<SetStateAction<string | null>>;
}
@@ -29,7 +27,6 @@ export function RSVPButton({
rsvpValue,
contextualizedEvent,
user,
calendarList,
setAfterChoiceFunc,
setOpenEditModePopup,
}: RSVPButtonProps) {
@@ -54,7 +51,6 @@ export function RSVPButton({
rsvpValue,
contextualizedEvent,
user,
calendarList,
setAfterChoiceFunc,
setOpenEditModePopup,
dispatch
@@ -1,6 +1,5 @@
import { AppDispatch } from "@/app/store";
import { handleRSVP } from "@/components/Event/eventHandlers/eventHandlers";
import { Calendar } from "@/features/Calendars/CalendarTypes";
import { PartStat } from "@/features/User/models/attendee";
import { userData } from "@/features/User/userDataTypes";
import { Dispatch, SetStateAction } from "react";
@@ -10,7 +9,6 @@ export async function handleRSVPClick(
rsvp: PartStat,
contextualizedEvent: ContextualizedEvent,
user: userData | undefined,
calendarList: Calendar[],
setAfterChoiceFunc: Dispatch<SetStateAction<Function | undefined>>,
setOpenEditModePopup: Dispatch<SetStateAction<string | null>>,
dispatch: AppDispatch
@@ -19,15 +17,7 @@ export async function handleRSVPClick(
if (isRecurring) {
setAfterChoiceFunc(() => async (type: string) => {
try {
await handleRSVP(
dispatch,
calendar,
user,
event,
rsvp,
type,
calendarList
);
await handleRSVP(dispatch, calendar, user, event, rsvp, type);
} catch (error) {
console.error("Error handling RSVP:", error);
}
+1 -19
View File
@@ -1,17 +1,13 @@
import { useAppDispatch, useAppSelector } from "@/app/hooks";
import { CalendarName } from "@/components/Calendar/CalendarName";
import { getTimezoneOffset } from "@/components/Calendar/TimezoneSelector";
import {
formatEventChipTitle,
updateTempCalendar,
} from "@/components/Calendar/utils/calendarUtils";
import { formatEventChipTitle } from "@/components/Calendar/utils/calendarUtils";
import ResponsiveDialog from "@/components/Dialog/ResponsiveDialog";
import { EditModeDialog } from "@/components/Event/EditModeDialog";
import EventDuplication from "@/components/Event/EventDuplicate";
import { handleDelete } from "@/components/Event/eventHandlers/eventHandlers";
import { InfoRow } from "@/components/Event/InfoRow";
import { renderAttendeeBadge } from "@/components/Event/utils/eventUtils";
import { getCalendarRange } from "@/utils/dateUtils";
import { browserDefaultTimeZone } from "@/utils/timezone";
import { DateSelectArg } from "@fullcalendar/core";
import {
@@ -282,18 +278,6 @@ export default function EventPreviewModal({
(a) => a.cal_address === event.organizer?.cal_address
);
const updateTempList = async () => {
if (calendars.templist) {
const calendarRange = getCalendarRange(new Date(event.start));
await updateTempCalendar(
calendars.templist,
event,
dispatch,
calendarRange
);
}
};
return (
<>
<ResponsiveDialog
@@ -429,8 +413,6 @@ export default function EventPreviewModal({
if (result && typeof result.unwrap === "function") {
await result.unwrap();
}
await updateTempList();
} catch (error) {
console.error("Failed to delete event:", error);
}
+1 -7
View File
@@ -60,12 +60,11 @@ function EventPopover({
event?: CalendarEvent;
}) {
const dispatch = useAppDispatch();
const { t, lang } = useI18n();
const { t } = useI18n();
const organizer = useAppSelector((state) => state.user.organiserData);
const userId =
useAppSelector((state) => state.user.userData?.openpaasId) ?? "";
const tempList = useAppSelector((state) => state.calendars.templist);
const calList = useAppSelector((state) => state.calendars.list);
const selectPersonalCalendars = createSelector(
(state: any) => state.calendars,
@@ -838,11 +837,6 @@ function EventPopover({
}
}
if (tempList) {
const calendarRange = getCalendarRange(new Date(start));
await updateTempCalendar(tempList, newEvent, dispatch, calendarRange);
}
// Clear temp data on successful save
clearEventFormTempData("create");
+5 -29
View File
@@ -65,7 +65,6 @@ function EventUpdateModal({
}) {
const { t } = useI18n();
const dispatch = useAppDispatch();
const tempList = useAppSelector((state) => state.calendars.templist);
const calList = useAppSelector((state) => state.calendars.list);
// Get event from Redux store (cached data) as fallback
const cachedEvent = useAppSelector(
@@ -78,6 +77,10 @@ function EventUpdateModal({
// Use fresh data if available, otherwise use eventData from props, otherwise use cached data
const event = freshEvent || eventData || cachedEvent;
useEffect(() => {
setFreshEvent(null);
}, [eventId, calId]);
// Fetch fresh event data when modal opens
useEffect(() => {
if (open && cachedEvent && !eventData) {
@@ -714,11 +717,6 @@ function EventUpdateModal({
// Clear cache to ensure navigation to other weeks works
dispatch(clearFetchCache(calId));
if (tempList) {
const calendarRange = getCalendarRange(new Date(start));
await updateTempCalendar(tempList, event, dispatch, calendarRange);
}
// STEP 5: Remove old recurring instances only after the rest succeeds
removeSeriesInstancesFromUI();
@@ -834,7 +832,7 @@ function EventUpdateModal({
const repetitionRulesChanged = changes.repetitionRulesChanged;
if (repetitionRulesChanged) {
// Date/time or repetition rules changed - remove all overrides and refresh
// Date/time or repetition rules changed - remove all overrides
const seriesInstancesSnapshot = getSeriesInstances();
@@ -892,23 +890,6 @@ function EventUpdateModal({
}
}
// STEP 3: Fetch to get new instances with correct timing
// If refreshCalendars fails, we need to throw error to reopen modal
try {
const calendarRange = getCalendarRange(new Date(start));
await refreshCalendars(
dispatch,
Object.values(calendarsList),
calendarRange
);
} catch (refreshError: any) {
// If refreshCalendars fails, throw error to reopen modal
throw new Error(
refreshError?.message ||
"Failed to refresh calendar events. Please try again."
);
}
// Clear cache after reload
dispatch(clearFetchCache(calId));
@@ -1085,15 +1066,10 @@ function EventUpdateModal({
if (moveResult && typeof moveResult.unwrap === "function") {
await moveResult.unwrap();
}
dispatch(removeEvent({ calendarUid: calId, eventUid: event.uid }));
// Clear temp data on successful move
clearEventFormTempData("update");
}
if (tempList) {
const calendarRange = getCalendarRange(new Date(start));
await updateTempCalendar(tempList, event, dispatch, calendarRange);
}
// Reset all state to default values only on successful save (after all branches)
clearEventFormTempData("update");