"use client"; import { ColumnDef, flexRender, getCoreRowModel, getSortedRowModel, useReactTable, PaginationState, SortingState, Updater, RowSelectionState, } from "@tanstack/react-table"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/shared/components/ui/table"; import { Checkbox } from "@/shared/components/ui/checkbox"; import { Pagination } from "@/shared/components/ui/pagination"; import { useState, useEffect, useMemo } from "react"; interface DataTableProps { columns: ColumnDef[]; data: TData[]; pageCount: number; pageIndex: number; pageSize: number; onPaginationChangeAction: (pagination: PaginationState) => void; manualPagination?: boolean; rowCount: number; sorting: SortingState; onSortingChangeAction: (sorting: SortingState) => void; onRowSelectionChange?: (selectedRows: TData[]) => void; enableRowSelection?: boolean; } export function DataTable({ columns, data, pageCount, pageIndex, pageSize, sorting, onSortingChangeAction, onPaginationChangeAction, onRowSelectionChange, enableRowSelection = false, manualPagination = true, rowCount, }: DataTableProps) { const [rowSelection, setRowSelection] = useState({}); const [pagination, setPagination] = useState({ pageIndex, pageSize, }); const columnsWithSelection = useMemo[]>(() => { if (!enableRowSelection) return columns; return [ { id: "select", header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value) } /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} /> ), enableSorting: false, enableHiding: false, }, ...columns, ]; }, [columns, enableRowSelection]); useEffect(() => { if ( pagination.pageIndex !== pageIndex || pagination.pageSize !== pageSize ) { setPagination({ pageIndex, pageSize }); } }, [pagination.pageIndex, pagination.pageSize, pageIndex, pageSize]); useEffect(() => { setRowSelection({}); }, [pageIndex]); const table = useReactTable({ data, columns: columnsWithSelection, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), manualPagination, manualSorting: true, pageCount, rowCount, state: { pagination, sorting, rowSelection, }, onPaginationChange: (updater: Updater) => { const newPagination = typeof updater === "function" ? updater(pagination) : updater; if ( pagination.pageIndex !== newPagination.pageIndex || pagination.pageSize !== newPagination.pageSize ) { setPagination(newPagination); onPaginationChangeAction(newPagination); } }, onSortingChange: (updaterOrValue: Updater) => { const newSorting = typeof updaterOrValue === "function" ? updaterOrValue(sorting) : updaterOrValue; onSortingChangeAction(newSorting); }, onRowSelectionChange: enableRowSelection ? (updater) => { const newSelection = typeof updater === "function" ? updater(rowSelection) : updater; setRowSelection(newSelection); if (onRowSelectionChange) { const selectedRowIndices = Object.keys(newSelection).filter( (key) => newSelection[key] ); const selectedRows = selectedRowIndices .map((index) => data[parseInt(index)]) .filter(Boolean); onRowSelectionChange(selectedRows); } } : undefined, enableRowSelection, getRowId: (row, index) => index.toString(), }); const selectedRowCount = Object.keys(rowSelection).filter( (key) => rowSelection[key] ).length; return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext() )} ))} ))} {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext() )} ))} )) ) : ( Tidak ada data )}
{enableRowSelection ? (
{selectedRowCount} dari {data.length} baris dipilih.
) : (
)} table.setPageIndex(page - 1)} perPage={pageSize} onPerPageChange={(perPage: number) => table.setPageSize(perPage)} />
); }