import { useEffect, useId, useState } from 'react'; import { AssessorApiClient } from '../../api/assessor-api-client'; import type { BackendStatus } from '../../app/app-state'; import { useEnginePreferences } from '../../app/engine-preferences'; import type { RegulatoryControlFinding, RegulatoryControlOverviewResponse } from '../regulatory-mapping'; import { useRegulatoryDecisionRevision } from './decision-revision'; import './compliance.css'; const assessorApi = new AssessorApiClient(); interface Props { projectId?: string; assessmentIds?: readonly string[]; scanRunIds?: readonly string[]; backendStatus: BackendStatus; onOpenFindings(findings: RegulatoryControlFinding[]): void; } type OverviewState = { status: 'idle' | 'loading' } | { status: 'error' } | { status: 'ready'; overview: RegulatoryControlOverviewResponse }; /** Client Info `ISO controls`: accepted controls of the timeslot's deviations, laid out like the Context heatmap. */ export function ClientIsoControls({ projectId, assessmentIds = [], scanRunIds = [], backendStatus, onOpenFindings }: Props) { const available = useEnginePreferences().compliance; const revision = useRegulatoryDecisionRevision(); const id = useId(); const [state, setState] = useState({ status: 'idle' }); const scopeKey = JSON.stringify([projectId, assessmentIds, scanRunIds]); const enabled = available && backendStatus === 'connected' && Boolean(projectId) && (assessmentIds.length > 0 || scanRunIds.length > 0); useEffect(() => { if (!enabled || !projectId) { setState({ status: 'idle' }); return; } let active = true; setState({ status: 'loading' }); assessorApi.getRegulatoryControlOverview(projectId, { assessmentIds: [...assessmentIds], scanRunIds: [...scanRunIds] }) .then(overview => { if (active) setState({ status: 'ready', overview }); }) .catch(() => { if (active) setState({ status: 'error' }); }); return () => { active = false; }; }, [enabled, revision, scopeKey]); // eslint-disable-line react-hooks/exhaustive-deps if (!available || state.status === 'idle') return null; return

ISO controls

{state.status === 'ready' && Findings: {state.overview.findingCount.toLocaleString('en-US')}}
{state.status === 'error' &&

ISO controls could not be loaded.

} {state.status === 'ready' && !state.overview.controls.length &&

No accepted ISO controls in this timeslot.

} {state.status === 'ready' && state.overview.controls.length > 0 &&
{state.overview.controls.map(control => )}
}
; }