import { useState, type FormEvent } from 'react'; import { AssessorApiClient } from '../../api/assessor-api-client'; import { OperationProgressDialog } from '../../components/OperationProgress/OperationProgress'; import type { PolicyAnalysisActionStatus, PolicyAnalysisOverview } from '../../domain/policy-analysis-overview'; import type { CreateEnvironmentProfileRequest, EnvironmentProfileScope } from '../../domain/gpo-snapshot-aggregation'; const assessorApi = new AssessorApiClient(); interface ContextDraft { productFamily: string; productVersion: string; role: string; scope: EnvironmentProfileScope; } interface ProfileDraft { name: string; domainKey: string; supersedesProfileId: string; operatingSystem: ContextDraft; includeProduct: boolean; product: ContextDraft; } const emptyContext = (): ContextDraft => ({ productFamily: '', productVersion: '', role: '', scope: 'computer' }); const emptyProfile = (): ProfileDraft => ({ name: '', domainKey: '', supersedesProfileId: '', operatingSystem: emptyContext(), includeProduct: false, product: emptyContext() }); function contextId(kind: 'operating-system' | 'product', context: ContextDraft): string { return [kind, context.productFamily, context.productVersion, context.role, context.scope] .map(value => value.trim().toLocaleLowerCase('en-US').replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')) .join(':'); } function shortId(value: string): string { return value.length > 22 ? `${value.slice(0, 10)}…${value.slice(-8)}` : value; } function actionLabel(status: PolicyAnalysisActionStatus): string { if (status === 'completed') return 'Completed'; if (status === 'blocked') return 'Blocked'; return status === 'review-only' ? 'Run as review-only' : 'Run'; } function ReasonCodes({ codes }: { codes: string[] }) { return codes.length ? {codes.map(code => {code})} : null; } export function PolicyAnalysisActions({ projectId, overview, onChanged }: { projectId: string; overview: PolicyAnalysisOverview; onChanged(): Promise; }) { const [draft, setDraft] = useState(emptyProfile); const [busyId, setBusyId] = useState(); const [progress, setProgress] = useState(); const [feedback, setFeedback] = useState<{ tone: 'success' | 'error'; message: string }>(); const profileById = new Map(overview.profiles.map(profile => [profile.id, profile])); const run = async (id: string, action: () => Promise, success: string, progressLabel: string) => { setBusyId(id); setProgress(progressLabel); setFeedback(undefined); try { await action(); setFeedback({ tone: 'success', message: success }); await onChanged(); return true; } catch (reason) { setFeedback({ tone: 'error', message: reason instanceof Error ? reason.message : 'The policy action failed.' }); return false; } finally { setBusyId(undefined); setProgress(undefined); } }; const createProfile = async (event: FormEvent) => { event.preventDefault(); const os = draft.operatingSystem; const contexts: CreateEnvironmentProfileRequest['contexts'] = [{ id: contextId('operating-system', os), kind: 'operating-system' as const, productFamily: os.productFamily.trim(), productVersion: os.productVersion.trim(), role: os.role.trim(), scope: os.scope }]; if (draft.includeProduct) { const product = draft.product; contexts.push({ id: contextId('product', product), kind: 'product', productFamily: product.productFamily.trim(), productVersion: product.productVersion.trim(), role: product.role.trim(), scope: product.scope }); } const created = await run('create-profile', () => assessorApi.createEnvironmentProfile(projectId, { name: draft.name.trim(), domainKey: draft.domainKey.trim() || undefined, supersedesProfileId: draft.supersedesProfileId || undefined, contexts }), 'Environment profile persisted.', 'Saving profile'); if (created) setDraft(emptyProfile()); }; const updateContext = (key: 'operatingSystem' | 'product', patch: Partial) => { setDraft(current => ({ ...current, [key]: { ...current[key], ...patch } })); }; const validOs = draft.name.trim() && draft.operatingSystem.productFamily.trim() && draft.operatingSystem.productVersion.trim() && draft.operatingSystem.role.trim(); const validProduct = !draft.includeProduct || draft.product.productFamily.trim() && draft.product.productVersion.trim() && draft.product.role.trim(); return
Analysis Workflow

Profiles and Runs

{overview.profiles.length}

Only actions derived from persisted project and catalog evidence are offered. Review-only runs remain ineligible for findings unless every downstream invariant is satisfied.

{feedback &&
{feedback.message}
}
Create Environment Profile
void createProfile(event)}>
Operating system context
{draft.includeProduct &&
Product context
}

Reprocessing

{!overview.actions.reprocess.length ?

No processed GPO source available.

: overview.actions.reprocess.slice(0, 20).map(action =>
GPO source{shortId(action.artifactId)}
)}

Snapshot aggregation

{!overview.actions.aggregate.length ?

Create a profile and process a GPO backup first.

: overview.actions.aggregate.slice(0, 20).map(action =>
{profileById.get(action.environmentProfileId)?.name ?? 'Environment profile'}{action.sourceAnalysisRunIds.length} identity run
)}

Baseline evaluation

{!overview.actions.evaluate.length ?

No snapshot aggregation available.

: overview.actions.evaluate.slice(0, 20).map(action =>
{profileById.get(action.environmentProfileId)?.name ?? 'Environment profile'}{action.baselineAnalysisIds.length} baseline analysis source{action.baselineAnalysisIds.length === 1 ? '' : 's'}
)}

Finding Factory

{!overview.actions.createFindings.length ?

No policy evaluation available.

: overview.actions.createFindings.slice(0, 20).map(action =>
{action.eligibleResultCount} eligible result{action.eligibleResultCount === 1 ? '' : 's'}{shortId(action.evaluationRunId)}
)}
; }