add columns
This commit is contained in:
@@ -26,9 +26,9 @@ export function DataTableColumnHeader<TData, TValue>({
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
variant="link"
|
||||
size="sm"
|
||||
className={cn('-ml-3 cursor-pointer', className)}
|
||||
className={cn('-ml-3 cursor-pointer text-inherit h-auto', className)}
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
|
||||
>
|
||||
<span>{title}</span>
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
type ReactNode
|
||||
} from 'react'
|
||||
@@ -43,7 +44,7 @@ interface DataTableProps<TData, TValue> {
|
||||
sort: SortingState
|
||||
pageSize: number
|
||||
rowCount: number
|
||||
columnInvisibilityInit?: string[]
|
||||
columnVisibilityInit?: VisibilityState
|
||||
}
|
||||
|
||||
interface TableContextProps<TData> {
|
||||
@@ -71,21 +72,33 @@ export function DataTable<TData, TValue>({
|
||||
pageSize,
|
||||
rowCount,
|
||||
setSelectedRows,
|
||||
columnInvisibilityInit = []
|
||||
columnVisibilityInit = {}
|
||||
}: DataTableProps<TData, TValue>) {
|
||||
const [dataTable, setDataTable] = useState<TData[]>(data)
|
||||
const columnInvisibility = useMemo<VisibilityState>(
|
||||
() =>
|
||||
Object.fromEntries(
|
||||
columnInvisibilityInit.map((column) => [column, false])
|
||||
),
|
||||
[columnInvisibilityInit]
|
||||
)
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
useState<VisibilityState>(columnInvisibility)
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
|
||||
|
||||
const columnVisibilityInit_ = useMemo<VisibilityState>(() => {
|
||||
const columns = searchParams.get('columns')
|
||||
|
||||
if (columns === null) {
|
||||
return columnVisibilityInit
|
||||
}
|
||||
|
||||
const columnVisibility = columns ? columns.split(',') : []
|
||||
return Object.keys(columnVisibilityInit).reduce<VisibilityState>(
|
||||
(acc, col) => ({
|
||||
...acc,
|
||||
[col]: columnVisibility.includes(col)
|
||||
}),
|
||||
{}
|
||||
)
|
||||
}, [])
|
||||
|
||||
const [columnVisibility, setColumnVisibility_] = useState<VisibilityState>(
|
||||
columnVisibilityInit_
|
||||
)
|
||||
|
||||
const sorting = useMemo(() => {
|
||||
const sortParam = searchParams.get('sort')
|
||||
|
||||
@@ -110,6 +123,7 @@ export function DataTable<TData, TValue>({
|
||||
setSearchParams((prev) => {
|
||||
prev.set('p', newState?.pageIndex.toString())
|
||||
prev.set('perPage', newState?.pageSize.toString())
|
||||
|
||||
return prev
|
||||
})
|
||||
},
|
||||
@@ -130,60 +144,67 @@ export function DataTable<TData, TValue>({
|
||||
} else {
|
||||
prev.delete('sort')
|
||||
}
|
||||
|
||||
return prev
|
||||
})
|
||||
},
|
||||
[sorting, setSearchParams]
|
||||
)
|
||||
|
||||
const setColumnVisibility = useCallback(
|
||||
(updater: any) => {
|
||||
const newColumnVisibility =
|
||||
typeof updater === 'function' ? updater(columnVisibility) : updater
|
||||
|
||||
setColumnVisibility_(newColumnVisibility)
|
||||
|
||||
setSearchParams((prev) => {
|
||||
const columns = Object.entries(newColumnVisibility)
|
||||
.filter(([_, visible]) => visible)
|
||||
.map(([col, _]) => col)
|
||||
|
||||
if (columns.length > 0) {
|
||||
prev.set('columns', columns.join(','))
|
||||
} else {
|
||||
prev.set('columns', '')
|
||||
}
|
||||
|
||||
return prev
|
||||
})
|
||||
},
|
||||
[setSearchParams, setColumnVisibility_]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
setDataTable(data)
|
||||
}, [data])
|
||||
|
||||
const tableConfig = useMemo(
|
||||
() => ({
|
||||
data: dataTable,
|
||||
columns,
|
||||
rowCount,
|
||||
state: {
|
||||
sorting,
|
||||
rowSelection,
|
||||
columnVisibility,
|
||||
pagination: {
|
||||
pageIndex,
|
||||
pageSize
|
||||
}
|
||||
},
|
||||
manualSorting: true,
|
||||
manualPagination: true,
|
||||
enableRowSelection: true,
|
||||
getRowId: (row: any) => row.id,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
onRowSelectionChange: setRowSelection,
|
||||
onSortingChange: setSorting,
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
onPaginationChange: setPagination,
|
||||
meta: {
|
||||
removeRow: (rowId: string) => {
|
||||
setDataTable((rows) => rows.filter((row: any) => row?.id !== rowId))
|
||||
}
|
||||
}
|
||||
}),
|
||||
[
|
||||
dataTable,
|
||||
columns,
|
||||
rowCount,
|
||||
const getRowId = useCallback((row: any) => row.id, [])
|
||||
const removeRow = useCallback((rowId: string) => {
|
||||
setDataTable((rows) => rows.filter((row: any) => row.id !== rowId))
|
||||
}, [])
|
||||
|
||||
const table = useReactTable({
|
||||
data: dataTable,
|
||||
columns,
|
||||
rowCount,
|
||||
state: {
|
||||
sorting,
|
||||
rowSelection,
|
||||
columnVisibility,
|
||||
setColumnVisibility,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
setSorting,
|
||||
setPagination
|
||||
]
|
||||
)
|
||||
|
||||
const table = useReactTable(tableConfig)
|
||||
pagination: { pageIndex, pageSize }
|
||||
},
|
||||
manualSorting: true,
|
||||
manualPagination: true,
|
||||
enableRowSelection: true,
|
||||
getRowId,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
onRowSelectionChange: setRowSelection,
|
||||
onSortingChange: setSorting,
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
onPaginationChange: setPagination,
|
||||
meta: { removeRow }
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!setSelectedRows) return
|
||||
|
||||
@@ -41,6 +41,7 @@ export function DataTableViewOptions<TData>({
|
||||
<DropdownMenuCheckboxItem
|
||||
key={column.id}
|
||||
checked={column.getIsVisible()}
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
||||
>
|
||||
{title}
|
||||
|
||||
Reference in New Issue
Block a user