223 lines
5.5 KiB
TypeScript
223 lines
5.5 KiB
TypeScript
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
import { FC } from 'react';
|
|
import { Pagination } from 'react-bootstrap';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useSearchParams, useNavigate, useLocation } from 'react-router-dom';
|
|
|
|
import { floppyNavigation } from '@/utils';
|
|
|
|
interface Props {
|
|
currentPage: number;
|
|
pageSize: number;
|
|
totalSize: number;
|
|
pathname?: string;
|
|
}
|
|
|
|
interface PageItemProps {
|
|
page: number;
|
|
currentPage: number;
|
|
path: string;
|
|
}
|
|
|
|
const pageArr = [
|
|
{
|
|
href: '1',
|
|
page: 1,
|
|
},
|
|
{
|
|
href: '#!',
|
|
page: 2,
|
|
},
|
|
{
|
|
href: '#!',
|
|
page: 3,
|
|
},
|
|
{
|
|
href: '#!',
|
|
page: 4,
|
|
},
|
|
{
|
|
href: '#!',
|
|
page: 5,
|
|
},
|
|
];
|
|
|
|
const PageItem = ({ page, currentPage, path }: PageItemProps) => {
|
|
const navigate = useNavigate();
|
|
return (
|
|
<Pagination.Item
|
|
active={currentPage === page}
|
|
href={path}
|
|
onClick={(e) => {
|
|
if (floppyNavigation.shouldProcessLinkClick(e)) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
navigate(path);
|
|
}
|
|
}}>
|
|
{page}
|
|
</Pagination.Item>
|
|
);
|
|
};
|
|
|
|
const Index: FC<Props> = ({
|
|
currentPage = 1,
|
|
pageSize = 15,
|
|
totalSize = 0,
|
|
pathname = '',
|
|
}) => {
|
|
const { t } = useTranslation('translation', { keyPrefix: 'pagination' });
|
|
const location = useLocation();
|
|
if (!pathname) {
|
|
pathname = location.pathname;
|
|
}
|
|
const [searchParams] = useSearchParams();
|
|
const navigate = useNavigate();
|
|
const totalPage = Math.ceil(totalSize / pageSize);
|
|
const realPage = currentPage > totalPage ? totalPage : currentPage;
|
|
|
|
const mapPage = pageArr.filter((i) => i.page <= totalPage);
|
|
|
|
if (totalPage <= 1) {
|
|
return null;
|
|
}
|
|
|
|
const handleParams = (pageNum): string => {
|
|
searchParams.set('page', String(pageNum));
|
|
const searchStr = searchParams.toString();
|
|
return `${pathname}?${searchStr}`;
|
|
};
|
|
return (
|
|
<Pagination size="sm" className="d-inline-flex mb-0">
|
|
{currentPage > 1 && (
|
|
<Pagination.Prev
|
|
href={handleParams(currentPage - 1)}
|
|
onClick={(e) => {
|
|
if (floppyNavigation.shouldProcessLinkClick(e)) {
|
|
e.preventDefault();
|
|
navigate(handleParams(currentPage - 1));
|
|
}
|
|
}}>
|
|
{t('prev')}
|
|
</Pagination.Prev>
|
|
)}
|
|
{currentPage >= 1 && currentPage <= 4 && (
|
|
<>
|
|
{mapPage.map((item) => {
|
|
return (
|
|
<PageItem
|
|
key={item.page}
|
|
page={item.page}
|
|
currentPage={currentPage}
|
|
path={handleParams(item.page)}
|
|
/>
|
|
);
|
|
})}
|
|
</>
|
|
)}
|
|
{currentPage === 4 && totalPage > 6 && (
|
|
<PageItem
|
|
key="page6"
|
|
page={6}
|
|
currentPage={currentPage}
|
|
path={handleParams(6)}
|
|
/>
|
|
)}
|
|
|
|
{currentPage > 4 && (
|
|
<>
|
|
<PageItem
|
|
key="first"
|
|
page={1}
|
|
currentPage={currentPage}
|
|
path={handleParams(1)}
|
|
/>
|
|
|
|
<Pagination.Ellipsis className="pe-none" />
|
|
</>
|
|
)}
|
|
{currentPage >= 5 && (
|
|
<>
|
|
<PageItem
|
|
key={realPage - 2}
|
|
page={realPage - 2}
|
|
currentPage={currentPage}
|
|
path={handleParams(realPage - 2)}
|
|
/>
|
|
<PageItem
|
|
key={realPage - 1}
|
|
page={realPage - 1}
|
|
currentPage={currentPage}
|
|
path={handleParams(realPage - 1)}
|
|
/>
|
|
</>
|
|
)}
|
|
|
|
{currentPage > totalPage && (
|
|
<PageItem
|
|
key={realPage}
|
|
page={realPage}
|
|
currentPage={currentPage}
|
|
path={handleParams(realPage)}
|
|
/>
|
|
)}
|
|
|
|
{currentPage >= 5 &&
|
|
totalPage >= currentPage &&
|
|
new Array(
|
|
totalPage <= 3
|
|
? totalPage - currentPage + 1
|
|
: Math.min(totalPage - currentPage + 1, 3),
|
|
)
|
|
.fill('')
|
|
.map((v, i) => {
|
|
return (
|
|
<PageItem
|
|
key={`${currentPage + i}`}
|
|
page={currentPage + i}
|
|
currentPage={currentPage}
|
|
path={handleParams(currentPage + i)}
|
|
/>
|
|
);
|
|
})}
|
|
{totalPage > 5 && realPage + 2 < totalPage && (
|
|
<Pagination.Ellipsis className="pe-none" />
|
|
)}
|
|
|
|
{totalPage > 0 && currentPage < totalPage && (
|
|
<Pagination.Next
|
|
disabled={currentPage === totalPage}
|
|
href={handleParams(currentPage + 1)}
|
|
onClick={(e) => {
|
|
if (floppyNavigation.shouldProcessLinkClick(e)) {
|
|
e.preventDefault();
|
|
navigate(handleParams(currentPage + 1));
|
|
}
|
|
}}>
|
|
{t('next')}
|
|
</Pagination.Next>
|
|
)}
|
|
</Pagination>
|
|
);
|
|
};
|
|
|
|
export default Index;
|