import { useState, useMemo } from 'react'; import { createColumnHelper, flexRender, getCoreRowModel, useReactTable, } from '@tanstack/react-table'; import { ScrollArea } from '../components/ScrollArea'; import { JsonTree } from '../components/JsonTree'; import { SSENetworkEntry } from '../state/model'; export type SSEMessagesTabProps = { selectedRequest: SSENetworkEntry; }; interface SSEMessageRow { id: string; type: string; data: string; timestamp: number; } const columnHelper = createColumnHelper(); const formatPreviewData = (data: string) => { return ( {data.substring(0, 100) + (data.length > 100 ? '...' : '')} ); }; const formatTimestamp = (timestamp: number) => { const date = new Date(timestamp); const timeString = date.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit', }); const milliseconds = date.getMilliseconds().toString().padStart(3, '0'); return `${timeString}.${milliseconds}`; }; const columns = [ columnHelper.accessor('timestamp', { header: 'Timestamp', cell: ({ getValue }) => (
{formatTimestamp(getValue())}
), size: 120, }), columnHelper.accessor('type', { header: 'Type', cell: ({ getValue }) => (
{getValue()}
), size: 100, }), columnHelper.accessor('data', { header: 'Data', cell: ({ getValue }) => { const data = getValue(); return formatPreviewData(data); }, size: 300, }), ]; export const SSEMessagesTab = ({ selectedRequest }: SSEMessagesTabProps) => { // Capture the selected message, so when it gets removed (message limit), it's still displayed const [selectedMessage, setSelectedMessage] = useState( null ); const formatData = (data: string) => { if (typeof data === 'string') { try { const jsonData = JSON.parse(data); return (
); } catch { // Fallback to pre tag if JSON parsing fails return (
            {data}
          
); } } return 'Invalid data'; }; const tableData = useMemo(() => { return selectedRequest.messages.map( (message): SSEMessageRow => ({ id: message.id, type: message.type, data: message.data, timestamp: message.timestamp, }) ); }, [selectedRequest.messages]); const table = useReactTable({ data: tableData, columns, getCoreRowModel: getCoreRowModel(), }); if (selectedRequest.messages.length === 0) { return (
No SSE messages available for this connection. Messages will appear here when the SSE connection receives data.
); } return (
{/* Messages Table */}
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( setSelectedMessage(row.original)} > {row.getVisibleCells().map((cell) => ( ))} ))}
{header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext() )}
{flexRender( cell.column.columnDef.cell, cell.getContext() )}
{/* Message Details Panel */} {selectedMessage && (

Message Details

Type: {selectedMessage.type}
Timestamp: {formatTimestamp(selectedMessage.timestamp)}
Content:
{formatData(selectedMessage.data)}
)}
); };