fix: update loading state handling in CalendarPage and DutyList components
- Set isLoading to false in CalendarPage to prevent unnecessary loading indicators. - Removed the loading spinner from CalendarHeader and adjusted rendering logic in DutyList to show a placeholder when data is not yet loaded for the month. - Enhanced tests in DutyList to verify behavior when data is empty and when data is loading, ensuring accurate user feedback during data fetching.
This commit is contained in:
@@ -64,9 +64,15 @@ export interface DutyListProps {
|
||||
export function DutyList({ scrollMarginTop = 268, className }: DutyListProps) {
|
||||
const { t } = useTranslation();
|
||||
const listRef = useRef<HTMLDivElement>(null);
|
||||
const { currentMonth, duties, loading } = useAppStore(
|
||||
useShallow((s) => ({ currentMonth: s.currentMonth, duties: s.duties, loading: s.loading }))
|
||||
const { currentMonth, duties, dataForMonthKey } = useAppStore(
|
||||
useShallow((s) => ({
|
||||
currentMonth: s.currentMonth,
|
||||
duties: s.duties,
|
||||
dataForMonthKey: s.dataForMonthKey,
|
||||
}))
|
||||
);
|
||||
const monthKey = `${currentMonth.getFullYear()}-${String(currentMonth.getMonth() + 1).padStart(2, "0")}`;
|
||||
const hasDataForMonth = dataForMonthKey === monthKey;
|
||||
|
||||
const { filtered, dates, dutiesByDateKey } = useMemo(() => {
|
||||
const filteredList = duties.filter((d) => d.event_type === "duty");
|
||||
@@ -105,7 +111,6 @@ export function DutyList({ scrollMarginTop = 268, className }: DutyListProps) {
|
||||
const id = setInterval(() => setNow(new Date()), 60_000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
const monthKey = `${currentMonth.getFullYear()}-${currentMonth.getMonth()}`;
|
||||
const scrolledForMonthRef = useRef<string | null>(null);
|
||||
const prevScrollMarginTopRef = useRef<number>(scrollMarginTop);
|
||||
const prevMonthKeyRef = useRef<string>(monthKey);
|
||||
@@ -139,17 +144,25 @@ export function DutyList({ scrollMarginTop = 268, className }: DutyListProps) {
|
||||
});
|
||||
}, [filtered, dates.length, scrollMarginTop, monthKey]);
|
||||
|
||||
if (!hasDataForMonth) {
|
||||
return (
|
||||
<div
|
||||
className={cn("min-h-[120px]", className)}
|
||||
role="status"
|
||||
aria-busy="true"
|
||||
aria-live="polite"
|
||||
aria-label={t("loading")}
|
||||
>
|
||||
<span className="sr-only">{t("loading")}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (filtered.length === 0) {
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-1", className)}>
|
||||
{loading ? (
|
||||
<p className="text-sm text-muted m-0">{t("loading")}</p>
|
||||
) : (
|
||||
<>
|
||||
<p className="text-sm text-muted m-0">{t("duty.none_this_month")}</p>
|
||||
<p className="text-xs text-muted m-0">{t("duty.none_this_month_hint")}</p>
|
||||
</>
|
||||
)}
|
||||
<p className="text-sm text-muted m-0">{t("duty.none_this_month")}</p>
|
||||
<p className="text-xs text-muted m-0">{t("duty.none_this_month_hint")}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user