import { Fragment, useEffect } from "react"; import { ColumnDef, flexRender, getCoreRowModel, getExpandedRowModel, Row, useReactTable, } from "@tanstack/react-table"; import { Table, TableHead, TableHeaderCell, TableBody, TableRow, TableCell, } from "@tremor/react"; interface DataTableProps { data: TData[]; columns: ColumnDef[]; renderSubComponent: (props: { row: Row }) => React.ReactElement; getRowCanExpand: (row: Row) => boolean; isLoading?: boolean; expandedRequestId?: string | null; onRowExpand?: (requestId: string | null) => void; setSelectedKeyIdInfoView?: (keyId: string | null) => void; loadingMessage?: string; noDataMessage?: string; } export function DataTable({ data = [], columns, getRowCanExpand, renderSubComponent, isLoading = false, expandedRequestId, onRowExpand, loadingMessage = "🚅 Loading logs...", noDataMessage = "No logs found", }: DataTableProps) { const table = useReactTable({ data, columns, getRowCanExpand, getCoreRowModel: getCoreRowModel(), getExpandedRowModel: getExpandedRowModel(), state: { expanded: expandedRequestId ? data.reduce((acc, row, index) => { if (row.request_id === expandedRequestId) { acc[index] = true; } return acc; }, {} as Record) : {}, }, onExpandedChange: (updater) => { if (!onRowExpand) return; // Get current expanded state const currentExpanded = expandedRequestId ? data.reduce((acc, row, index) => { if (row.request_id === expandedRequestId) { acc[index] = true; } return acc; }, {} as Record) : {}; // Calculate new expanded state const newExpanded = typeof updater === 'function' ? updater(currentExpanded) : updater; // If empty, it means we're closing the expanded row if (Object.keys(newExpanded).length === 0) { onRowExpand(null); return; } // Find the request_id of the expanded row const expandedIndex = Object.keys(newExpanded)[0]; const expandedRow = expandedIndex !== undefined ? data[parseInt(expandedIndex)] : null; // Call the onRowExpand callback with the request_id onRowExpand(expandedRow ? expandedRow.request_id : null); }, }); // No need for the useEffect here as we're handling everything in onExpandedChange return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( {header.isPlaceholder ? null : ( flexRender( header.column.columnDef.header, header.getContext() ) )} ); })} ))} {isLoading ?

{loadingMessage}

: table.getRowModel().rows.length > 0 ? table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext() )} ))} {row.getIsExpanded() && ( {renderSubComponent({ row })} )} )) :

{noDataMessage}

}
); }