import * as React from 'react'; import { useMemo } from 'react'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import type { ColumnDef, ColumnFiltersState, PaginationState, SortingState, Updater, VisibilityState, } from '@tanstack/react-table'; import { flexRender, getCoreRowModel, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, } from '@tanstack/react-table'; import type { DataTableChildren } from '../data-table'; import { Skeleton } from '../skeleton'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../table'; import { DataTableToolbar } from './data-table-toolbar'; interface DataTableProps { columns: ColumnDef[]; data: TData[]; perPage?: number; currentPage?: number; totalPages?: number; onPaginationChange?: (_page: number, _perPage: number) => void; children?: DataTableChildren; stats?: Record; onStatusFilterChange?: (values: string[]) => void; selectedStatusValues?: string[]; onTimePeriodFilterChange?: (values: string[]) => void; selectedTimePeriodValues?: string[]; onSourceFilterChange?: (values: string[]) => void; selectedSourceValues?: string[]; onResetFilters?: () => void; isStatusFiltered?: boolean; isTimePeriodFiltered?: boolean; isSourceFiltered?: boolean; showSourceFilter?: boolean; skeleton?: { enable: boolean; rows: number; component?: React.ReactNode; }; error?: { enable: boolean; component?: React.ReactNode; }; emptyState?: { enable: boolean; component?: React.ReactNode; }; } export function DataTable({ columns, data, error, perPage, currentPage, totalPages, skeleton, onPaginationChange, children, stats, onStatusFilterChange, selectedStatusValues, onTimePeriodFilterChange, selectedTimePeriodValues, onSourceFilterChange, selectedSourceValues, onResetFilters, isStatusFiltered, isTimePeriodFiltered, isSourceFiltered, showSourceFilter, emptyState, }: DataTableProps) { const { _ } = useLingui(); const [rowSelection, setRowSelection] = React.useState({}); const [columnVisibility, setColumnVisibility] = React.useState({}); const [columnFilters, setColumnFilters] = React.useState([]); const [sorting, setSorting] = React.useState([]); const pagination = useMemo(() => { if (currentPage !== undefined && perPage !== undefined) { return { pageIndex: currentPage - 1, pageSize: perPage, }; } return { pageIndex: 0, pageSize: 0, }; }, [currentPage, perPage]); const manualPagination = Boolean(currentPage !== undefined && totalPages !== undefined); const onTablePaginationChange = (updater: Updater) => { if (typeof updater === 'function') { const newState = updater(pagination); onPaginationChange?.(newState.pageIndex + 1, newState.pageSize); } else { onPaginationChange?.(updater.pageIndex + 1, updater.pageSize); } }; const table = useReactTable({ data, columns, state: { sorting, columnVisibility, rowSelection, columnFilters, pagination: manualPagination ? pagination : undefined, }, manualPagination, pageCount: manualPagination ? totalPages : undefined, initialState: { pagination: { pageSize: 10, }, }, enableRowSelection: true, onRowSelectionChange: setRowSelection, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, onColumnVisibilityChange: setColumnVisibility, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getPaginationRowModel: getPaginationRowModel(), getSortedRowModel: getSortedRowModel(), getFacetedRowModel: getFacetedRowModel(), getFacetedUniqueValues: getFacetedUniqueValues(), onPaginationChange: onTablePaginationChange, }); return ( <>
{table.getRowModel().rows?.length || error?.enable || skeleton?.enable ? (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( {header.isPlaceholder ? null : 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())} ))} )) ) : error?.enable ? ( {error.component ?? ( Something went wrong. )} ) : skeleton?.enable ? ( Array.from({ length: skeleton.rows }).map((_, i) => ( {skeleton.component ?? } )) ) : null}
) : emptyState?.enable ? ( (emptyState.component ?? (
{_(msg`No results.`)}
)) ) : (
{_(msg`No results.`)}
)}
{children && (table.getRowModel().rows?.length || error?.enable || skeleton?.enable) && (
{children(table)}
)} ); }