oak-frontend-base/es/components/pagination/web.js

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, total, currentPage, more, count, getTotal } = oakPagination || {};
const paginationRef = useRef(null);
const [internalInputVal, setInternalInputVal] = useState(currentPage);
useEffect(() => {
setInternalInputVal(currentPage);
}, [currentPage]);
if (!oakPagination) {
return null;
}
if (total === 0) {
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>);
}