import { useState, useRef, useMemo } from "react"; import { useAppDispatch, useAppSelector } from "../../app/hooks"; import { getTempCalendarsListAsync, removeTempCal, } from "../../features/Calendars/CalendarSlice"; import { Calendars } from "../../features/Calendars/CalendarTypes"; import { CalendarEvent } from "../../features/Events/EventsTypes"; import { User, PeopleSearch } from "../Attendees/PeopleSearch"; const requestControllers = new Map(); export function TempCalendarsInput({ setAnchorEl, setTempEvent, selectedCalendars, setSelectedCalendars, }: { setAnchorEl: Function; setTempEvent: Function; selectedCalendars: string[]; setSelectedCalendars: Function; }) { const [tempUsers, setTempUsers] = useState([]); const dispatch = useAppDispatch(); const tempcalendars = useAppSelector((state) => state.calendars.templist) ?? {}; const calendars = useAppSelector((state) => state.calendars.list); const prevUsersRef = useRef([]); const userColors = new Map(); const handleUserChange = async (_: any, users: User[]) => { setTempUsers(users); const prevUsers = prevUsersRef.current; const addedUsers = users.filter( (u) => !prevUsers.some((p) => p.email === u.email) ); const removedUsers = prevUsers.filter( (p) => !users.some((u) => u.email === p.email) ); prevUsersRef.current = users; const { calendarsToImport, calendarsToToggle } = getCalendarsFromUsersDelta( addedUsers, buildEmailToCalendarMap(calendars), selectedCalendars ); if (calendarsToImport.length > 0) { for (const user of calendarsToImport) { const controller = new AbortController(); requestControllers.set(user.email, controller); if (!userColors.has(user.email)) { const existingColors = new Set(userColors.values()); userColors.set(user.email, generateUserColor(existingColors)); } user.color = userColors.get(user.email)!; dispatch( getTempCalendarsListAsync(user, { signal: controller.signal }) ); } } if (calendarsToToggle.length > 0) { setSelectedCalendars((prev: string[]) => [ ...new Set([...prev, ...calendarsToToggle]), ]); } for (const user of removedUsers) { const controller = requestControllers.get(user.email); if (controller) { controller.abort(); requestControllers.delete(user.email); } const calIds = buildEmailToCalendarMap(tempcalendars).get(user.email); calIds?.forEach((id) => dispatch(removeTempCal(id))); } }; const handleToggleEventPreview = () => { const newEvent: CalendarEvent = { title: "New Event", attendee: tempUsers.map((u) => ({ cn: u.displayName, cal_address: u.email, partstat: "NEED-ACTION", role: "REQ-PARTICIPANT", rsvp: "TRUE", cutype: "INDIVIDUAL", })), } as CalendarEvent; setTempEvent(newEvent); setAnchorEl(document.body); }; return ( ); } function getCalendarsFromUsersDelta( addedUsers: User[], emailToCalendarId: Map, selectedCalendars: string[] ) { const selectedSet = new Set(selectedCalendars); const calendarsToImport: User[] = []; const calendarsToToggle: string[] = []; for (const user of addedUsers) { const calIds = emailToCalendarId.get(user.email) ?? []; if (!calIds || calIds.every((calId) => !selectedSet.has(calId))) { calendarsToImport.push(user); } else { // calIds.forEach((calId) => calendarsToToggle.push(calId)); } } return { calendarsToImport, calendarsToToggle }; } function buildEmailToCalendarMap(calRecord: Record) { const map = new Map(); for (const [id, cal] of Object.entries(calRecord)) { cal.ownerEmails?.forEach((email) => { const existing = map.get(email); if (existing) { existing.push(id); } else { map.set(email, [id]); } }); } return map; } function generateUserColor(existingColors: Set): string { let color: string; do { const hue = Math.floor(Math.random() * 360); color = `hsl(${hue}, 70%, 50%)`; } while (existingColors.has(color)); return color; }