Extended ShortUrlsPaginator so that it allows appending current query string

This commit is contained in:
Alejandro Celaya 2021-11-08 22:13:37 +01:00
parent a2421ee2d3
commit 3bc5b4c154
2 changed files with 53 additions and 29 deletions

View file

@ -1,15 +1,24 @@
import { Link } from 'react-router-dom';
import { Pagination, PaginationItem, PaginationLink } from 'reactstrap';
import { pageIsEllipsis, keyForPage, progressivePagination, prettifyPageNumber } from '../utils/helpers/pagination';
import {
pageIsEllipsis,
keyForPage,
progressivePagination,
prettifyPageNumber,
NumberOrEllipsis,
} from '../utils/helpers/pagination';
import { ShlinkPaginator } from '../api/types';
interface PaginatorProps {
paginator?: ShlinkPaginator;
serverId: string;
currentQueryString?: string;
}
const Paginator = ({ paginator, serverId }: PaginatorProps) => {
const Paginator = ({ paginator, serverId, currentQueryString = '' }: PaginatorProps) => {
const { currentPage = 0, pagesCount = 0 } = paginator ?? {};
const urlForPage = (pageNumber: NumberOrEllipsis) =>
`/server/${serverId}/list-short-urls/${pageNumber}${currentQueryString}`;
if (pagesCount <= 1) {
return null;
@ -22,10 +31,7 @@ const Paginator = ({ paginator, serverId }: PaginatorProps) => {
disabled={pageIsEllipsis(pageNumber)}
active={currentPage === pageNumber}
>
<PaginationLink
tag={Link}
to={`/server/${serverId}/list-short-urls/${pageNumber}`}
>
<PaginationLink tag={Link} to={urlForPage(pageNumber)}>
{prettifyPageNumber(pageNumber)}
</PaginationLink>
</PaginationItem>
@ -34,19 +40,11 @@ const Paginator = ({ paginator, serverId }: PaginatorProps) => {
return (
<Pagination className="sticky-card-paginator" listClassName="flex-wrap justify-content-center mb-0">
<PaginationItem disabled={currentPage === 1}>
<PaginationLink
previous
tag={Link}
to={`/server/${serverId}/list-short-urls/${currentPage - 1}`}
/>
<PaginationLink previous tag={Link} to={urlForPage(currentPage - 1)} />
</PaginationItem>
{renderPages()}
<PaginationItem disabled={currentPage >= pagesCount}>
<PaginationLink
next
tag={Link}
to={`/server/${serverId}/list-short-urls/${currentPage + 1}`}
/>
<PaginationLink next tag={Link} to={urlForPage(currentPage + 1)} />
</PaginationItem>
</Pagination>
);

View file

@ -1,28 +1,54 @@
import { shallow, ShallowWrapper } from 'enzyme';
import { PaginationItem } from 'reactstrap';
import { PaginationItem, PaginationLink } from 'reactstrap';
import { Mock } from 'ts-mockery';
import Paginator from '../../src/short-urls/Paginator';
import { ShlinkPaginator } from '../../src/api/types';
import { ELLIPSIS } from '../../src/utils/helpers/pagination';
describe('<Paginator />', () => {
let wrapper: ShallowWrapper;
const buildPaginator = (pagesCount?: number) => Mock.of<ShlinkPaginator>({ pagesCount, currentPage: 1 });
afterEach(() => wrapper?.unmount());
it('renders nothing if the number of pages is below 2', () => {
wrapper = shallow(<Paginator serverId="abc123" />);
it.each([
[ undefined ],
[ buildPaginator() ],
[ buildPaginator(0) ],
[ buildPaginator(1) ],
])('renders nothing if the number of pages is below 2', (paginator) => {
wrapper = shallow(<Paginator serverId="abc123" paginator={paginator} />);
expect(wrapper.text()).toEqual('');
});
it('renders previous, next and the list of pages', () => {
const paginator = {
currentPage: 1,
pagesCount: 5,
totalItems: 10,
};
const extraPagesPrevNext = 2;
const expectedItems = paginator.pagesCount + extraPagesPrevNext;
it.each([
[ buildPaginator(2), 4, 0 ],
[ buildPaginator(3), 5, 0 ],
[ buildPaginator(4), 6, 0 ],
[ buildPaginator(5), 7, 1 ],
[ buildPaginator(6), 7, 1 ],
[ buildPaginator(23), 7, 1 ],
])('renders previous, next and the list of pages, with ellipses when expected', (
paginator,
expectedPages,
expectedEllipsis,
) => {
wrapper = shallow(<Paginator serverId="abc123" paginator={paginator} />);
const items = wrapper.find(PaginationItem);
const ellipsis = items.filterWhere((item) => item.find(PaginationLink).prop('children') === ELLIPSIS);
expect(wrapper.find(PaginationItem)).toHaveLength(expectedItems);
expect(items).toHaveLength(expectedPages);
expect(ellipsis).toHaveLength(expectedEllipsis);
});
it('appends query string to all pages', () => {
const paginator = buildPaginator(3);
const currentQueryString = '?foo=bar';
wrapper = shallow(<Paginator serverId="abc123" paginator={paginator} currentQueryString={currentQueryString} />);
const links = wrapper.find(PaginationLink);
expect(links).toHaveLength(5);
links.forEach((link) => expect(link.prop('to')).toContain(currentQueryString));
});
});