diff --git a/frontend/src/components/pages/ReportingPage.js b/frontend/src/components/pages/ReportingPage.js index 3acf5cc..8a4800e 100644 --- a/frontend/src/components/pages/ReportingPage.js +++ b/frontend/src/components/pages/ReportingPage.js @@ -1061,42 +1061,22 @@ function TableCell({ colKey, finding, canWrite, onCveMouseEnter, onCveMouseLeave const wf = finding.workflow; if (!wf || !wf.id) return —; const ws = workflowStyle(wf.state); - const isEditable = ['reworked', 'rejected', 'expired'].includes((wf.state || '').toLowerCase()); - - const handleBadgeClick = isEditable ? () => { - const numericId = parseInt(String(wf.id).replace(/\D/g, ''), 10); - const sub = fpSubmissions.find(s => s.ivanti_workflow_batch_id === numericId); - if (sub) onEditSubmission(sub); - } : undefined; - return ( { - e.currentTarget.style.borderColor = ws.text; - e.currentTarget.style.background = ws.bg.replace('0.12', '0.2'); - } : undefined} - onMouseLeave={isEditable ? (e) => { - e.currentTarget.style.borderColor = ws.border; - e.currentTarget.style.background = ws.bg; - } : undefined} > {wf.id} {wf.state} - {isEditable && } ); @@ -3159,9 +3139,33 @@ export default function VulnerabilityTriagePage({ filterDate, filterEXC }) { const [fpModalItems, setFpModalItems] = useState([]); // FP Submission editing state - const [fpSubmissions, setFpSubmissions] = useState([]); + const [fpSubmissionsRaw, setFpSubmissions] = useState([]); const [editSubmission, setEditSubmission] = useState(null); + // Enrich submissions with actual Ivanti workflow state from findings data + const fpSubmissions = useMemo(() => { + if (fpSubmissionsRaw.length === 0 || findings.length === 0) return fpSubmissionsRaw; + const stateMap = { + 'reworked': 'rework', 'rejected': 'rejected', 'expired': 'rejected', + 'approved': 'approved', 'requested': 'submitted', 'actionable': 'submitted', + }; + return fpSubmissionsRaw.map(sub => { + let findingIds; + try { findingIds = JSON.parse(sub.finding_ids_json || '[]'); } catch { return sub; } + if (findingIds.length === 0) return sub; + const matchedFinding = findings.find(f => + f.workflow && findingIds.includes(String(f.id)) + ); + if (!matchedFinding || !matchedFinding.workflow) return sub; + const ivantiState = (matchedFinding.workflow.state || '').toLowerCase(); + const mappedStatus = stateMap[ivantiState]; + if (mappedStatus && mappedStatus !== sub.lifecycle_status) { + return { ...sub, lifecycle_status: mappedStatus }; + } + return sub; + }); + }, [fpSubmissionsRaw, findings]); + // Queue API helpers const fetchQueue = useCallback(async () => { setQueueLoading(true);