import React, { useEffect, useMemo, useRef, useState } from "react";
import {
Button,
ButtonGroup,
Dropdown,
Form,
InputGroup,
Overlay,
Popover,
} from "react-bootstrap";
import { FormattedMessage, FormattedNumber, useIntl } from "react-intl";
import useFocus from "src/utils/focus";
import { Icon } from "../Shared/Icon";
import { faCheck, faChevronDown } from "@fortawesome/free-solid-svg-icons";
import { useStopWheelScroll } from "src/utils/form";
const PageCount: React.FC<{
totalPages: number;
currentPage: number;
onChangePage: (page: number) => void;
}> = ({ totalPages, currentPage, onChangePage }) => {
const intl = useIntl();
const currentPageCtrl = useRef(null);
const [pageInput, pageFocus] = useFocus();
const [showSelectPage, setShowSelectPage] = useState(false);
useEffect(() => {
if (showSelectPage) {
// delaying the focus to the next execution loop so that rendering takes place first and stops the page from resetting.
setTimeout(() => {
pageFocus();
}, 0);
}
}, [showSelectPage, pageFocus]);
useStopWheelScroll(pageInput);
const pageOptions = useMemo(() => {
const maxPagesToShow = 10;
const min = Math.max(1, currentPage - maxPagesToShow / 2);
const max = Math.min(min + maxPagesToShow, totalPages);
const pages = [];
for (let i = min; i <= max; i++) {
pages.push(i);
}
return pages;
}, [totalPages, currentPage]);
function onCustomChangePage() {
const newPage = Number.parseInt(pageInput.current?.value ?? "0");
if (newPage) {
onChangePage(newPage);
}
setShowSelectPage(false);
}
return (
{pageOptions.map((s) => (
onChangePage(s)}
>
{s}
))}
setShowSelectPage(false)}
>
);
};
interface IPaginationProps {
itemsPerPage: number;
currentPage: number;
totalItems: number;
metadataByline?: React.ReactNode;
onChangePage: (page: number) => void;
}
interface IPaginationIndexProps {
itemsPerPage: number;
currentPage: number;
totalItems: number;
metadataByline?: React.ReactNode;
}
const minPagesForCompact = 4;
export const Pagination: React.FC = ({
itemsPerPage,
currentPage,
totalItems,
onChangePage,
}) => {
const intl = useIntl();
const totalPages = useMemo(
() => Math.ceil(totalItems / itemsPerPage),
[totalItems, itemsPerPage]
);
const pageButtons = useMemo(() => {
if (totalPages >= minPagesForCompact)
return (
);
const pages = [...Array(totalPages).keys()].map((i) => i + 1);
return pages.map((page: number) => (
));
}, [totalPages, currentPage, onChangePage]);
if (totalPages <= 1) return ;
return (
{pageButtons}
);
};
export const PaginationIndex: React.FC = ({
itemsPerPage,
currentPage,
totalItems,
metadataByline,
}) => {
const intl = useIntl();
// Build the pagination index string
const firstItemCount: number = Math.min(
(currentPage - 1) * itemsPerPage + 1,
totalItems
);
const lastItemCount: number = Math.min(
firstItemCount + (itemsPerPage - 1),
totalItems
);
const indexText: string = `${intl.formatNumber(
firstItemCount
)}-${intl.formatNumber(lastItemCount)} of ${intl.formatNumber(totalItems)}`;
return (
{indexText}
{metadataByline}
);
};