chore: initial commit
This commit is contained in:
110
src/components/data-table/base-table.tsx
Normal file
110
src/components/data-table/base-table.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import { useEffect } from 'react'
|
||||
|
||||
import { flexRender, type Table as ITable } from '@tanstack/react-table'
|
||||
import { ChevronDown, ChevronRight } from 'lucide-react'
|
||||
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table.tsx'
|
||||
import { cn } from '@/lib/utils.ts'
|
||||
|
||||
import { Loading } from './loading.tsx'
|
||||
|
||||
interface Props<TData> {
|
||||
table: ITable<TData>
|
||||
}
|
||||
|
||||
export function BaseTable<TData>({ table }: Props<TData>) {
|
||||
const pageIndex = table.getState().pagination.pageIndex
|
||||
const pageSize = table.getState().pagination.pageSize
|
||||
const rowCount = table.options.rowCount
|
||||
const currentPageRowsLength = table.getCoreRowModel().rows.length
|
||||
const showLoading = table.options.meta?.showLoading
|
||||
|
||||
useEffect(() => {
|
||||
if (pageIndex > 0 && currentPageRowsLength === 0 && rowCount) {
|
||||
const lastPageIndex = Math.max(0, Math.ceil(rowCount / pageSize) - 1)
|
||||
if (lastPageIndex !== pageIndex) {
|
||||
table.setPageIndex(lastPageIndex)
|
||||
table.setPagination((prev) => ({ ...prev, pageIndex: lastPageIndex }))
|
||||
}
|
||||
}
|
||||
}, [pageIndex, currentPageRowsLength, rowCount, pageSize, table])
|
||||
|
||||
const isTree = !!table.options.getExpandedRowModel
|
||||
|
||||
return (
|
||||
<Loading visible={showLoading}>
|
||||
<div className='rounded-md border'>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => (
|
||||
<TableHead
|
||||
key={header.id}
|
||||
className={cn(header.column.columnDef.meta?.className ?? '')}
|
||||
>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(header.column.columnDef.header, header.getContext())}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
|
||||
{row.getVisibleCells().map((cell, cellIndex) => (
|
||||
<TableCell
|
||||
key={cell.id}
|
||||
className={cn(cell.column.columnDef.meta?.className ?? '')}
|
||||
>
|
||||
{cellIndex === 0 && isTree ? (
|
||||
<div
|
||||
className='flex items-center gap-1'
|
||||
style={{ paddingLeft: `${row.depth * 1.25}rem` }}
|
||||
>
|
||||
{row.getCanExpand() ? (
|
||||
<button
|
||||
onClick={row.getToggleExpandedHandler()}
|
||||
className='flex items-center justify-center w-4 h-4 shrink-0 cursor-pointer'
|
||||
>
|
||||
{row.getIsExpanded() ? (
|
||||
<ChevronDown className='w-4 h-4 ' />
|
||||
) : (
|
||||
<ChevronRight className='w-4 h-4 ' />
|
||||
)}
|
||||
</button>
|
||||
) : (
|
||||
<span className='w-4 h-4 shrink-0'></span>
|
||||
)}
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</div>
|
||||
) : (
|
||||
flexRender(cell.column.columnDef.cell, cell.getContext())
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={table.getAllColumns().length} className='h-24 text-center'>
|
||||
No results.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</Loading>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user