mirror of
https://github.com/prymitive/karma
synced 2026-05-05 03:16:51 +00:00
fix(ui): rewrite Pagination with hooks
This commit is contained in:
committed by
Łukasz Mierzwa
parent
6fe85732b0
commit
1c4e8fc161
@@ -57,7 +57,6 @@ const LabelSetList = ({ alertStore, labelsList }) => {
|
||||
</div>
|
||||
<PageSelect
|
||||
totalPages={Math.ceil(labelsList.length / maxPerPage)}
|
||||
activePage={activePage}
|
||||
maxPerPage={maxPerPage}
|
||||
totalItemsCount={labelsList.length}
|
||||
setPageCallback={setActivePage}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { Component } from "react";
|
||||
import React, { useState, useCallback, useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { HotKeys } from "react-hotkeys";
|
||||
@@ -13,82 +13,90 @@ import { faAngleDoubleRight } from "@fortawesome/free-solid-svg-icons/faAngleDou
|
||||
|
||||
import { IsMobile } from "Common/Device";
|
||||
|
||||
class PageSelect extends Component {
|
||||
static propTypes = {
|
||||
totalPages: PropTypes.number.isRequired,
|
||||
activePage: PropTypes.number.isRequired,
|
||||
maxPerPage: PropTypes.number.isRequired,
|
||||
totalItemsCount: PropTypes.number.isRequired,
|
||||
setPageCallback: PropTypes.func.isRequired,
|
||||
};
|
||||
const PageSelect = ({
|
||||
totalItemsCount,
|
||||
totalPages,
|
||||
maxPerPage,
|
||||
initialPage,
|
||||
setPageCallback,
|
||||
}) => {
|
||||
const [activePage, setActivePage] = useState(initialPage);
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.HotKeysRef = React.createRef();
|
||||
}
|
||||
useEffect(() => {
|
||||
if (activePage > totalPages) {
|
||||
const page = Math.max(1, totalPages);
|
||||
setActivePage(page);
|
||||
setPageCallback(page);
|
||||
}
|
||||
}, [activePage, maxPerPage, totalPages, setPageCallback]);
|
||||
|
||||
onPageUp = () => {
|
||||
const { setPageCallback, activePage, totalPages } = this.props;
|
||||
setPageCallback(Math.min(activePage + 1, totalPages));
|
||||
};
|
||||
const onChange = useCallback(
|
||||
(page) => {
|
||||
setActivePage(page);
|
||||
setPageCallback(page);
|
||||
},
|
||||
[setPageCallback]
|
||||
);
|
||||
|
||||
onPageDown = () => {
|
||||
const { setPageCallback, activePage } = this.props;
|
||||
setPageCallback(Math.max(activePage - 1, 1));
|
||||
};
|
||||
const onPageUp = useCallback(() => {
|
||||
const page = Math.min(activePage + 1, totalPages);
|
||||
setActivePage(page);
|
||||
setPageCallback(page);
|
||||
}, [activePage, setPageCallback, totalPages]);
|
||||
|
||||
componentDidMount() {
|
||||
this.HotKeysRef.current.focus();
|
||||
}
|
||||
const onPageDown = useCallback(() => {
|
||||
const page = Math.max(activePage - 1, 1);
|
||||
setActivePage(page);
|
||||
setPageCallback(page);
|
||||
}, [activePage, setPageCallback]);
|
||||
|
||||
render() {
|
||||
const {
|
||||
totalItemsCount,
|
||||
totalPages,
|
||||
maxPerPage,
|
||||
activePage,
|
||||
setPageCallback,
|
||||
} = this.props;
|
||||
|
||||
const isMobile = IsMobile();
|
||||
|
||||
return (
|
||||
<HotKeys
|
||||
className="components-pagination"
|
||||
innerRef={this.HotKeysRef}
|
||||
keyMap={{
|
||||
onArrowLeft: "ArrowLeft",
|
||||
onArrowRight: "ArrowRight",
|
||||
}}
|
||||
handlers={{
|
||||
onArrowLeft: this.onPageDown,
|
||||
onArrowRight: this.onPageUp,
|
||||
}}
|
||||
>
|
||||
{totalItemsCount > maxPerPage ? (
|
||||
<div className="mt-3">
|
||||
<Pagination
|
||||
activePage={activePage}
|
||||
itemsCountPerPage={maxPerPage}
|
||||
totalItemsCount={totalItemsCount}
|
||||
pageRangeDisplayed={isMobile ? 3 : 5}
|
||||
onChange={setPageCallback}
|
||||
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>
|
||||
) : null}
|
||||
</HotKeys>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<HotKeys
|
||||
className="components-pagination"
|
||||
innerRef={(r) => r && r.focus()}
|
||||
keyMap={{
|
||||
onArrowLeft: "ArrowLeft",
|
||||
onArrowRight: "ArrowRight",
|
||||
}}
|
||||
handlers={{
|
||||
onArrowLeft: onPageDown,
|
||||
onArrowRight: onPageUp,
|
||||
}}
|
||||
allowChanges
|
||||
>
|
||||
{totalItemsCount > maxPerPage ? (
|
||||
<div className="mt-3">
|
||||
<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>
|
||||
) : null}
|
||||
</HotKeys>
|
||||
);
|
||||
};
|
||||
PageSelect.propTypes = {
|
||||
totalPages: PropTypes.number.isRequired,
|
||||
initialPage: PropTypes.number,
|
||||
maxPerPage: PropTypes.number.isRequired,
|
||||
totalItemsCount: PropTypes.number.isRequired,
|
||||
setPageCallback: PropTypes.func.isRequired,
|
||||
};
|
||||
PageSelect.defaultProps = {
|
||||
initialPage: 1,
|
||||
};
|
||||
|
||||
export { PageSelect };
|
||||
|
||||
@@ -26,7 +26,6 @@ describe("<PageSelect />", () => {
|
||||
const tree = mount(
|
||||
<PageSelect
|
||||
totalPages={4}
|
||||
activePage={1}
|
||||
maxPerPage={5}
|
||||
totalItemsCount={17}
|
||||
setPageCallback={setPageCallback}
|
||||
@@ -34,10 +33,6 @@ describe("<PageSelect />", () => {
|
||||
);
|
||||
tree.simulate("focus");
|
||||
|
||||
setPageCallback.mockImplementation((val) =>
|
||||
tree.setProps({ activePage: val })
|
||||
);
|
||||
|
||||
PressKey(tree, "ArrowRight", 39);
|
||||
expect(setPageCallback).toHaveBeenLastCalledWith(2);
|
||||
|
||||
@@ -68,7 +63,6 @@ describe("<PageSelect />", () => {
|
||||
const tree = mount(
|
||||
<PageSelect
|
||||
totalPages={7}
|
||||
activePage={1}
|
||||
maxPerPage={5}
|
||||
totalItemsCount={35}
|
||||
setPageCallback={jest.fn()}
|
||||
@@ -82,7 +76,6 @@ describe("<PageSelect />", () => {
|
||||
const tree = mount(
|
||||
<PageSelect
|
||||
totalPages={7}
|
||||
activePage={1}
|
||||
maxPerPage={5}
|
||||
totalItemsCount={35}
|
||||
setPageCallback={jest.fn()}
|
||||
@@ -90,4 +83,27 @@ describe("<PageSelect />", () => {
|
||||
);
|
||||
expect(tree.find(".page-link")).toHaveLength(5);
|
||||
});
|
||||
|
||||
it("resets page if activePage >= totalPages", () => {
|
||||
const setPageCallback = jest.fn();
|
||||
const tree = mount(
|
||||
<PageSelect
|
||||
initialPage={3}
|
||||
totalPages={7}
|
||||
maxPerPage={5}
|
||||
totalItemsCount={35}
|
||||
setPageCallback={setPageCallback}
|
||||
/>
|
||||
);
|
||||
expect(tree.find(".page-item").at(3).hasClass("active")).toBe(true);
|
||||
|
||||
tree.setProps({ totalPages: 2 });
|
||||
tree.update();
|
||||
expect(tree.find(".page-item").at(2).hasClass("active")).toBe(true);
|
||||
expect(setPageCallback).toHaveBeenLastCalledWith(2);
|
||||
|
||||
tree.setProps({ totalPages: 5 });
|
||||
tree.update();
|
||||
expect(tree.find(".page-item").at(2).hasClass("active")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -77,15 +77,6 @@ const Browser = ({
|
||||
{ deps: [currentTime] }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (response) {
|
||||
const totalPages = Math.ceil(response.length / maxPerPage);
|
||||
if (activePage > totalPages) {
|
||||
setActivePage(Math.max(1, totalPages));
|
||||
}
|
||||
}
|
||||
}, [activePage, maxPerPage, response]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setCurrentTime(Math.floor(Date.now() / 1000));
|
||||
@@ -168,7 +159,6 @@ const Browser = ({
|
||||
))}
|
||||
<PageSelect
|
||||
totalPages={Math.ceil(response.length / maxPerPage)}
|
||||
activePage={activePage}
|
||||
maxPerPage={maxPerPage}
|
||||
totalItemsCount={response.length}
|
||||
setPageCallback={setActivePage}
|
||||
|
||||
Reference in New Issue
Block a user