diff --git a/src/app/admin/reviews/page.tsx b/src/app/admin/reviews/page.tsx index 5bf85ee..8363dab 100644 --- a/src/app/admin/reviews/page.tsx +++ b/src/app/admin/reviews/page.tsx @@ -86,12 +86,12 @@ export default function ReviewsPage() { }, [isAdmin, router]) const fetchReviews = useCallback( - async (currentSkip = 0) => { + async (currentSkip = 0, options?: { silent?: boolean }) => { if (abortRef.current) abortRef.current.abort() const ctrl = new AbortController() abortRef.current = ctrl - setLoading(true) + if (!options?.silent) setLoading(true) setError(null) try { const res = await listReviews( @@ -107,13 +107,13 @@ export default function ReviewsPage() { setReviews(res.reviews) setTotal(res.total) setSkip(currentSkip) - setSelectedIds(new Set()) + if (!options?.silent) setSelectedIds(new Set()) } catch (err: unknown) { if ((err as { name?: string })?.name !== "AbortError") { setError("Failed to load reviews") } } finally { - setLoading(false) + if (!options?.silent) setLoading(false) } }, [statusFilter, actionFilter, sort] @@ -205,7 +205,7 @@ export default function ReviewsPage() { `${failures} of ${selectedReviews.length} ${kind === "approve" ? "approvals" : "dismissals"} failed` ) } - await fetchReviews(skip) + await fetchReviews(skip, { silent: true }) refreshPendingCount() } @@ -400,7 +400,7 @@ export default function ReviewsPage() { key={review.ref_id} review={review} schemas={schemas} - onRefresh={() => fetchReviews(skip)} + onRefresh={() => fetchReviews(skip, { silent: true })} onCountRefresh={refreshPendingCount} selectable={review.status === "pending"} selected={selectedIds.has(review.ref_id)} diff --git a/src/lib/__tests__/reviews.test.tsx b/src/lib/__tests__/reviews.test.tsx index 9309c54..2044764 100644 --- a/src/lib/__tests__/reviews.test.tsx +++ b/src/lib/__tests__/reviews.test.tsx @@ -126,7 +126,8 @@ describe("ReviewRow", () => { const { getByText } = render( ) - expect(getByText("Approve")).toBeTruthy() + // merge_nodes action uses "Merge" as the approve verb (ACTION_LABELS) + expect(getByText("Merge")).toBeTruthy() expect(getByText("Dismiss")).toBeTruthy() }) @@ -134,7 +135,7 @@ describe("ReviewRow", () => { const { queryByText } = render( ) - expect(queryByText("Approve")).toBeNull() + expect(queryByText("Merge")).toBeNull() expect(queryByText("Dismiss")).toBeNull() }) @@ -142,7 +143,7 @@ describe("ReviewRow", () => { const { queryByText } = render( ) - expect(queryByText("Approve")).toBeNull() + expect(queryByText("Merge")).toBeNull() expect(queryByText("Dismiss")).toBeNull() }) @@ -150,7 +151,7 @@ describe("ReviewRow", () => { const { queryByText } = render( ) - expect(queryByText("Approve")).toBeNull() + expect(queryByText("Merge")).toBeNull() expect(queryByText("Dismiss")).toBeNull() }) @@ -193,8 +194,9 @@ describe("ReviewRow", () => { ) // First click opens the confirm popover - await user.click(getByText("Approve")) - expect(getByText("Approve this merge?")).toBeTruthy() + // merge_nodes action uses "Merge" as the approve verb (ACTION_LABELS) + await user.click(getByText("Merge")) + expect(getByText("Merge these nodes?")).toBeTruthy() // Confirm in the popover triggers the API await user.click(getByText("Confirm")) @@ -213,7 +215,8 @@ describe("ReviewRow", () => { ) - await user.click(getByText("Approve")) + // merge_nodes action uses "Merge" as the approve verb (ACTION_LABELS) + await user.click(getByText("Merge")) await user.click(getByText("Confirm")) const errEl = await findByText(/no handler registered for action: supersede/) @@ -377,9 +380,10 @@ describe("ReviewRow", () => { onRefresh={noop} /> ) - // Row renders with an svg icon and subject count + // soft_delete action uses rowLabel: "Hide [displayName]" — the subject node + // has name "Mock Episode", so the row label becomes "Hide Mock Episode". expect(container.querySelector("svg")).toBeTruthy() - expect(getByText(/1 subject/)).toBeTruthy() + expect(getByText(/Hide Mock Episode/)).toBeTruthy() }) it("renders topic_review_candidate row without errors", () => { @@ -402,9 +406,10 @@ describe("ReviewRow", () => { onRefresh={noop} /> ) - // Row renders with an svg icon and subject count + // soft_delete action uses rowLabel: "Hide [displayName]" — the subject node + // has name "Orphaned Topic", so the row label becomes "Hide Orphaned Topic". expect(container.querySelector("svg")).toBeTruthy() - expect(getByText(/1 subject/)).toBeTruthy() + expect(getByText(/Hide Orphaned Topic/)).toBeTruthy() }) })