import React from 'react'; import { Box, Paper, Typography, Chip, IconButton, Tooltip, LinearProgress, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination, } from '@mui/material'; import { History as HistoryIcon, Delete as DeleteIcon, Visibility as VisibilityIcon, ContentCopy as CopyIcon, Facebook as FacebookIcon, Cancel as CancelIcon, Replay as ResumeIcon, } from '@mui/icons-material'; import type { AnalysisSession, PaginationInfo } from './history-types'; import { getRiskIcon, getRiskCategoryColor, formatDuration, formatDate } from './history-helpers'; // Sessions still in flight can be canceled (agent-v3 /:id/cancel). const CANCELABLE = new Set(['pending', 'running', 'processing']); // Failed/canceled sessions can be resumed from checkpoint (/:id/resume). const RESUMABLE = new Set(['failed', 'canceled']); interface Props { loading: boolean; analyses: AnalysisSession[]; pagination: PaginationInfo; copiedId: string | null; onPageChange: (event: unknown, newPage: number) => void; onRowsPerPageChange: (event: React.ChangeEvent) => void; onViewDetails: (sessionId: string) => void; onDeleteClick: (session: AnalysisSession) => void; onCopyId: (e: React.MouseEvent, id: string) => void; onSocialPostClick?: (session: AnalysisSession) => void; onCancelClick?: (session: AnalysisSession) => void; onResumeClick?: (session: AnalysisSession) => void; } export const HistoryTable: React.FC = ({ loading, analyses, pagination, copiedId, onPageChange, onRowsPerPageChange, onViewDetails, onDeleteClick, onCopyId, onSocialPostClick, onCancelClick, onResumeClick, }) => ( {loading && } Session ID Date Email Source Risk Techniques AI % Claims Duration Actions {!loading && analyses.length === 0 ? ( No analyses found ) : ( analyses.map((analysis) => ( onViewDetails(analysis.session_id)} > e.stopPropagation()}> {analysis.session_id.substring(0, 8)}... onCopyId(e, analysis.session_id)}> {formatDate(analysis.started_at)} {analysis.input_type} {analysis.user_email || No email} {(analysis.source_verdict || analysis.domain) && ( {analysis.source_publication || analysis.domain || ''} {(analysis.source_verdict || analysis.domain_verdict) && ( )} )} {analysis.risk_score !== null ? ( ) : ( )} {analysis.techniques_count !== null ? ( 0 ? 'warning' : 'default'} variant="outlined" /> ) : '-'} {analysis.ai_probability !== null ? ( 50 ? 'warning' : 'default'} variant="outlined" /> ) : '-'} {analysis.total_claims !== null ? ( {analysis.total_claims} ) : '-'} {formatDuration(analysis.total_duration_ms)} e.stopPropagation()}> onViewDetails(analysis.session_id)} title="View details" > {onSocialPostClick && ( onSocialPostClick(analysis)} title="Post to Facebook" sx={{ color: '#1877F2' }} > )} {onCancelClick && CANCELABLE.has(analysis.status) && ( onCancelClick(analysis)} title="Cancel running analysis" color="warning" > )} {onResumeClick && RESUMABLE.has(analysis.status) && ( onResumeClick(analysis)} title="Resume from checkpoint (re-runs only unfinished components)" color="primary" > )} onDeleteClick(analysis)} title="Delete" color="error" > )) )}
);