|
9 | 9 | VisibilityState, |
10 | 10 | } from "@tanstack/react-table"; |
11 | 11 | import * as API from "aws-amplify/api"; |
12 | | -import { useState, useMemo, ChangeEvent, ChangeEventHandler } from "react"; |
| 12 | +import { useState, useMemo, useEffect, useRef, ChangeEvent, ChangeEventHandler } from "react"; |
13 | 13 | //import { formatDate } from "../utils"; |
14 | 14 | import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; |
15 | 15 | import * as ToggleGroup from "@radix-ui/react-toggle-group"; |
@@ -42,7 +42,7 @@ import style from "./BlockersTable.module.scss"; |
42 | 42 | import { SkeletonBlockersTable } from "./Skeleton"; |
43 | 43 | import { StyledLabeledInput } from "./StyledLabeledInput"; |
44 | 44 | import { useDebouncedCallback } from 'use-debounce'; |
45 | | -import { Link } from "react-router-dom"; |
| 45 | +import { Link, useSearchParams } from "react-router-dom"; |
46 | 46 | import { BlockersTableColumnToggle } from "./BlockersTableColumnToggle"; |
47 | 47 |
|
48 | 48 | SyntaxHighlighter.registerLanguage("jsx", jsx); |
@@ -101,8 +101,19 @@ declare module '@tanstack/table-core' { |
101 | 101 |
|
102 | 102 | export const BlockersTable = ({ auditId, isShared }: BlockersTableProps) => { |
103 | 103 | const queryClient = useQueryClient(); |
104 | | - const [page, setPage] = useState(0); |
105 | | - const [pageSize, setPageSize] = useState(10); |
| 104 | + const [searchParams, setSearchParams] = useSearchParams(); |
| 105 | + const page = parseInt(searchParams.get("page") ?? "0", 10); |
| 106 | + const pageSize = parseInt(searchParams.get("pageSize") ?? "10", 10); |
| 107 | + |
| 108 | + const setPage = (updater: number | ((p: number) => number)) => { |
| 109 | + setSearchParams((prev) => { |
| 110 | + const next = new URLSearchParams(prev); |
| 111 | + const newPage = typeof updater === "function" ? updater(page) : updater; |
| 112 | + if (newPage === 0) next.delete("page"); |
| 113 | + else next.set("page", newPage.toString()); |
| 114 | + return next; |
| 115 | + }); |
| 116 | + }; |
106 | 117 |
|
107 | 118 | const [selectedTags, setSelectedTags] = useState<Option[]>([]); |
108 | 119 | const [availableTags, setAvailableTags] = useState<Option[]>([]); // Added to prevent content flicker while fetching |
@@ -330,6 +341,23 @@ export const BlockersTable = ({ auditId, isShared }: BlockersTableProps) => { |
330 | 341 | placeholderData: (previousData) => previousData, |
331 | 342 | }); |
332 | 343 |
|
| 344 | + // Announce pagination changes to screen readers once the newly requested |
| 345 | + // page has actually loaded (data still holds the previous page until then). |
| 346 | + const announcedPageRef = useRef(page); |
| 347 | + const announcedPageSizeRef = useRef(pageSize); |
| 348 | + useEffect(() => { |
| 349 | + if (!data?.pagination) return; |
| 350 | + if (announcedPageRef.current !== page || announcedPageSizeRef.current !== pageSize) { |
| 351 | + setAnnounceMessage( |
| 352 | + `Showing ${data.blockers?.length ?? 0} of ${data.pagination.totalCount} blockers, page ${page + 1} of ${data.pagination.totalPages}`, |
| 353 | + "normal", |
| 354 | + true |
| 355 | + ); |
| 356 | + } |
| 357 | + announcedPageRef.current = page; |
| 358 | + announcedPageSizeRef.current = pageSize; |
| 359 | + }, [data]); |
| 360 | + |
333 | 361 | const getElementTagFromContent = (content: string) => { |
334 | 362 | const parser = new DOMParser(); |
335 | 363 | const extractedElementTag = `<${parser.parseFromString(content, "text/html").body?.firstChild?.nodeName.toLowerCase()}>`; |
@@ -716,7 +744,13 @@ export const BlockersTable = ({ auditId, isShared }: BlockersTableProps) => { |
716 | 744 | }; |
717 | 745 |
|
718 | 746 | const handlePageSizeChange = (e: ChangeEvent<HTMLSelectElement>) => { |
719 | | - setPageSize(parseInt(e.target.value)); |
| 747 | + setSearchParams((prev) => { |
| 748 | + const next = new URLSearchParams(prev); |
| 749 | + const size = e.target.value; |
| 750 | + if (size === "10") next.delete("pageSize"); |
| 751 | + else next.set("pageSize", size); |
| 752 | + return next; |
| 753 | + }); |
720 | 754 | }; |
721 | 755 |
|
722 | 756 | const handleSortByUrl = () => { |
|
0 commit comments