From d0421520c9077fb42aac767bdb3bc70866d06d84 Mon Sep 17 00:00:00 2001 From: Angela The Date: Mon, 27 May 2024 22:30:20 -0700 Subject: [PATCH] Add pagination to eCR Viewer homepage (#1889) * add pagination element and CSS class * update number of items per page, update snapshot tests, add pagination unit tests * fix spacing between table and pagination * update snapshot test --- .../ecr-viewer/src/app/ListEcrViewer.tsx | 37 +++++++++++++- .../tests/components/ListEcrViewer.test.tsx | 49 ++++++++++++++++++- .../__snapshots__/ListEcrViewer.test.tsx.snap | 24 ++++++++- .../ecr-viewer/src/styles/custom-styles.scss | 18 +++++++ 4 files changed, 124 insertions(+), 4 deletions(-) diff --git a/containers/ecr-viewer/src/app/ListEcrViewer.tsx b/containers/ecr-viewer/src/app/ListEcrViewer.tsx index 814f539832..e02159d217 100644 --- a/containers/ecr-viewer/src/app/ListEcrViewer.tsx +++ b/containers/ecr-viewer/src/app/ListEcrViewer.tsx @@ -1,5 +1,9 @@ +"use client"; + import { Table } from "@trussworks/react-uswds"; import { ListEcr } from "@/app/api/services/listEcrDataService"; +import { useState } from "react"; +import { Pagination } from "@trussworks/react-uswds"; interface ListEcrViewerProps { listFhirData: ListEcr; @@ -15,8 +19,24 @@ export default function ListECRViewer({ listFhirData, }: ListEcrViewerProps): JSX.Element { const header = ["eCR ID", "Stored Date"]; + const [currentPage, setCurrentPage] = useState(1); + const itemsPerPage = 25; + const totalPages = Math.ceil(listFhirData.length / itemsPerPage); + + const handlePageChange = (pageNumber: number) => { + setCurrentPage(pageNumber); + renderPage(pageNumber); + }; + + const renderPage = (pageNumber: number) => { + const startIndex = (pageNumber - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + const pageData = listFhirData.slice(startIndex, endIndex); + return renderListEcrTableData(pageData); + }; + return ( -
+
- {renderListEcrTableData(listFhirData)} + {renderPage(currentPage)}
+ handlePageChange(currentPage + 1)} + onClickPrevious={() => handlePageChange(currentPage - 1)} + onClickPageNumber={( + _event: React.MouseEvent, + page: number, + ) => { + handlePageChange(page); + }} + />
); } diff --git a/containers/ecr-viewer/src/app/tests/components/ListEcrViewer.test.tsx b/containers/ecr-viewer/src/app/tests/components/ListEcrViewer.test.tsx index d52b777487..64802b11b9 100644 --- a/containers/ecr-viewer/src/app/tests/components/ListEcrViewer.test.tsx +++ b/containers/ecr-viewer/src/app/tests/components/ListEcrViewer.test.tsx @@ -1,4 +1,4 @@ -import { render } from "@testing-library/react"; +import { fireEvent, render, screen } from "@testing-library/react"; import { axe } from "jest-axe"; import ListECRViewer from "@/app/ListEcrViewer"; @@ -28,3 +28,50 @@ describe("Home Page, ListECRViewer", () => { expect(await axe(container)).toHaveNoViolations(); }); }); + +describe("Pagination for home page", () => { + const listFhirData = Array.from({ length: 51 }, (_, i) => ({ + ecrId: `id-${i + 1}`, + dateModified: `2021-01-0${(i % 9) + 1}`, + })); + beforeEach(() => { + render(); + }); + + it("should render first page correctly", () => { + const rows = screen.getAllByRole("row"); + expect(rows).toHaveLength(26); // 25 data rows + 1 header row + }); + + it("should navigate to the next page correctly using the Next button", () => { + const nextButton = screen.getByTestId("pagination-next"); + fireEvent.click(nextButton); + + const rows = screen.getAllByRole("row"); + expect(rows).toHaveLength(26); + expect(screen.getByText("id-26")).toBeInTheDocument(); + expect(screen.getByText("id-50")).toBeInTheDocument(); + }); + + it("should navigate to the previous page correctly using the Previous button", () => { + const nextButton = screen.getByTestId("pagination-next"); + fireEvent.click(nextButton); // Must navigate past 1st page so Previous button can display + + const previousButton = screen.getByTestId("pagination-previous"); + fireEvent.click(previousButton); + + const rows = screen.getAllByRole("row"); + expect(rows).toHaveLength(26); + expect(screen.getByText("id-1")).toBeInTheDocument(); + expect(screen.getByText("id-25")).toBeInTheDocument(); + }); + + it("should navigate to a specific page correctly when clicking page button", () => { + const page3Button = screen.getByText("3", { selector: "button" }); + fireEvent.click(page3Button); + + const rows = screen.getAllByRole("row"); + expect(rows).toHaveLength(2); + expect(screen.getByText("id-51")).toBeInTheDocument(); + }); +}); diff --git a/containers/ecr-viewer/src/app/tests/components/__snapshots__/ListEcrViewer.test.tsx.snap b/containers/ecr-viewer/src/app/tests/components/__snapshots__/ListEcrViewer.test.tsx.snap index 52d1abc502..f8992b3146 100644 --- a/containers/ecr-viewer/src/app/tests/components/__snapshots__/ListEcrViewer.test.tsx.snap +++ b/containers/ecr-viewer/src/app/tests/components/__snapshots__/ListEcrViewer.test.tsx.snap @@ -3,7 +3,7 @@ exports[`Home Page, ListECRViewer should match snapshot 1`] = `
+
`; diff --git a/containers/ecr-viewer/src/styles/custom-styles.scss b/containers/ecr-viewer/src/styles/custom-styles.scss index 4c9a96e030..7de0890e34 100644 --- a/containers/ecr-viewer/src/styles/custom-styles.scss +++ b/containers/ecr-viewer/src/styles/custom-styles.scss @@ -199,6 +199,24 @@ td { font-weight: bold; } +.homepage-wrapper { + display: flex; + max-width: 1440px; + gap: 48px; + overflow: visible; + align-items: center; + flex-wrap: wrap; + flex-direction: column; + + .usa-table { + margin-bottom: 0 !important; + } + + .usa-pagination { + margin-top: 0 !important; + } +} + .main-container { display: flex; justify-content: center;