update
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
type ColumnDef,
|
||||
type ColumnSort,
|
||||
type SortingState,
|
||||
type Table,
|
||||
type VisibilityState
|
||||
} from '@tanstack/react-table'
|
||||
import { createContext, useState, type ReactNode } from 'react'
|
||||
import { useSearchParams } from 'react-router'
|
||||
|
||||
import { Card, CardContent } from '@repo/ui/components/ui/card'
|
||||
import {
|
||||
Table as Table_,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow
|
||||
} from '@repo/ui/components/ui/table'
|
||||
import { DataTablePagination } from './pagination'
|
||||
|
||||
interface DataTableProps<TData, TValue> {
|
||||
children?: ReactNode
|
||||
columns: ColumnDef<TData, TValue>[]
|
||||
data: TData[]
|
||||
pageIndex: number
|
||||
sort: SortingState
|
||||
pageSize: number
|
||||
rowCount: number
|
||||
hiddenColumn?: string[]
|
||||
}
|
||||
|
||||
export const TableContext = createContext<{ table: Table<any> } | null>(null)
|
||||
|
||||
export function DataTable<TData, TValue>({
|
||||
children,
|
||||
columns,
|
||||
data,
|
||||
sort,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
rowCount,
|
||||
hiddenColumn = []
|
||||
}: DataTableProps<TData, TValue>) {
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const hiddenColumn_ = Object.fromEntries(
|
||||
hiddenColumn.map((column) => [column, false])
|
||||
)
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
useState<VisibilityState>(hiddenColumn_)
|
||||
const [rowSelection, setRowSelection] = useState({})
|
||||
const sortParam = searchParams.get('sort')
|
||||
const sorting = sortParam
|
||||
? sortParam.split(',').map((s) => {
|
||||
const [id, dir] = s.split(':')
|
||||
return { id, desc: dir === 'desc' }
|
||||
})
|
||||
: sort
|
||||
|
||||
const setPagination = (updater: any) => {
|
||||
const newState =
|
||||
typeof updater === 'function' ? updater({ pageIndex, pageSize }) : updater
|
||||
|
||||
setSearchParams((searchParams) => {
|
||||
searchParams.set('p', newState?.pageIndex.toString())
|
||||
searchParams.set('perPage', newState?.pageSize.toString())
|
||||
return searchParams
|
||||
})
|
||||
}
|
||||
|
||||
const setSorting = (updater: any) => {
|
||||
const newSorting =
|
||||
typeof updater === 'function' ? updater(sorting) : updater
|
||||
|
||||
setSearchParams((searchParams) => {
|
||||
if (newSorting.length) {
|
||||
const sort = newSorting
|
||||
.map((s: ColumnSort) => `${s.id}:${s.desc ? 'desc' : 'asc'}`)
|
||||
.join(',')
|
||||
searchParams.set('sort', sort)
|
||||
}
|
||||
return searchParams
|
||||
})
|
||||
}
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
columns,
|
||||
rowCount,
|
||||
state: {
|
||||
sorting,
|
||||
rowSelection,
|
||||
columnVisibility,
|
||||
pagination: {
|
||||
pageIndex,
|
||||
pageSize
|
||||
}
|
||||
},
|
||||
manualSorting: true,
|
||||
manualPagination: true,
|
||||
enableRowSelection: true,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
onRowSelectionChange: setRowSelection,
|
||||
onSortingChange: setSorting,
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
onPaginationChange: setPagination
|
||||
})
|
||||
|
||||
return (
|
||||
<TableContext value={{ table }}>
|
||||
<div className="space-y-2.5 max-md:mb-2">
|
||||
<Card className="relative w-full overflow-auto">
|
||||
<CardContent>
|
||||
{children}
|
||||
|
||||
<Table_>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow
|
||||
key={headerGroup.id}
|
||||
className="hover:bg-transparent"
|
||||
>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id} className="p-2.5">
|
||||
{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) => (
|
||||
<TableCell key={cell.id} className="p-2.5">
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext()
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
Nenhum resultado.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table_>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<DataTablePagination table={table} />
|
||||
</div>
|
||||
</TableContext>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user