Skip to content

Commit

Permalink
add TablePagination component
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Jul 31, 2024
1 parent ba86be2 commit c0acc91
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 9 deletions.
119 changes: 119 additions & 0 deletions src/components/TablePagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { SyncProblem as SyncProblemIcon } from "@mui/icons-material"
import {
CircularProgress,
TablePagination as MuiTablePagination,
type TablePaginationProps as MuiTablePaginationProps,
Stack,
type StackProps,
type TablePaginationBaseProps,
Typography,
} from "@mui/material"
import type { TypedUseLazyQuery } from "@reduxjs/toolkit/query/react"
import {
type ElementType,
type JSXElementConstructor,
type ReactNode,
useEffect,
} from "react"

import { usePagination } from "../hooks/api"
import type { ListArg, ListResult } from "../utils/api"

export type TablePaginationProps<
QueryArg extends ListArg,
ResultType extends ListResult<any>,
RootComponent extends
ElementType = JSXElementConstructor<TablePaginationBaseProps>,
AdditionalProps = {},
> = Omit<
MuiTablePaginationProps<RootComponent, AdditionalProps>,
| "component"
| "count"
| "rowsPerPage"
| "onRowsPerPageChange"
| "page"
| "onPageChange"
| "rowsPerPageOptions"
> & {
children: (data: ResultType["data"]) => ReactNode
useLazyListQuery: TypedUseLazyQuery<ResultType, QueryArg, any>
filters?: Omit<QueryArg, "limit" | "offset">
rowsPerPageOptions?: number[]
stackProps?: StackProps
page?: number
rowsPerPage?: number
}

const TablePagination = <
QueryArg extends ListArg,
ResultType extends ListResult<any>,
RootComponent extends
ElementType = JSXElementConstructor<TablePaginationBaseProps>,
AdditionalProps = {},
>({
children,
useLazyListQuery,
filters,
page: initialPage = 0,
rowsPerPage: initialLimit = 50,
rowsPerPageOptions = [50, 100, 150],
stackProps,
...tablePaginationProps
}: TablePaginationProps<
QueryArg,
ResultType,
RootComponent,
AdditionalProps
>): JSX.Element => {
const [trigger, { data: result, isLoading, error }] = useLazyListQuery()
const [{ limit, page, offset }, setPagination] = usePagination({
page: initialPage,
limit: initialLimit,
})

useEffect(() => {
trigger({ limit, offset, ...filters } as QueryArg)
}, [trigger, limit, offset, filters])

useEffect(() => {
console.error(error)
}, [error])

const { data, count = 0, maxLimit } = result || {}

if (maxLimit) {
rowsPerPageOptions = rowsPerPageOptions.filter(option => option <= maxLimit)
}

return (
<Stack {...stackProps}>
{isLoading ? (
<CircularProgress />
) : error || !data ? (
<>
<SyncProblemIcon color="error" />
<Typography color="error.main">Failed to load data</Typography>
</>
) : (
children(data)
)}
<MuiTablePagination
component="div"
count={count}
rowsPerPage={limit}
onRowsPerPageChange={event => {
setPagination({ limit: parseInt(event.target.value), page: 0 })
}}
page={page}
onPageChange={(_, page) => {
setPagination(({ limit }) => ({ limit, page }))
}}
// ascending order
rowsPerPageOptions={rowsPerPageOptions.sort((a, b) => a - b)}
{...tablePaginationProps}
/>
</Stack>
)
}

export default TablePagination
21 changes: 12 additions & 9 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,30 @@ import Image, { type ImageProps } from "./Image"
import ItemizedList, { type ItemizedListProps } from "./ItemizedList"
import OrderedGrid, { type OrderedGridProps } from "./OrderedGrid"
import ScrollRoutes, { type ScrollRoutesProps } from "./ScrollRoutes"
import TablePagination, { type TablePaginationProps } from "./TablePagination"
import YouTubeVideo, { type YouTubeVideoProps } from "./YouTubeVideo"

export {
App,
type AppProps,
ClickableTooltip,
type ClickableTooltipProps,
CopyIconButton,
type CopyIconButtonProps,
Countdown,
type CountdownProps,
ElevatedAppBar,
type ElevatedAppBarProps,
Image,
type ImageProps,
ItemizedList,
type ItemizedListProps,
OrderedGrid,
type OrderedGridProps,
ScrollRoutes,
type ScrollRoutesProps,
TablePagination,
YouTubeVideo,
type AppProps,
type ClickableTooltipProps,
type CopyIconButtonProps,
type CountdownProps,
type ElevatedAppBarProps,
type ImageProps,
type ItemizedListProps,
type OrderedGridProps,
type ScrollRoutesProps,
type TablePaginationProps,
type YouTubeVideoProps,
}

0 comments on commit c0acc91

Please sign in to comment.