File manager - Edit - /var/www/payraty/helpdesk/common/resources/client/ui/navigation/pagination-controls.tsx
Back
import { hasNextPage, hasPreviousPage, LengthAwarePaginationResponse, PaginationResponse, SimplePaginationResponse, } from '@common/http/backend-response/pagination-response'; import {Button} from '@common/ui/buttons/button'; import memoize from 'nano-memoize'; import {Link} from 'react-router-dom'; import clsx from 'clsx'; import {Trans} from '@common/i18n/trans'; import {KeyboardArrowRightIcon} from '@common/icons/material/KeyboardArrowRight'; import {KeyboardArrowLeftIcon} from '@common/icons/material/KeyboardArrowLeft'; import {scrollToTop} from '@common/ui/navigation/use-scroll-to-top'; import {useRef} from 'react'; import {FirstPageIcon} from '@common/icons/material/FirstPage'; import {FormattedNumber} from '@common/i18n/formatted-number'; export type PaginationControlsType = 'simple' | 'lengthAware'; interface Props { pagination: PaginationResponse<unknown> | undefined; className?: string; type?: PaginationControlsType; scrollToTop?: boolean; } export function PaginationControls({ pagination, className, type, scrollToTop, }: Props) { if ( !pagination?.data?.length || (!hasNextPage(pagination) && !hasPreviousPage(pagination)) ) { return null; } const isLengthAware = (!type || type === 'lengthAware') && 'total' in pagination && pagination.total != null; if (isLengthAware) { return ( <LengthAwarePagination data={pagination as LengthAwarePaginationResponse} className={className} scrollToTop={scrollToTop} /> ); } return ( <SimplePagination data={pagination as SimplePaginationResponse} className={className} scrollToTop={scrollToTop} /> ); } interface LengthAwarePaginationProps { data: LengthAwarePaginationResponse; className?: string; scrollToTop?: boolean; } function LengthAwarePagination({ data, className, scrollToTop: shouldScrollToTop, }: LengthAwarePaginationProps) { const ref = useRef<HTMLElement>(null); const currentPage = data.current_page; const total = data.total; const perPage = data.per_page; const range = generatePaginationRangeWithDots(currentPage, total, perPage); return ( <nav ref={ref} className={clsx('flex flex-wrap items-center justify-center', className)} > <ul className="flex items-center gap-4"> {range.map((item, index) => { const isCurrentPage = item === currentPage; return ( <li key={item === '...' ? `...-${index}` : item}> <Button elementType={isCurrentPage ? undefined : Link} to={!isCurrentPage ? `?page=${item}` : undefined} replace variant={isCurrentPage ? 'outline' : undefined} disabled={isCurrentPage || item === '...'} onClick={shouldScrollToTop ? () => scrollToTop(ref) : undefined} > {item === '...' ? item : <FormattedNumber value={+item} />} </Button> </li> ); })} </ul> </nav> ); } interface SimplePaginationProps { data: SimplePaginationResponse<unknown>; className?: string; scrollToTop?: boolean; } function SimplePagination({ data, className, scrollToTop: shouldScrollToTop, }: SimplePaginationProps) { const ref = useRef<HTMLDivElement>(null); const currentPage = data.current_page; const isLastPage = !hasNextPage(data); return ( <div ref={ref} className={clsx('flex items-center gap-12', className)}> {currentPage > 1 && ( <Button variant="outline" elementType={Link} className="min-w-110" to="?page=1" replace startIcon={<FirstPageIcon />} onClick={shouldScrollToTop ? () => scrollToTop(ref) : undefined} size="xs" > <Trans message="First" /> </Button> )} <Button variant="outline" elementType={currentPage == 1 ? undefined : Link} disabled={currentPage == 1} className="mr-auto min-w-110" to={currentPage == 1 ? undefined : `?page=${currentPage - 1}`} replace={currentPage == 1 ? undefined : true} startIcon={<KeyboardArrowLeftIcon />} onClick={shouldScrollToTop ? () => scrollToTop(ref) : undefined} size="xs" > <Trans message="Previous" /> </Button> <Button variant="outline" elementType={isLastPage ? undefined : Link} disabled={isLastPage} className="min-w-110" to={isLastPage ? undefined : `?page=${currentPage + 1}`} replace={isLastPage ? undefined : true} endIcon={<KeyboardArrowRightIcon />} onClick={shouldScrollToTop ? () => scrollToTop(ref) : undefined} size="xs" > <Trans message="Next" /> </Button> </div> ); } const generatePaginationRangeWithDots = memoize( (currentPage: number, total: number, perPage: number) => { const totalPages = Math.ceil(total / perPage); const delta = 3; const range = []; for ( let i = Math.max(2, currentPage - delta); i <= Math.min(totalPages - 1, currentPage + delta); i++ ) { range.push(i); } if (currentPage - delta > 2) { range.unshift('...'); } if (currentPage + delta < totalPages - 1) { range.push('...'); } range.unshift(1); range.push(totalPages); return range; }, );
| ver. 1.4 |
Github
|
.
| PHP 8.3.30 | Generation time: 0 |
proxy
|
phpinfo
|
Settings