diff --git a/src/app/(protected)/workorders/_components/list/table/wo-table-body.tsx b/src/app/(protected)/workorders/_components/list/table/wo-table-body.tsx index 65f49dbd..7e51c960 100644 --- a/src/app/(protected)/workorders/_components/list/table/wo-table-body.tsx +++ b/src/app/(protected)/workorders/_components/list/table/wo-table-body.tsx @@ -23,8 +23,14 @@ export function WoTableBody({ tableData, renderRow, renderInlineRow }: WoTableBo const unassignedRows = tableData.unassigned ?? []; const showUnscheduled = (tableData.unscheduled?.length ?? 0) > 0 || tableData.draftDayKey === UNSCHEDULED_DAY_KEY; + // SH-165: "still loading" and "zero unassigned" are distinct states. Without + // this split the pin announced "No unassigned work orders." while the queue + // was still paging board/search on first mount. const showUnassignedLoading = - tableData.unassignedOpen && Boolean(tableData.unassignedLoading) && !tableData.unassignedError; + tableData.unassignedOpen && + unassignedRows.length === 0 && + !tableData.unassignedError && + tableData.unassignedLoading; const showUnassignedEmpty = tableData.unassignedOpen && unassignedRows.length === 0 && @@ -53,10 +59,10 @@ export function WoTableBody({ tableData, renderRow, renderInlineRow }: WoTableBo )} {showUnassignedLoading && ( - + - Loading unassigned work orders. + Loading unassigned work orders… diff --git a/src/app/(protected)/workorders/_hooks/use-work-orders-board-source.ts b/src/app/(protected)/workorders/_hooks/use-work-orders-board-source.ts index 2227e3f9..914bf835 100644 --- a/src/app/(protected)/workorders/_hooks/use-work-orders-board-source.ts +++ b/src/app/(protected)/workorders/_hooks/use-work-orders-board-source.ts @@ -76,7 +76,7 @@ export function useWorkOrdersBoardSource(filters: FiltersReturn): WorkOrdersBoar } = useWorkOrdersBoardSearch(resolvedSearchParams ?? { datePreset: "ThisWeek" }, advActive); const { data: queueData, - isPending: queuePending, + isLoading: queueLoading, isFetching: queueFetching, error: queueError, refetch: refetchQueue, @@ -96,7 +96,10 @@ export function useWorkOrdersBoardSource(filters: FiltersReturn): WorkOrdersBoar data: advActive ? searchData : boardData, unassignedQueue: advActive ? EMPTY_UNASSIGNED_QUEUE : (queueData ?? EMPTY_UNASSIGNED_QUEUE), unassignedError: advActive ? null : (queueError ?? null), - unassignedLoading: advActive ? false : queuePending, + // SH-165: the pinned queue has its own first-load state. Folding it into + // isFetching only made "still paging board/search" indistinguishable from + // "zero unassigned", so the pin announced an empty queue while loading. + unassignedLoading: advActive ? false : queueLoading, isLoading: advActive ? searchLoading : boardLoading, isFetching: advActive ? searchFetching : boardFetching || queueFetching, error: advActive ? searchError : boardError, diff --git a/src/test/app/(protected)/workorders/wo-table-unassigned-queue.test.tsx b/src/test/app/(protected)/workorders/wo-table-unassigned-queue.test.tsx index a3461cd9..66a61208 100644 --- a/src/test/app/(protected)/workorders/wo-table-unassigned-queue.test.tsx +++ b/src/test/app/(protected)/workorders/wo-table-unassigned-queue.test.tsx @@ -309,6 +309,36 @@ describe("WoTableBody Unassigned queue (SH-165)", () => { expect(screen.queryByText("WED · 07/15")).not.toBeInTheDocument(); }); + it("distinguishes a still-loading queue from an empty one", () => { + render( + + null} + renderInlineRow={() => null} + /> +
, + ); + + expect(screen.getByText(/Loading unassigned work orders/)).toBeInTheDocument(); + expect(screen.queryByText("No unassigned work orders.")).not.toBeInTheDocument(); + }); + + it("announces an empty queue only once loading has settled", () => { + render( + + null} + renderInlineRow={() => null} + /> +
, + ); + + expect(screen.getByText("No unassigned work orders.")).toBeInTheDocument(); + expect(screen.queryByText(/Loading unassigned work orders/)).not.toBeInTheDocument(); + }); + it("keeps the Unassigned pin visible when the queue query fails", () => { render( @@ -351,25 +381,6 @@ describe("WoTableBody Unassigned queue (SH-165)", () => { expect(screen.queryByTestId(/row-/)).not.toBeInTheDocument(); }); - it("shows a loading state instead of empty while the unassigned queue is pending", () => { - render( -
- ( - - - - )} - renderInlineRow={() => null} - /> -
{row.woNumber}
, - ); - - expect(screen.getByText("Loading unassigned work orders.")).toBeInTheDocument(); - expect(screen.queryByText("No unassigned work orders.")).not.toBeInTheDocument(); - }); - it("removes a pinned row immediately after assigning through the board PATCH path", async () => { const user = userEvent.setup(); const pinned = makeRow({