import { useId, useMemo } from 'react'; import { useApp } from '../../app/AppProvider'; import type { AssessmentContextResponse } from '../../api/assessor-api-contract'; import { contextHeatmap, contextHeatmapFindingCount, contextSeverityLabels } from '../../assessment-context/context-heatmap'; import { useAssessmentContext } from './use-assessment-context'; import './context-heatmap.css'; /** Existing scoped Context request is shared with Work and the Finding Reader. */ export function ClientContextHeatmap({ onOpenCluster }: { onOpenCluster(clusterId: string): void }) { const app = useApp(); const state = useAssessmentContext(Boolean(app.dataset), app.targetProjectId, app.activeAssessmentIds, app.activeScanRunIds, app.dataset); if (state.status === 'off' || state.status === 'unavailable') return null; if (state.status === 'loading') return

Context heatmap

Loading Context…

; if (state.status === 'error') return

Context heatmap

Context could not be loaded. Reopen the client to retry.

; return ; } export function ContextHeatmap({ context, onOpenCluster }: { context: AssessmentContextResponse; onOpenCluster(clusterId: string): void }) { const id = useId(); const cells = useMemo(() => contextHeatmap(context), [context]); const findingCount = useMemo(() => contextHeatmapFindingCount(context), [context]); return

Context heatmap

Findings: {findingCount.toLocaleString('en-US')}
{cells.map(({ cluster: item, reference, hasEvidence, scannerDeviations, gpoDeviations }) => )}
; }