feishin/src/renderer/components/virtual-table/table-pagination.tsx

144 lines
4.5 KiB
TypeScript
Raw Normal View History

2022-12-27 13:13:12 -08:00
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
2022-12-26 01:45:36 -08:00
import { Group } from '@mantine/core';
import { useForm } from '@mantine/form';
import { useDisclosure } from '@mantine/hooks';
2022-12-27 13:13:12 -08:00
import { MutableRefObject } from 'react';
2022-12-26 01:45:36 -08:00
import { RiHashtag } from 'react-icons/ri';
import { Button } from '/@/renderer/components/button';
2022-12-27 13:13:12 -08:00
import { MotionFlex } from '../motion';
2022-12-26 01:45:36 -08:00
import { NumberInput } from '/@/renderer/components/input';
import { Pagination } from '/@/renderer/components/pagination';
import { Popover } from '/@/renderer/components/popover';
2022-12-27 13:13:12 -08:00
import { Text } from '/@/renderer/components/text';
2022-12-26 01:45:36 -08:00
import { useContainerQuery } from '/@/renderer/hooks';
2022-12-27 13:13:12 -08:00
import { TablePagination as TablePaginationType } from '/@/renderer/types';
2022-12-26 01:45:36 -08:00
interface TablePaginationProps {
2022-12-27 13:13:12 -08:00
pagination: TablePaginationType;
setPagination: (pagination: Partial<TablePaginationType>) => void;
tableRef: MutableRefObject<AgGridReactType | null>;
2022-12-26 01:45:36 -08:00
}
2022-12-27 13:13:12 -08:00
export const TablePagination = ({ tableRef, pagination, setPagination }: TablePaginationProps) => {
2022-12-26 01:45:36 -08:00
const [isGoToPageOpen, handlers] = useDisclosure(false);
2022-12-27 13:13:12 -08:00
const containerQuery = useContainerQuery();
2022-12-26 01:45:36 -08:00
2022-12-27 13:13:12 -08:00
const goToForm = useForm({
2022-12-26 01:45:36 -08:00
initialValues: {
pageNumber: undefined,
},
});
const handlePagination = (index: number) => {
2022-12-27 13:13:12 -08:00
const newPage = index - 1;
tableRef.current?.api.paginationGoToPage(newPage);
setPagination({ currentPage: newPage });
2022-12-26 01:45:36 -08:00
};
2022-12-27 13:13:12 -08:00
const handleGoSubmit = goToForm.onSubmit((values) => {
2022-12-26 01:45:36 -08:00
handlers.close();
if (!values.pageNumber || values.pageNumber < 1 || values.pageNumber > pagination.totalPages) {
return;
}
2022-12-27 13:13:12 -08:00
const newPage = values.pageNumber - 1;
tableRef.current?.api.paginationGoToPage(newPage);
setPagination({ currentPage: newPage });
2022-12-26 01:45:36 -08:00
});
2022-12-27 13:13:12 -08:00
const currentPageStartIndex = pagination.currentPage * pagination.itemsPerPage + 1;
const currentPageStopIndex = (pagination.currentPage + 1) * pagination.itemsPerPage;
2022-12-26 01:45:36 -08:00
return (
2022-12-27 13:13:12 -08:00
<MotionFlex
2022-12-26 01:45:36 -08:00
ref={containerQuery.ref}
2022-12-27 13:13:12 -08:00
layout
align="center"
animate={{ y: 0 }}
exit={{ y: 50 }}
initial={{ y: 50 }}
justify="space-between"
p="1rem"
sx={{ borderTop: '1px solid var(--generic-border-color)' }}
2022-12-26 01:45:36 -08:00
>
2022-12-27 13:13:12 -08:00
<Text
$secondary
size="md"
2022-12-26 01:45:36 -08:00
>
2022-12-27 13:13:12 -08:00
{containerQuery.isMd ? (
<>
Showing <b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '}
<b>{pagination.totalItems}</b> items
</>
) : containerQuery.isSm ? (
<>
<b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '}
<b>{pagination.totalItems}</b> items
</>
) : (
<>
<b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '}
<b>{pagination.totalItems}</b>
</>
)}
</Text>
<Group
ref={containerQuery.ref}
2022-12-26 01:45:36 -08:00
noWrap
2022-12-27 13:13:12 -08:00
spacing="sm"
>
<Popover
trapFocus
opened={isGoToPageOpen}
position="bottom-start"
transition="fade"
onClose={() => handlers.close()}
>
<Popover.Target>
<Button
compact
radius="sm"
size="lg"
sx={{ height: '32px', padding: 0, width: '32px' }}
tooltip={{ label: 'Go to page' }}
variant="default"
onClick={() => handlers.toggle()}
>
<RiHashtag size={15} />
</Button>
</Popover.Target>
<Popover.Dropdown>
<form onSubmit={handleGoSubmit}>
<Group>
<NumberInput
{...goToForm.getInputProps('pageNumber')}
hideControls={false}
max={pagination.totalPages}
min={1}
width={70}
/>
<Button
type="submit"
variant="filled"
>
Go
</Button>
</Group>
</form>
</Popover.Dropdown>
</Popover>
<Pagination
noWrap
2022-12-28 00:39:36 -08:00
$hideDividers={!containerQuery.isSm}
2022-12-27 13:13:12 -08:00
boundaries={1}
page={pagination.currentPage + 1}
radius="sm"
2022-12-28 00:39:36 -08:00
siblings={containerQuery.isMd ? 2 : containerQuery.isSm ? 1 : 0}
2022-12-27 13:13:12 -08:00
total={pagination.totalPages - 1}
onChange={handlePagination}
/>
</Group>
</MotionFlex>
2022-12-26 01:45:36 -08:00
);
};