diff --git a/src/components/ArticleList/ArticleList.tsx b/src/components/ArticleList/ArticleList.tsx index 640d14348..93f6f7e64 100644 --- a/src/components/ArticleList/ArticleList.tsx +++ b/src/components/ArticleList/ArticleList.tsx @@ -1,10 +1,9 @@ import React from 'react' - +import { Pagination } from '@trussworks/react-uswds' import styles from './ArticleList.module.scss' import type { ArticleListItemRecord } from 'types' import { ArticleListItem } from 'components/ArticleListItem/ArticleListItem' -import Pagination from 'components/Pagination/Pagination' type ArticleListProps = { articles: ArticleListItemRecord[] diff --git a/src/components/Pagination/Pagination.test.tsx b/src/components/Pagination/Pagination.test.tsx deleted file mode 100644 index 8784ae38e..000000000 --- a/src/components/Pagination/Pagination.test.tsx +++ /dev/null @@ -1,281 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import { render, screen } from '@testing-library/react' -import React from 'react' - -import Pagination from './Pagination' - -describe('Pagination component', () => { - const testPages = 24 - const testThreePages = 3 - const testSevenPages = 7 - const testPathname = '/test-pathname' - - it('renders pagination for a list of pages', () => { - render( - - ) - expect(screen.getByRole('navigation')).toBeInTheDocument() - - expect(screen.getByLabelText('Previous page')).toHaveAttribute( - 'href', - `${testPathname}?page=9` - ) - expect(screen.getByLabelText('Page 1')).toHaveAttribute( - 'href', - `${testPathname}?page=1` - ) - expect(screen.getByLabelText('Page 9')).toHaveAttribute( - 'href', - `${testPathname}?page=9` - ) - expect(screen.getByLabelText('Page 10')).toHaveAttribute( - 'href', - `${testPathname}?page=10` - ) - expect(screen.getByLabelText('Page 10')).toHaveAttribute( - 'aria-current', - 'page' - ) - expect(screen.getByLabelText('Page 11')).toHaveAttribute( - 'href', - `${testPathname}?page=11` - ) - expect(screen.getByLabelText('Page 24')).toHaveAttribute( - 'href', - `${testPathname}?page=24` - ) - expect(screen.getByLabelText('Next page')).toHaveAttribute( - 'href', - `${testPathname}?page=11` - ) - }) - - it('only renders the maximum number of slots', () => { - render( - - ) - expect(screen.getAllByRole('listitem')).toHaveLength(7) // overflow slots don't count - }) - - it('renders pagination when the first page is current', () => { - render( - - ) - expect(screen.queryByLabelText('Previous page')).not.toBeInTheDocument() - expect(screen.queryByLabelText('Next page')).toBeInTheDocument() - expect(screen.getByLabelText('Page 1')).toHaveAttribute( - 'aria-current', - 'page' - ) - }) - - it('renders pagination when the last page is current', () => { - render( - - ) - expect(screen.queryByLabelText('Previous page')).toBeInTheDocument() - expect(screen.queryByLabelText('Next page')).not.toBeInTheDocument() - expect(screen.getByLabelText('Page 24')).toHaveAttribute( - 'aria-current', - 'page' - ) - }) - - it('renders overflow at the beginning and end when current page is in the middle', () => { - render( - - ) - expect(screen.getByLabelText('Previous page')).toHaveAttribute( - 'href', - `${testPathname}?page=9` - ) - expect(screen.getByLabelText('Page 1')).toHaveAttribute( - 'href', - `${testPathname}?page=1` - ) - expect(screen.getByLabelText('Page 9')).toHaveAttribute( - 'href', - `${testPathname}?page=9` - ) - expect(screen.getByLabelText('Page 10')).toHaveAttribute( - 'href', - `${testPathname}?page=10` - ) - expect(screen.getByLabelText('Page 10')).toHaveAttribute( - 'aria-current', - 'page' - ) - expect(screen.getByLabelText('Page 11')).toHaveAttribute( - 'href', - `${testPathname}?page=11` - ) - expect(screen.getByLabelText('Page 24')).toHaveAttribute( - 'href', - `${testPathname}?page=24` - ) - expect(screen.getByLabelText('Next page')).toHaveAttribute( - 'href', - `${testPathname}?page=11` - ) - expect(screen.getAllByText('…')).toHaveLength(2) - }) - - it('renders overflow at the end when at the beginning of the pages', () => { - render( - - ) - - expect(screen.getByLabelText('Previous page')).toHaveAttribute( - 'href', - `${testPathname}?page=2` - ) - expect(screen.getByLabelText('Page 1')).toHaveAttribute( - 'href', - `${testPathname}?page=1` - ) - expect(screen.getByLabelText('Page 2')).toHaveAttribute( - 'href', - `${testPathname}?page=2` - ) - expect(screen.getByLabelText('Page 3')).toHaveAttribute( - 'href', - `${testPathname}?page=3` - ) - expect(screen.getByLabelText('Page 3')).toHaveAttribute( - 'aria-current', - 'page' - ) - expect(screen.getByLabelText('Page 4')).toHaveAttribute( - 'href', - `${testPathname}?page=4` - ) - expect(screen.getByLabelText('Page 5')).toHaveAttribute( - 'href', - `${testPathname}?page=5` - ) - expect(screen.getByLabelText('Page 24')).toHaveAttribute( - 'href', - `${testPathname}?page=24` - ) - expect(screen.getByLabelText('Next page')).toHaveAttribute( - 'href', - `${testPathname}?page=4` - ) - expect(screen.getAllByText('…')).toHaveLength(1) - }) - - it('renders overflow at the beginning when at the end of the pages', () => { - render( - - ) - - expect(screen.getByLabelText('Previous page')).toHaveAttribute( - 'href', - `${testPathname}?page=20` - ) - expect(screen.getByLabelText('Page 1')).toHaveAttribute( - 'href', - `${testPathname}?page=1` - ) - expect(screen.getByLabelText('Page 20')).toHaveAttribute( - 'href', - `${testPathname}?page=20` - ) - expect(screen.getByLabelText('Page 21')).toHaveAttribute( - 'href', - `${testPathname}?page=21` - ) - expect(screen.getByLabelText('Page 21')).toHaveAttribute( - 'aria-current', - 'page' - ) - expect(screen.getByLabelText('Page 22')).toHaveAttribute( - 'href', - `${testPathname}?page=22` - ) - expect(screen.getByLabelText('Page 23')).toHaveAttribute( - 'href', - `${testPathname}?page=23` - ) - expect(screen.getByLabelText('Page 24')).toHaveAttribute( - 'href', - `${testPathname}?page=24` - ) - expect(screen.getByLabelText('Next page')).toHaveAttribute( - 'href', - `${testPathname}?page=22` - ) - expect(screen.getAllByText('…')).toHaveLength(1) - }) - - describe('for fewer pages than the max slots', () => { - it('renders pagination with no overflow', () => { - render( - - ) - expect(screen.getAllByRole('listitem')).toHaveLength(5) - expect(screen.queryAllByText('…')).toHaveLength(0) - }) - - it('renders pagination with no overflow', () => { - render( - - ) - expect(screen.getAllByRole('listitem')).toHaveLength(9) - expect(screen.queryAllByText('…')).toHaveLength(0) - }) - }) - - describe('with a custom slot number passed in', () => { - it('only renders the maximum number of slots', () => { - render( - - ) - expect(screen.getAllByRole('listitem')).toHaveLength(10) - }) - }) -}) diff --git a/src/components/Pagination/Pagination.tsx b/src/components/Pagination/Pagination.tsx deleted file mode 100644 index a730dab90..000000000 --- a/src/components/Pagination/Pagination.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import React from 'react' -import classnames from 'classnames' -import { Icon } from '@trussworks/react-uswds' -import LinkTo from 'components/util/LinkTo/LinkTo' - -type PaginationProps = { - pathname: string // pathname of results page - totalPages: number // total items divided by items per page - currentPage: number // current page number (starting at 1) - maxSlots?: number // number of pagination "slots" -} - -const PaginationPage = ({ - page, - isCurrent, - pathname, -}: { - pathname: string - page: number - isCurrent?: boolean -}) => { - const linkClasses = classnames('usa-pagination__button', { - 'usa-current': isCurrent, - }) - - return ( -
  • - - {page} - -
  • - ) -} - -const PaginationOverflow = () => ( -
  • - -
  • -) - -const Pagination = ({ - pathname, - totalPages, - currentPage, - className, - maxSlots = 7, - ...props -}: PaginationProps & JSX.IntrinsicElements['nav']) => { - const navClasses = classnames('usa-pagination', className) - - const isOnFirstPage = currentPage === 1 - const isOnLastPage = currentPage === totalPages - - const showOverflow = totalPages > maxSlots // If more pages than slots, use overflow indicator(s) - - const middleSlot = Math.round(maxSlots / 2) // 4 if maxSlots is 7 - const showPrevOverflow = showOverflow && currentPage > middleSlot - const showNextOverflow = - showOverflow && totalPages - currentPage >= middleSlot - - // Assemble array of page numbers to be shown - const currentPageRange: Array = showOverflow - ? [currentPage] - : Array.from({ length: totalPages }).map((_, i) => i + 1) - - if (showOverflow) { - // Determine range of pages to show based on current page & number of slots - // Follows logic described at: https://designsystem.digital.gov/components/pagination/ - const prevSlots = isOnFirstPage ? 0 : showPrevOverflow ? 2 : 1 // first page + prev overflow - const nextSlots = isOnLastPage ? 0 : showNextOverflow ? 2 : 1 // next overflow + last page - const pageRangeSize = maxSlots - 1 - (prevSlots + nextSlots) // remaining slots to show (minus one for the current page) - - // Determine how many slots we have before/after the current page - let currentPageBeforeSize = 0 - let currentPageAfterSize = 0 - if (showPrevOverflow && showNextOverflow) { - // We are in the middle of the set, there will be overflow (...) at both the beginning & end - // Ex: [1] [...] [9] [10] [11] [...] [24] - currentPageBeforeSize = Math.round((pageRangeSize - 1) / 2) - currentPageAfterSize = pageRangeSize - currentPageBeforeSize - } else if (showPrevOverflow) { - // We are in the end of the set, there will be overflow (...) at the beginning - // Ex: [1] [...] [20] [21] [22] [23] [24] - currentPageAfterSize = totalPages - currentPage - 1 // current & last - currentPageAfterSize = currentPageAfterSize < 0 ? 0 : currentPageAfterSize - currentPageBeforeSize = pageRangeSize - currentPageAfterSize - } else if (showNextOverflow) { - // We are in the beginning of the set, there will be overflow (...) at the end - // Ex: [1] [2] [3] [4] [5] [...] [24] - currentPageBeforeSize = currentPage - 2 // first & current - currentPageBeforeSize = - currentPageBeforeSize < 0 ? 0 : currentPageBeforeSize - currentPageAfterSize = pageRangeSize - currentPageBeforeSize - } - - // Populate the remaining slots - let counter = 1 - while (currentPageBeforeSize > 0) { - // Add previous pages before the current page - currentPageRange.unshift(currentPage - counter) - counter++ - currentPageBeforeSize-- - } - - counter = 1 - while (currentPageAfterSize > 0) { - // Add subsequent pages after the current page - currentPageRange.push(currentPage + counter) - counter++ - currentPageAfterSize-- - } - - // Add prev/next overflow indicators, and first/last pages as needed - if (showPrevOverflow) currentPageRange.unshift('overflow') - if (currentPage !== 1) currentPageRange.unshift(1) - if (showNextOverflow) currentPageRange.push('overflow') - if (currentPage !== totalPages) currentPageRange.push(totalPages) - } - - const prevPage = !isOnFirstPage && currentPage - 1 - const nextPage = !isOnLastPage && currentPage + 1 - - return ( - - ) -} - -export default Pagination diff --git a/src/operations/cms/queries/getPortalNewsArticles.ts b/src/operations/cms/queries/getPortalNewsArticles.ts index 6bce48b84..358f9a7aa 100644 --- a/src/operations/cms/queries/getPortalNewsArticles.ts +++ b/src/operations/cms/queries/getPortalNewsArticles.ts @@ -19,6 +19,8 @@ export const GET_PORTAL_NEWS_ARTICLES = gql` export const GET_ARTICLES_COUNT = gql` query GetArticlesCount { - articlesCount + articlesCount( + where: { status: { equals: Published }, category: { equals: ORBITBlog } } + ) } ` diff --git a/src/pages/about-us/orbit-blog.tsx b/src/pages/about-us/orbit-blog.tsx index 6d0f748b7..a97b99003 100644 --- a/src/pages/about-us/orbit-blog.tsx +++ b/src/pages/about-us/orbit-blog.tsx @@ -7,7 +7,10 @@ import type { ArticleListItemRecord } from 'types' import Loader from 'components/Loader/Loader' import { useUser } from 'hooks/useUser' import { withPageLayout } from 'layout/DefaultLayout/PageLayout' -import { GET_PORTAL_NEWS_ARTICLES } from 'operations/cms/queries/getPortalNewsArticles' +import { + GET_PORTAL_NEWS_ARTICLES, + GET_ARTICLES_COUNT, +} from 'operations/cms/queries/getPortalNewsArticles' import { ArticleList } from 'components/ArticleList/ArticleList' import styles from 'styles/pages/news.module.scss' import BreadcrumbNav from 'components/BreadcrumbNav/BreadcrumbNav' @@ -76,11 +79,7 @@ export const getServerSideProps: GetServerSideProps = async ( const { data: { articlesCount }, } = await client.query({ - query: gql` - query articlesCount { - articlesCount - } - `, + query: GET_ARTICLES_COUNT, }) // Calculate total pages // If NaN, return 1 page diff --git a/src/components/Pagination/Pagination.stories.tsx b/src/stories/Pagination.stories.tsx similarity index 97% rename from src/components/Pagination/Pagination.stories.tsx rename to src/stories/Pagination.stories.tsx index 6946bb93c..e47e5acd9 100644 --- a/src/components/Pagination/Pagination.stories.tsx +++ b/src/stories/Pagination.stories.tsx @@ -1,6 +1,6 @@ import React from 'react' import { ComponentMeta, ComponentStory } from '@storybook/react' -import Pagination from './Pagination' +import { Pagination } from '@trussworks/react-uswds' export default { title: 'Base/Pagination',