fix(ui): use a custom pagination component

This commit is contained in:
Łukasz Mierzwa
2021-12-29 11:14:31 +00:00
committed by Łukasz Mierzwa
parent c454601b3b
commit 9171a529ca
6 changed files with 702 additions and 574 deletions

1001
ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -43,7 +43,6 @@
"react-hotkeys-hook": "3.4.4",
"react-idle-timer": "4.6.4",
"react-intersection-observer": "8.33.1",
"react-js-pagination": "3.0.3",
"react-json-pretty": "2.2.0",
"react-linkify": "0.2.2",
"react-media-hook": "0.4.9",
@@ -76,7 +75,6 @@
"@types/qs": "6.9.7",
"@types/react": "17.0.38",
"@types/react-dom": "17.0.11",
"@types/react-js-pagination": "3.0.4",
"@types/semver": "7.3.9",
"@wojtekmaj/enzyme-adapter-react-17": "0.6.6",
"diffable-html": "5.0.0",

View File

@@ -58,6 +58,54 @@ describe("<PageSelect />", () => {
expect(setPageCallback).toHaveBeenLastCalledWith(1);
});
it("calls setPageCallback on button press", () => {
const setPageCallback = jest.fn();
const tree = mount(
<PageSelect
totalPages={15}
maxPerPage={5}
totalItemsCount={15 * 5}
setPageCallback={setPageCallback}
/>
);
tree.simulate("focus");
for (const elem of [
{ index: 0, page: 1, label: "" }, // <<
{ index: 1, page: 1, label: "" }, // <
{ index: 2, page: 1, label: "1" }, // <<12345>> -> <<12345>>
{ index: 3, page: 2, label: "2" }, // <<12345>> -> <<12345>>
{ index: 4, page: 3, label: "3" }, // <<12345>> -> <<12345>>
{ index: 5, page: 4, label: "4" }, // <<12345>> -> <<23456>>
{ index: 4, page: 4, label: "4" }, // <<23456>> -> <<23456>>
{ index: 0, page: 1, label: "" }, // <<23456>> -> <<12345>>
{ index: 6, page: 5, label: "5" }, // <<12345>> -> <<34567>>
{ index: 7, page: 6, label: "" }, // <<34567>> -> <<45678>>
{ index: 1, page: 5, label: "" }, // <<34567>> -> <<23456>>
{ index: 8, page: 15, label: "" }, // <<23456>> -> <<end>>
]) {
expect(tree.find("button.page-link").at(elem.index).text()).toBe(
elem.label
);
tree.find("button.page-link").at(elem.index).simulate("click");
expect(setPageCallback).toHaveBeenLastCalledWith(elem.page);
}
});
it("doesn't render anything if totalItemsCount <= maxPerPage", () => {
global.innerWidth = 1024;
const tree = mount(
<PageSelect
totalPages={1}
maxPerPage={5}
totalItemsCount={5}
setPageCallback={jest.fn()}
/>
);
expect(tree.find(".page-link")).toHaveLength(0);
});
it("renders 5 page range on desktop", () => {
global.innerWidth = 1024;
const tree = mount(

View File

@@ -2,8 +2,6 @@ import { useState, useEffect, FC } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import Pagination from "react-js-pagination";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons/faAngleLeft";
import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight";
@@ -27,6 +25,7 @@ const PageSelect: FC<{
initialPage = 1,
setPageCallback,
}) => {
const [pages, setPages] = useState<number[]>([]);
const [activePage, setActivePage] = useState<number>(initialPage);
const onChange = (page: number) => {
@@ -34,13 +33,30 @@ const PageSelect: FC<{
setPageCallback(page);
};
useEffect(() => {
const allPages = Array.from(Array(totalPages).keys()).map((k) => k + 1);
const gap = IsMobile() ? 1 : 2;
let minPage = activePage - gap;
let maxPage = activePage + gap;
if (minPage < 1) {
maxPage = Math.min(maxPage + -minPage + 1, totalPages);
minPage = 1;
}
if (maxPage > totalPages) {
minPage = Math.max(1, minPage - (maxPage - totalPages));
maxPage = totalPages;
}
setPages(allPages.slice(minPage - 1, maxPage));
}, [activePage, totalPages]);
useEffect(() => {
if (activePage > totalPages) {
const page = Math.max(1, totalPages);
setActivePage(page);
setPageCallback(page);
}
}, [activePage, maxPerPage, totalPages, setPageCallback]);
}, [activePage, totalPages, setPageCallback]);
useHotkeys(
"left",
@@ -67,25 +83,65 @@ const PageSelect: FC<{
return (
<div className="components-pagination">
{totalItemsCount > maxPerPage ? (
<div className="mt-3">
<Pagination
<ul className="pagination justify-content-center mt-3">
{totalPages >= 10 ? (
<li className={`page-item ${activePage > 1 ? "" : "disabled"}`}>
<button className="page-link" onClick={() => onChange(1)}>
<FontAwesomeIcon icon={faAngleDoubleLeft} />
</button>
</li>
) : null}
<li className={`page-item ${activePage > 1 ? "" : "disabled"}`}>
<button
className="page-link"
onClick={() => onChange(Math.max(1, activePage - 1))}
>
<FontAwesomeIcon icon={faAngleLeft} />
</button>
</li>
{pages.map((page) => (
<li
key={page}
className={`page-item ${
page === activePage ? "active font-weight-bold" : ""
}`}
>
<button className="page-link" onClick={() => onChange(page)}>
{page}
</button>
</li>
))}
<li
className={`page-item ${activePage < totalPages ? "" : "disabled"}`}
>
<button
className="page-link"
onClick={() => onChange(Math.min(activePage + 1, totalPages))}
>
<FontAwesomeIcon icon={faAngleRight} />
</button>
</li>
{totalPages >= 10 ? (
<li
className={`page-item ${
activePage < totalPages ? "" : "disabled"
}`}
>
<button
className="page-link"
onClick={() => onChange(totalPages)}
>
<FontAwesomeIcon icon={faAngleDoubleRight} />
</button>
</li>
) : null}
{/* <Pagination
activePage={activePage}
itemsCountPerPage={maxPerPage}
totalItemsCount={totalItemsCount}
pageRangeDisplayed={IsMobile() ? 3 : 5}
onChange={onChange}
hideFirstLastPages={totalPages < 10}
innerClass="pagination justify-content-center"
itemClass="page-item"
linkClass="page-link"
activeClass="active"
activeLinkClass="font-weight-bold"
prevPageText={<FontAwesomeIcon icon={faAngleLeft} />}
nextPageText={<FontAwesomeIcon icon={faAngleRight} />}
firstPageText={<FontAwesomeIcon icon={faAngleDoubleLeft} />}
lastPageText={<FontAwesomeIcon icon={faAngleDoubleRight} />}
/>
</div>
/> */}
</ul>
) : null}
</div>
);

View File

@@ -12,85 +12,63 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
</ul>
</div>
<div class=\\"components-pagination\\">
<div class=\\"mt-3\\">
<ul class=\\"pagination justify-content-center\\">
<li class=\\"page-item disabled\\">
<a
class=\\"page-link\\"
href=\\"#\\"
aria-label=\\"Go to previous page\\"
<ul class=\\"pagination justify-content-center mt-3\\">
<li class=\\"page-item disabled\\">
<button class=\\"page-link\\">
<svg
aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"angle-left\\"
class=\\"svg-inline--fa fa-angle-left fa-w-8 \\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 256 512\\"
>
<svg
aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"angle-left\\"
class=\\"svg-inline--fa fa-angle-left fa-w-8 \\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 256 512\\"
<path
fill=\\"currentColor\\"
d=\\"M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z\\"
>
<path
fill=\\"currentColor\\"
d=\\"M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z\\"
>
</path>
</svg>
</a>
</li>
<li class=\\"page-item active\\">
<a
class=\\"page-link font-weight-bold\\"
href=\\"#\\"
aria-label=\\"Go to page number 1\\"
</path>
</svg>
</button>
</li>
<li class=\\"page-item active font-weight-bold\\">
<button class=\\"page-link\\">
1
</button>
</li>
<li class=\\"page-item \\">
<button class=\\"page-link\\">
2
</button>
</li>
<li class=\\"page-item \\">
<button class=\\"page-link\\">
3
</button>
</li>
<li class=\\"page-item \\">
<button class=\\"page-link\\">
<svg
aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"angle-right\\"
class=\\"svg-inline--fa fa-angle-right fa-w-8 \\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 256 512\\"
>
1
</a>
</li>
<li class=\\"page-item\\">
<a
class=\\"page-link\\"
href=\\"#\\"
aria-label=\\"Go to page number 2\\"
>
2
</a>
</li>
<li class=\\"page-item\\">
<a
class=\\"page-link\\"
href=\\"#\\"
aria-label=\\"Go to page number 3\\"
>
3
</a>
</li>
<li class=\\"page-item\\">
<a
class=\\"page-link\\"
href=\\"#\\"
aria-label=\\"Go to next page\\"
>
<svg
aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"angle-right\\"
class=\\"svg-inline--fa fa-angle-right fa-w-8 \\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 256 512\\"
<path
fill=\\"currentColor\\"
d=\\"M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z\\"
>
<path
fill=\\"currentColor\\"
d=\\"M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z\\"
>
</path>
</svg>
</a>
</li>
</ul>
</div>
</path>
</svg>
</button>
</li>
</ul>
</div>
</div>
</div>

View File

@@ -1,3 +1,8 @@
.components-pagination:focus {
outline: none;
}
button.page-link:focus {
color: $pagination-hover-color;
background-color: $pagination-hover-bg;
}