From 50d734e192bbe1671eba386eee3540a765def006 Mon Sep 17 00:00:00 2001 From: Nikolay Tatarinov Date: Tue, 3 Mar 2026 17:42:03 +0300 Subject: [PATCH] feat: update loading state handling in DutyList component - Replaced the loading skeleton with a compact loading placeholder to improve user experience when data is not yet loaded for the month. - Enhanced the rendering logic to ensure the loading state is visually distinct and does not display the skeleton when data is being fetched. - Updated related tests to verify the new loading behavior and ensure accurate feedback during data fetching. --- webapp-next/src/components/duty/DutyList.test.tsx | 3 ++- webapp-next/src/components/duty/DutyList.tsx | 11 +++-------- webapp-next/src/components/ui/skeleton.tsx | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/webapp-next/src/components/duty/DutyList.test.tsx b/webapp-next/src/components/duty/DutyList.test.tsx index 455c7bf..c5f8b06 100644 --- a/webapp-next/src/components/duty/DutyList.test.tsx +++ b/webapp-next/src/components/duty/DutyList.test.tsx @@ -42,12 +42,13 @@ describe("DutyList", () => { expect(screen.getByText(/No duties this month/i)).toBeInTheDocument(); }); - it("renders quiet placeholder when data not yet loaded for month", () => { + it("renders compact loading placeholder when data not yet loaded for month (no skeleton)", () => { useAppStore.getState().setDuties([]); useAppStore.getState().batchUpdate({ dataForMonthKey: null }); render(); expect(screen.queryByText(/No duties this month/i)).not.toBeInTheDocument(); expect(document.querySelector('[aria-busy="true"]')).toBeInTheDocument(); + expect(document.querySelector('[data-slot="skeleton"]')).not.toBeInTheDocument(); }); it("renders duty with full_name and time range", () => { diff --git a/webapp-next/src/components/duty/DutyList.tsx b/webapp-next/src/components/duty/DutyList.tsx index 70ef692..3fec87e 100644 --- a/webapp-next/src/components/duty/DutyList.tsx +++ b/webapp-next/src/components/duty/DutyList.tsx @@ -17,6 +17,7 @@ import { } from "@/lib/date-utils"; import { cn } from "@/lib/utils"; import { Skeleton } from "@/components/ui/skeleton"; +import { LoadingState } from "@/components/states/LoadingState"; import { DutyTimelineCard } from "./DutyTimelineCard"; /** Extra offset so the sticky calendar slightly overlaps the target card (card sits a bit under the calendar). */ @@ -146,14 +147,8 @@ export function DutyList({ scrollMarginTop = 268, className }: DutyListProps) { if (!hasDataForMonth) { return ( -
- {t("loading")} - +
+
); } diff --git a/webapp-next/src/components/ui/skeleton.tsx b/webapp-next/src/components/ui/skeleton.tsx index 3ec6be7..0118624 100644 --- a/webapp-next/src/components/ui/skeleton.tsx +++ b/webapp-next/src/components/ui/skeleton.tsx @@ -4,7 +4,7 @@ function Skeleton({ className, ...props }: React.ComponentProps<"div">) { return (
)