import { useState } from 'react'; import type { DatasetSheet } from '../../domain/dataset'; import type { FindingRecord } from '../../domain/finding'; import { highlightText } from '../HighlightText/highlight-text'; import { useVirtualRows } from '../../hooks/use-virtual-rows'; interface Props { sheet: DatasetSheet; records: FindingRecord[]; search?: string; } /** * Geschaetzte Zeilenhoehe, nur fuer die Fenstermathematik - siehe * `RECORD_ROW_HEIGHT` in DatasetViewer.tsx fuer die gleiche Ueberlegung. * Groesser als die Kartenzeile, weil einzelne Spalten (Description, * Likelihood of Compromise) auch bei einer Rasterzeile umbrechen koennen. */ const TABLE_ROW_HEIGHT = 44; export function DataTable({ sheet, records, search }: Props) { const [markedRecordId, setMarkedRecordId] = useState(null); const rowWindow = useVirtualRows(records.length, TABLE_ROW_HEIGHT, 12); const columnCount = sheet.analysis.headers.length + 1; // Berechnete Geometrie der Virtualisierung als benannte Werte statt eines // literalen Inline-Style-Objekts - siehe DatasetViewer.tsx fuer dieselbe // Begruendung. const topSpacerStyle = { height: rowWindow.paddingTop, padding: 0, border: 0 }; const bottomSpacerStyle = { height: rowWindow.paddingBottom, padding: 0, border: 0 }; return (
{sheet.analysis.headers.map(header => )} {rowWindow.paddingTop > 0 && } {records.slice(rowWindow.startIndex, rowWindow.endIndex).map(record => ( setMarkedRecordId(record.id)}> {record.fields.map(field => )} ))} {rowWindow.paddingBottom > 0 && }
#{highlightText(header, search)}
{record.index + 1}{highlightText(field.value, search)}
); }