import type { ColumnDef, ColumnFiltersState, Row, SortingState, VisibilityState, } from "@tanstack/react-table"; import { flexRender, getCoreRowModel, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getSortedRowModel, useReactTable, } from "@tanstack/react-table"; import { useState } from "react"; import { useVirtual } from "react-virtual"; import classNames from "@calcom/lib/classNames"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../table/TableNew"; import type { ActionItem } from "./DataTableSelectionBar"; import { DataTableSelectionBar } from "./DataTableSelectionBar"; import type { FilterableItems } from "./DataTableToolbar"; import { DataTableToolbar } from "./DataTableToolbar"; export interface DataTableProps { tableContainerRef: React.RefObject; columns: ColumnDef[]; data: TData[]; searchKey?: string; filterableItems?: FilterableItems; selectionOptions?: ActionItem[]; tableCTA?: React.ReactNode; isLoading?: boolean; onRowMouseclick?: (row: Row) => void; onScroll?: (e: React.UIEvent) => void; CTA?: React.ReactNode; tableOverlay?: React.ReactNode; } export function DataTable({ columns, data, filterableItems, tableCTA, searchKey, selectionOptions, tableContainerRef, isLoading, tableOverlay, /** This should only really be used if you dont have actions in a row. */ onRowMouseclick, onScroll, }: DataTableProps) { const [rowSelection, setRowSelection] = useState({}); const [columnVisibility, setColumnVisibility] = useState({}); const [columnFilters, setColumnFilters] = useState([]); const [sorting, setSorting] = useState([]); const table = useReactTable({ data, columns, state: { sorting, columnVisibility, rowSelection, columnFilters, }, enableRowSelection: true, debugTable: true, manualPagination: true, onRowSelectionChange: setRowSelection, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, onColumnVisibilityChange: setColumnVisibility, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), getFacetedRowModel: getFacetedRowModel(), getFacetedUniqueValues: getFacetedUniqueValues(), }); const { rows } = table.getRowModel(); const rowVirtualizer = useVirtual({ parentRef: tableContainerRef, size: rows.length, overscan: 10, }); const { virtualItems: virtualRows, totalSize } = rowVirtualizer; const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0; const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0) : 0; return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} ); })} ))} {paddingTop > 0 && ( )} {virtualRows && !isLoading ? ( virtualRows.map((virtualRow) => { const row = rows[virtualRow.index] as Row; return ( onRowMouseclick && onRowMouseclick(row)} className={classNames(onRowMouseclick && "hover:cursor-pointer")}> {row.getVisibleCells().map((cell) => { return ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ); })} ); }) ) : ( No results. )} {paddingBottom > 0 && ( )} {tableOverlay && tableOverlay}
{/* */}
); }