224 lines
8.8 KiB
JavaScript
224 lines
8.8 KiB
JavaScript
import React, { useState, useEffect, useRef } from "react";
|
|
import { LeftOutlined, RightOutlined } from "@ant-design/icons";
|
|
import classNames from "classnames";
|
|
import Style from "./index.module.less";
|
|
import { isInteger } from "lodash";
|
|
import Pager from './pager';
|
|
import Options from 'rc-pagination/es/Options';
|
|
import zhCN from 'rc-pagination/es/locale/zh_CN';
|
|
import Select from 'antd/es/select';
|
|
import 'rc-pagination/assets/index.css';
|
|
function calculatePage(p, pageSize, total) {
|
|
const _pageSize = typeof p === 'undefined' ? pageSize : p;
|
|
return Math.floor((total - 1) / _pageSize) + 1;
|
|
}
|
|
const MiniSelect = (props) => <Select {...props} showSearch size="small"/>;
|
|
const MiddleSelect = (props) => <Select {...props} showSearch size="middle"/>;
|
|
MiniSelect.Option = Select.Option;
|
|
MiddleSelect.Option = Select.Option;
|
|
export default function Render(props) {
|
|
const { style, className, oakPagination, oakFullpath, newTotal, showQuickJumper, showSizeChanger, size, showTotal, showTitle, } = props.data;
|
|
const { t, setPageSize, setCurrentPage } = props.methods;
|
|
const { pageSize = 0, total = 0, currentPage = 1, more, count, getTotal } = oakPagination || {};
|
|
const paginationRef = useRef(null);
|
|
const [internalInputVal, setInternalInputVal] = useState(currentPage);
|
|
useEffect(() => {
|
|
setInternalInputVal(currentPage);
|
|
}, [currentPage]);
|
|
if (!oakPagination) {
|
|
return null;
|
|
}
|
|
if (!total) {
|
|
return null;
|
|
}
|
|
const prefixCls = 'rc-pagination';
|
|
const selectPrefixCls = 'rc-select';
|
|
const hasPrev = currentPage > 1;
|
|
const hasNext = currentPage < calculatePage(undefined, pageSize, newTotal);
|
|
const allPages = calculatePage(undefined, pageSize, newTotal);
|
|
const prevPage = currentPage - 1 > 0 ? currentPage - 1 : 0;
|
|
const nextPage = currentPage + 1 < allPages ? currentPage + 1 : allPages;
|
|
const itemRender = (_, type, originalElement) => {
|
|
if (type === "prev") {
|
|
return (<a>
|
|
<LeftOutlined />
|
|
</a>);
|
|
}
|
|
if (type === "next") {
|
|
return (<a style={{
|
|
cursor: hasNext ? "pointer" : "not-allowed",
|
|
color: hasNext ? "#006cb7" : "rgba(0, 0, 0, 0.25)",
|
|
}} onClick={hasNext ? () => {
|
|
if (currentPage) {
|
|
setCurrentPage(currentPage + 1);
|
|
}
|
|
} : undefined}>
|
|
<RightOutlined />
|
|
</a>);
|
|
}
|
|
return originalElement;
|
|
};
|
|
function isValid(page) {
|
|
return isInteger(page) && page !== currentPage && isInteger(newTotal) && newTotal > 0;
|
|
}
|
|
function handleChange(page) {
|
|
if (isValid(page)) {
|
|
const currentPage = calculatePage(undefined, pageSize, newTotal);
|
|
let newPage = page;
|
|
if (page > currentPage) {
|
|
newPage = currentPage;
|
|
}
|
|
else if (page < 1) {
|
|
newPage = 1;
|
|
}
|
|
if (newPage !== internalInputVal) {
|
|
setInternalInputVal(newPage);
|
|
}
|
|
setCurrentPage(newPage);
|
|
return newPage;
|
|
}
|
|
return currentPage;
|
|
}
|
|
//总条数
|
|
const totalText = showTotal ? (<li className={Style[`${prefixCls}-total-text`]}>
|
|
{showTotal(newTotal, [
|
|
total === 0 ? 0 : newTotal,
|
|
currentPage * pageSize > newTotal ? newTotal : currentPage * pageSize,
|
|
])}
|
|
</li>) : (<li className={Style[`${prefixCls}-total-text`]}>
|
|
{/* 共 {newTotal >= total! ? (more ? newTotal + '+' : (currentPage! - 1) * pageSize! + count!) : total} 条 */}
|
|
共 {(newTotal > total ? (more ? (newTotal - pageSize) + '+' : (currentPage - 1) * pageSize + count) : total + (newTotal >= getTotal ? '+' : ''))} 条
|
|
</li>);
|
|
//上一页
|
|
function renderPrev(prevPage) {
|
|
const prevButton = (<a>
|
|
<LeftOutlined />
|
|
</a>);
|
|
return React.isValidElement(prevButton)
|
|
? React.cloneElement(prevButton, { disabled: !hasPrev })
|
|
: prevButton;
|
|
}
|
|
function prevHandle() {
|
|
if (hasPrev)
|
|
handleChange(currentPage - 1);
|
|
}
|
|
let prev = renderPrev(prevPage);
|
|
if (prev) {
|
|
const prevDisabled = !hasPrev || !newTotal;
|
|
prev = (<li title={showTitle ? '上一页' : undefined} onClick={prevHandle} tabIndex={prevDisabled ? undefined : 0} className={classNames(Style[`${prefixCls}-prev`], {
|
|
[Style[`${prefixCls}-disabled`]]: prevDisabled,
|
|
})} aria-disabled={prevDisabled}>
|
|
{prev}
|
|
</li>);
|
|
}
|
|
//下一页
|
|
function renderNext(nextPage) {
|
|
const nextButton = (<a style={{
|
|
cursor: hasNext ? "pointer" : "not-allowed",
|
|
color: hasNext ? "#006cb7" : "rgba(0, 0, 0, 0.25)",
|
|
}} onClick={hasNext ? () => {
|
|
if (currentPage) {
|
|
setCurrentPage(currentPage + 1);
|
|
}
|
|
} : undefined}>
|
|
<RightOutlined />
|
|
</a>);
|
|
return React.isValidElement(nextButton)
|
|
? React.cloneElement(nextButton, { disabled: !hasNext })
|
|
: nextButton;
|
|
}
|
|
function nextHandle() {
|
|
if (hasNext)
|
|
handleChange(currentPage + 1);
|
|
}
|
|
let next = renderNext(nextPage);
|
|
if (next) {
|
|
let nextDisabled, nextTabIndex;
|
|
// if (simple) {
|
|
// nextDisabled = !hasNext;
|
|
// nextTabIndex = hasPrev ? 0 : null;
|
|
// } else {
|
|
nextDisabled = !hasNext || !newTotal;
|
|
nextTabIndex = nextDisabled ? undefined : 0;
|
|
// }
|
|
next = (<li title={showTitle ? '下一页' : undefined} onClick={nextHandle} tabIndex={nextTabIndex} className={classNames(Style[`${prefixCls}-next`], {
|
|
[Style[`${prefixCls}-disabled`]]: nextDisabled,
|
|
})} aria-disabled={nextDisabled}>
|
|
{next}
|
|
</li>);
|
|
}
|
|
//页码
|
|
const pagerList = [];
|
|
const pagerProps = {
|
|
rootPrefixCls: prefixCls,
|
|
onClick: handleChange,
|
|
showTitle: showTitle,
|
|
itemRender,
|
|
page: -1,
|
|
};
|
|
const pageBufferSize = 5;
|
|
if (allPages <= pageBufferSize * 2) {
|
|
if (!allPages) {
|
|
pagerList.push(<Pager {...pagerProps} key="noPager" page={1} className={classNames(className, {
|
|
[`${prefixCls}-item-disabled`]: true,
|
|
})}/>);
|
|
}
|
|
for (let i = 1; i <= allPages; i += 1) {
|
|
pagerList.push(<Pager {...pagerProps} key={i} page={i} active={currentPage === i}/>);
|
|
}
|
|
}
|
|
else {
|
|
const left = Math.min(allPages - pageBufferSize * 2 + 1, Math.max(1, currentPage - pageBufferSize));
|
|
const right = Math.min(left + pageBufferSize * 2 - 1, allPages);
|
|
for (let i = left; i <= right; i += 1) {
|
|
pagerList.push(<Pager {...pagerProps} key={i} page={i} active={currentPage === i}/>);
|
|
}
|
|
}
|
|
function changePageSize(size) {
|
|
// const newCurrent = calculatePage(size, pageSize!, newTotal);
|
|
// const nextCurrent =
|
|
// currentPage! > newCurrent && newCurrent !== 0 ? newCurrent : currentPage!;
|
|
setPageSize(size);
|
|
//pageSize 改变时自动回到第一页
|
|
// setInternalInputVal(nextCurrent);
|
|
// setCurrentPage(nextCurrent);
|
|
}
|
|
const shouldDisplayQuickJumper = newTotal > pageSize ? showQuickJumper : false;
|
|
const goButton = showQuickJumper && showQuickJumper.goButton;
|
|
let gotoButton = goButton;
|
|
return (
|
|
// <Pagination
|
|
// style={style}
|
|
// className={classNames(className, {
|
|
// [Style.pagination]: more,
|
|
// [Style.paginationNoMore]: !more,
|
|
// })}
|
|
// itemRender={itemRender}
|
|
// pageSize={pageSize}
|
|
// total={newTotal}
|
|
// current={currentPage}
|
|
// showQuickJumper={showQuickJumper}
|
|
// showSizeChanger={showSizeChanger}
|
|
// size={size}
|
|
// showTotal={showTotal}
|
|
// onShowSizeChange={(current: number, pageSize: number) => {
|
|
// setPageSize(pageSize);
|
|
// }}
|
|
// onChange={(page: number, pageSize: number) => {
|
|
// setCurrentPage(page);
|
|
// }}
|
|
// />
|
|
<ul className={classNames(className, {
|
|
[Style[`${prefixCls}-end`]]: true,
|
|
})} style={style} ref={paginationRef}>
|
|
{totalText}
|
|
{prev}
|
|
{/* {simple ? simplePager : pagerList} */}
|
|
{pagerList}
|
|
{next}
|
|
<Options locale={zhCN} rootPrefixCls={prefixCls}
|
|
// disabled={disabled}
|
|
selectComponentClass={size === 'small' ? MiniSelect : MiddleSelect} selectPrefixCls={selectPrefixCls} changeSize={changePageSize} pageSize={pageSize} showSizeChanger={showSizeChanger} quickGo={shouldDisplayQuickJumper ? handleChange : undefined} goButton={gotoButton}/>
|
|
</ul>);
|
|
}
|