import { ColumnDef, flexRender, getCoreRowModel, SortingState, useReactTable, } from '@tanstack/react-table'; import { useTranslation } from 'react-i18next'; import { ArrowDown, ArrowUp, ArrowUpDown } from 'lucide-react'; import { Skeleton } from '@/components/ui/skeleton'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { TablePaginationBar } from '@/components/explore/TablePaginationBar'; import { DEFAULT_TABLE_PAGE_SIZE } from '@/utils/tablePagination'; export interface ServerTableParams { offset?: number; limit?: number; sort?: string; order?: 'asc' | 'desc'; } interface DataTableProps { columns: ColumnDef[]; data: TData[]; total?: number; isLoading?: boolean; tableKey: string; params: TParams; onParamsChange: (params: TParams) => void; emptyMessage?: string; } export function DataTable({ columns, data, total, isLoading, tableKey, params, onParamsChange, emptyMessage, }: DataTableProps) { const { t } = useTranslation(); const empty = emptyMessage ?? t('common.noData'); const sorting: SortingState = params.sort && params.order ? [{ id: params.sort, desc: params.order === 'desc' }] : []; const table = useReactTable({ data, columns, pageCount: total != null ? Math.ceil(total / (params.limit || DEFAULT_TABLE_PAGE_SIZE)) : -1, state: { sorting, pagination: { pageIndex: Math.floor((params.offset || 0) / (params.limit || DEFAULT_TABLE_PAGE_SIZE)), pageSize: params.limit || DEFAULT_TABLE_PAGE_SIZE, }, }, manualPagination: true, manualSorting: true, getCoreRowModel: getCoreRowModel(), onSortingChange: (updater) => { const next = typeof updater === 'function' ? updater(sorting) : updater; const first = next[0]; onParamsChange({ ...params, sort: first?.id ?? params.sort, order: first ? (first.desc ? 'desc' : 'asc') : params.order, offset: 0, }); }, }); return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { const canSort = header.column.getCanSort(); const sorted = header.column.getIsSorted(); return ( {header.isPlaceholder ? null : canSort ? ( ) : ( flexRender(header.column.columnDef.header, header.getContext()) )} ); })} ))} {isLoading ? ( Array.from({ length: 5 }).map((_, i) => ( {columns.map((_, j) => ( ))} )) ) : table.getRowModel().rows.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} )) ) : ( {empty} )}
); }