[#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
-7
View File
@@ -406,10 +406,6 @@ export default function CalendarApp({
});
}, [calendarsWithClearedCache, dispatch, rangeKey, rangeStart, rangeEnd]);
const tempCalendarControllersRef = useRef<Map<string, AbortController>>(
new Map()
);
useEffect(() => {
const currentIds = new Set(tempCalendarIds);
Object.keys(tempFetchedRangesRef.current).forEach((id) => {
@@ -558,9 +554,6 @@ export default function CalendarApp({
setSelectedRange,
setAnchorEl,
calendarRef,
selectedCalendars,
tempcalendars,
calendarRange,
dispatch,
setOpenEventDisplay,
setEventDisplayedId,
+7 -8
View File
@@ -30,11 +30,10 @@ function CalendarPopover({
}) {
const { t } = useI18n();
const dispatch = useAppDispatch();
const userId =
useAppSelector((state) => state.user.userData?.openpaasId) ?? "";
const userData = useAppSelector((state) => state.user.userData) ?? {};
const calendars = useAppSelector((state) => state.calendars.list);
const isOwn = calendar?.id
? extractEventBaseUuid(calendar.id) === userId
? extractEventBaseUuid(calendar.id) === userData.openpaasId
: true;
// existing calendar params
@@ -104,14 +103,14 @@ function CalendarPopover({
name: name.trim(),
desc: desc.trim(),
color: color,
userId,
userData,
calId,
})
);
dispatch(
patchACLCalendarAsync({
calId: `${userId}/${calId}`,
calLink: `/calendars/${userId}/${calId}.json`,
calId: `${userData.openpaasId}/${calId}`,
calLink: `/calendars/${userData.openpaasId}/${calId}.json`,
request: visibility === "public" ? "{DAV:}read" : "",
})
);
@@ -142,7 +141,7 @@ function CalendarPopover({
importedContent &&
dispatch(
importEventFromFileAsync({
calLink: `/calendar/${userId}/${calId}.json`,
calLink: `/calendar/${userData.openpaasId}/${calId}.json`,
file: importedContent,
})
);
@@ -227,7 +226,7 @@ function CalendarPopover({
importTarget={importTarget}
setImportTarget={setImportTarget}
setImportedContent={setImportedContent}
userId={userId}
userId={userData.openpaasId ?? ""}
newCalParams={{
name: newCalName,
setName: setNewCalName,
@@ -1,10 +1,8 @@
import { AppDispatch } from "@/app/store";
import { User } from "@/components/Attendees/PeopleSearch";
import { formatLocalDateTime } from "@/components/Event/utils/dateTimeFormatters";
import { refreshCalendars } from "@/components/Event/utils/eventUtils";
import { updateEventLocal } from "@/features/Calendars/CalendarSlice";
import { Calendar } from "@/features/Calendars/CalendarTypes";
import {
getCalendarDetailAsync,
getEventAsync,
putEventAsync,
updateEventInstanceAsync,
@@ -14,21 +12,15 @@ import { getEvent } from "@/features/Events/EventApi";
import { CalendarEvent } from "@/features/Events/EventsTypes";
import { userAttendee } from "@/features/User/models/attendee";
import { createAttendee } from "@/features/User/models/attendee.mapper";
import {
formatDateToYYYYMMDDTHHMMSS,
getDeltaInMilliseconds,
} from "@/utils/dateUtils";
import { CalendarApi, DateSelectArg } from "@fullcalendar/core";
import { updateTempCalendar } from "../utils/calendarUtils";
import { getDeltaInMilliseconds } from "@/utils/dateUtils";
import { CalendarApi, DateSelectArg, EventDropArg } from "@fullcalendar/core";
import { EventResizeDoneArg } from "@fullcalendar/interaction";
export interface EventHandlersProps {
setSelectedRange: (range: DateSelectArg | null) => void;
setAnchorEl: (el: HTMLElement | null) => void;
calendarRef: React.RefObject<CalendarApi | null>;
selectedCalendars: string[];
tempcalendars: Record<string, Calendar>;
calendarRange: { start: Date; end: Date };
dispatch: any;
dispatch: AppDispatch;
setOpenEventDisplay: (open: boolean) => void;
setEventDisplayedId: (id: string) => void;
setEventDisplayedCalId: (id: string) => void;
@@ -47,9 +39,6 @@ export const createEventHandlers = (props: EventHandlersProps) => {
setSelectedRange,
setAnchorEl,
calendarRef,
selectedCalendars,
tempcalendars,
calendarRange,
dispatch,
setOpenEventDisplay,
setEventDisplayedId,
@@ -88,35 +77,10 @@ export const createEventHandlers = (props: EventHandlersProps) => {
setAnchorEl(document.body);
};
const handleClosePopover = (refresh?: boolean) => {
const handleClosePopover = () => {
calendarRef.current?.unselect();
setAnchorEl(null);
setSelectedRange(null);
if (refresh) {
selectedCalendars.forEach((calId) =>
dispatch(
getCalendarDetailAsync({
calId,
match: {
start: formatDateToYYYYMMDDTHHMMSS(calendarRange.start),
end: formatDateToYYYYMMDDTHHMMSS(calendarRange.end),
},
})
)
);
Object.keys(tempcalendars).forEach((calId) =>
dispatch(
getCalendarDetailAsync({
calId,
match: {
start: formatDateToYYYYMMDDTHHMMSS(calendarRange.start),
end: formatDateToYYYYMMDDTHHMMSS(calendarRange.end),
},
calType: "temp",
})
)
);
}
};
const handleCloseEventDisplay = () => {
@@ -151,11 +115,11 @@ export const createEventHandlers = (props: EventHandlersProps) => {
}
};
const handleEventAllow = (dropInfo: any, draggedEvent: any) => {
const handleEventAllow = () => {
return true;
};
const handleEventDrop = async (arg: any) => {
const handleEventDrop = async (arg: EventDropArg) => {
if (!arg.event || !arg.event._def || !arg.event._def.extendedProps) {
return;
}
@@ -182,7 +146,6 @@ export const createEventHandlers = (props: EventHandlersProps) => {
} as CalendarEvent,
true
);
if (isRecurring) {
setSelectedEvent(event);
setOpenEditModePopup("edit");
@@ -192,9 +155,6 @@ export const createEventHandlers = (props: EventHandlersProps) => {
await dispatch(
updateEventInstanceAsync({ cal: calendar, event: newEvent })
);
dispatch(
updateEventLocal({ calId: newEvent.calId, event: newEvent })
);
} else if (typeOfAction === "all") {
const master = await getEvent(newEvent, true);
await dispatch(
@@ -208,30 +168,17 @@ export const createEventHandlers = (props: EventHandlersProps) => {
},
})
);
await refreshCalendars(
dispatch,
Object.values(calendars),
calendarRange
);
await updateTempCalendar(
tempcalendars,
event,
dispatch,
calendarRange
);
}
}
);
} else {
dispatch(updateEventLocal({ calId: newEvent.calId, event: newEvent }));
await dispatch(
putEventAsync({ cal: calendars[newEvent.calId], newEvent })
);
}
await updateTempCalendar(tempcalendars, event, dispatch, calendarRange);
};
const handleEventResize = async (arg: any) => {
const handleEventResize = async (arg: EventResizeDoneArg) => {
if (!arg.event || !arg.event._def || !arg.event._def.extendedProps) {
return;
}
@@ -261,7 +208,6 @@ export const createEventHandlers = (props: EventHandlersProps) => {
} as CalendarEvent,
true
);
if (isRecurring) {
setSelectedEvent(event);
setOpenEditModePopup("edit");
@@ -271,9 +217,6 @@ export const createEventHandlers = (props: EventHandlersProps) => {
await dispatch(
updateEventInstanceAsync({ cal: calendar, event: newEvent })
);
dispatch(
updateEventLocal({ calId: newEvent.calId, event: newEvent })
);
} else if (typeOfAction === "all") {
const master = await getEvent(newEvent, true);
@@ -288,17 +231,6 @@ export const createEventHandlers = (props: EventHandlersProps) => {
},
})
);
await refreshCalendars(
dispatch,
Object.values(calendars),
calendarRange
);
await updateTempCalendar(
tempcalendars,
event,
dispatch,
calendarRange
);
}
}
);
@@ -307,7 +239,6 @@ export const createEventHandlers = (props: EventHandlersProps) => {
putEventAsync({ cal: calendars[newEvent.calId], newEvent })
);
}
await updateTempCalendar(tempcalendars, event, dispatch, calendarRange);
};
return {
@@ -19,9 +19,6 @@ export const useCalendarEventHandlers = (props: EventHandlersProps) => {
props.calendarRef,
props.setAnchorEl,
props.setSelectedRange,
props.selectedCalendars,
props.tempcalendars,
props.calendarRange,
props.dispatch,
]),
handleCloseEventDisplay: useCallback(
@@ -43,14 +40,10 @@ export const useCalendarEventHandlers = (props: EventHandlersProps) => {
props.setSelectedEvent,
props.setOpenEditModePopup,
props.setAfterChoiceFunc,
props.tempcalendars,
props.calendarRange,
]),
handleEventResize: useCallback(eventHandlers.handleEventResize, [
props.calendars,
props.dispatch,
props.tempcalendars,
props.calendarRange,
]),
};
};
@@ -271,35 +271,3 @@ export function getCalendarVisibility(acl: AclEntry[]): "private" | "public" {
if (hasRead) return "public";
return "private";
}
export async function updateTempCalendar(
tempcalendars: Record<string, Calendar>,
event: CalendarEvent,
dispatch: ThunkDispatch<any, any, any>,
calendarRange: { start: Date; end: Date }
) {
if (tempcalendars && event?.attendee) {
const attendeesEmails = event.attendee
.map((a) => a.cal_address)
.filter(Boolean);
const tempCalendarValues = Object.values(tempcalendars);
for (const tempCalendar of tempCalendarValues) {
const ownerEmails = tempCalendar.ownerEmails || [];
// Check if any of the attendees are owners of this temp calendar
const isOwnerAttendee = ownerEmails.some((ownerEmail) =>
attendeesEmails.includes(ownerEmail)
);
if (isOwnerAttendee) {
await refreshSingularCalendar(
dispatch,
tempCalendar,
calendarRange,
"temp"
);
}
}
}
}
@@ -12,8 +12,6 @@ import { PartStat } from "@/features/User/models/attendee";
import { createAttendee } from "@/features/User/models/attendee.mapper";
import { userData } from "@/features/User/userDataTypes";
import { buildFamilyName } from "@/utils/buildFamilyName";
import { getCalendarRange } from "@/utils/dateUtils";
import { refreshCalendars } from "../utils/eventUtils";
function updateEventAttendees(
event: CalendarEvent,
@@ -78,15 +76,11 @@ async function handleSoloRSVP(
}
async function handleAllRSVP(
dispatch: AppDispatch,
event: CalendarEvent,
userEmail: string,
rsvp: PartStat,
calendars: Calendar[]
rsvp: PartStat
) {
const calendarRange = getCalendarRange(new Date(event.start));
await updateSeriesPartstat(event, userEmail, rsvp);
await refreshCalendars(dispatch, calendars, calendarRange);
}
async function handleDefaultRSVP(
@@ -103,8 +97,7 @@ export async function handleRSVP(
user: userData | undefined,
event: CalendarEvent,
rsvp: PartStat,
typeOfAction?: string,
calendars?: Calendar[]
typeOfAction?: string
) {
const newEvent = {
...event,
@@ -114,13 +107,10 @@ export async function handleRSVP(
if (typeOfAction === "solo") {
await handleSoloRSVP(dispatch, calendar, newEvent);
} else if (typeOfAction === "all") {
if (!calendars || calendars.length === 0) {
throw new Error("Cannot update all occurrences without calendar list");
}
if (!user?.email) {
throw new Error("Cannot update all occurrences without user email");
}
await handleAllRSVP(dispatch, event, user.email, rsvp, calendars);
await handleAllRSVP(event, user.email, rsvp);
} else {
await handleDefaultRSVP(dispatch, calendar, newEvent);
}