add columns

This commit is contained in:
2025-11-19 00:46:57 -03:00
parent 786c5e1580
commit a180e269f2
6 changed files with 94 additions and 64 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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}