Co-authored-by: Lê Nhân Phụng <lenhanphung@Phung-Mac-M4.local>
This commit is contained in:
@@ -1,48 +1,56 @@
|
||||
import { Alert, Collapse } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { useState, useMemo, useEffect } from "react";
|
||||
import { useAppSelector } from "../../app/hooks";
|
||||
import { EventErrorSnackbar } from "../../components/Error/ErrorSnackbar";
|
||||
|
||||
export default function ImportAlert() {
|
||||
const [visibleAlerts, setVisibleAlerts] = useState<Record<string, boolean>>(
|
||||
{}
|
||||
);
|
||||
const calendars = useAppSelector((state) => state.calendars.list);
|
||||
const [dismissedErrors, setDismissedErrors] = useState<Set<string>>(
|
||||
new Set()
|
||||
);
|
||||
|
||||
const toggleEventAlert = (eventId: string) => {
|
||||
setVisibleAlerts((prev) => ({
|
||||
...prev,
|
||||
[eventId]: false,
|
||||
}));
|
||||
// Collect all errors from all events in all calendars
|
||||
const errors = useMemo(() => {
|
||||
const errorList: { id: string; message: string }[] = [];
|
||||
Object.values(calendars || {}).forEach((calendar) => {
|
||||
if (calendar.events) {
|
||||
Object.values(calendar.events).forEach((event) => {
|
||||
if (event.error) {
|
||||
errorList.push({
|
||||
id: event.uid,
|
||||
message: event.error,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return errorList;
|
||||
}, [calendars]);
|
||||
|
||||
// Filter out dismissed errors
|
||||
const activeErrors = useMemo(() => {
|
||||
return errors.filter((e) => !dismissedErrors.has(e.id));
|
||||
}, [errors, dismissedErrors]);
|
||||
|
||||
const messages = activeErrors.map((e) => e.message);
|
||||
|
||||
const handleClose = () => {
|
||||
// Mark all currently active errors as dismissed
|
||||
setDismissedErrors((prev) => {
|
||||
const next = new Set(prev);
|
||||
activeErrors.forEach((e) => next.add(e.id));
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{Object.keys(calendars || {}).map((calendarId) =>
|
||||
calendars?.[calendarId]?.events
|
||||
? Object.keys(calendars[calendarId]?.events)
|
||||
.filter((id) => calendars[calendarId]?.events[id].error)
|
||||
.map((id) => {
|
||||
const isVisible =
|
||||
visibleAlerts[calendars[calendarId].events[id].uid] ?? true; // default to visible
|
||||
// If new errors appear that were previously dismissed (e.g. re-fetch),
|
||||
// we might want to un-dismiss them, but for now simple dismissal is enough.
|
||||
// Actually, if the error persists in the store, it's the same error.
|
||||
// If the user fixes it and it comes back, it might be a new fetch.
|
||||
// But usually uid is stable.
|
||||
|
||||
return (
|
||||
<Collapse
|
||||
in={isVisible}
|
||||
key={calendars[calendarId].events[id].uid}
|
||||
>
|
||||
<Alert
|
||||
severity="error"
|
||||
onClose={() =>
|
||||
toggleEventAlert(calendars[calendarId].events[id].uid)
|
||||
}
|
||||
>
|
||||
{calendars[calendarId].events[id].error}
|
||||
</Alert>
|
||||
</Collapse>
|
||||
);
|
||||
})
|
||||
: []
|
||||
)}
|
||||
</>
|
||||
);
|
||||
if (messages.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <EventErrorSnackbar messages={messages} onClose={handleClose} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user