3ef8c9b247
CI / detect-changes (push) Successful in 7s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Failing after 4s
CI / validate-canonical-controls (push) Successful in 11s
CI / loc-budget (push) Successful in 14s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m24s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
User-Vorgabe: pro Slot transparent zeigen WAS wir tun:
1. Was wurde geprueft (MC-Coverage, collapsible)
2. Speedometer mit Severity-Verteilung
3. LLM-Eskalation-Log (wenn benutzt)
4. Findings sortiert HIGH->LOW, je Card:
- Methodik-Badge (MC / Regex / KB / LLM / Cross)
- Gesetzliche Basis (Norm-Block, violett)
- Befund (Zitat-Block, amber)
- Empfehlung -> 'Pflicht-Massnahme' bei HIGH,
'Best-Practice' bei MEDIUM/LOW, 'LLM-Vorschlag'
bei LLM-Quelle
5. Maszahmen-Plan (gerollupte Recommendations mit
related_finding_ids + Aufwand)
Refactor: ein File AgentTestTab.tsx (519 LOC) -> 7 Files:
_agentTypes.ts (Types + Methodik-Konstanten)
AgentSpeedometer.tsx
AgentMcCoverage.tsx
AgentFindingCard.tsx
AgentRecommendationCard.tsx
AgentSlotCard.tsx
AgentTestTab.tsx (Top-Level, schlank)
Plus Methodik-Info-Erklaerung am Tab-Anfang + Disclaimer.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
58 lines
1.9 KiB
TypeScript
58 lines
1.9 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* Speedometer + Color-Legende für eine MC-Auswertung.
|
|
* Zeigt 5 Klassen: OK / n/a / HIGH / MEDIUM / LOW als horizontaler Balken.
|
|
*/
|
|
|
|
import React from 'react'
|
|
|
|
interface Props {
|
|
total: number
|
|
ok: number
|
|
na: number
|
|
high: number
|
|
medium: number
|
|
low: number
|
|
}
|
|
|
|
export function AgentSpeedometer({ total, ok, na, high, medium, low }: Props) {
|
|
const safeTotal = Math.max(total, 1)
|
|
return (
|
|
<div className="space-y-1">
|
|
<div className="text-xs text-gray-500">
|
|
{total} Machine-Checks (MCs) durchlaufen
|
|
</div>
|
|
<div className="flex h-4 rounded overflow-hidden border">
|
|
<Bar pct={(ok / safeTotal) * 100} color="#10b981" />
|
|
<Bar pct={(na / safeTotal) * 100} color="#94a3b8" />
|
|
<Bar pct={(high / safeTotal) * 100} color="#dc2626" />
|
|
<Bar pct={(medium / safeTotal) * 100} color="#f59e0b" />
|
|
<Bar pct={(low / safeTotal) * 100} color="#3b82f6" />
|
|
</div>
|
|
<div className="flex flex-wrap gap-3 text-xs">
|
|
<Legend color="#10b981" label={`OK ${ok}`} title="Geprüft & erfüllt" />
|
|
<Legend color="#94a3b8" label={`n/a ${na}`} title="Nicht anwendbar (Branche, B2C, …)" />
|
|
<Legend color="#dc2626" label={`HIGH ${high}`} title="Pflichtangabe fehlt / hartes Risiko" />
|
|
<Legend color="#f59e0b" label={`MEDIUM ${medium}`} title="Ergänzung empfohlen" />
|
|
<Legend color="#3b82f6" label={`LOW ${low}`} title="Best-Practice-Hinweis" />
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function Bar({ pct, color }: { pct: number; color: string }) {
|
|
return <div style={{ width: `${pct}%`, background: color }} />
|
|
}
|
|
|
|
function Legend({
|
|
color, label, title,
|
|
}: { color: string; label: string; title?: string }) {
|
|
return (
|
|
<span className="inline-flex items-center gap-1" title={title}>
|
|
<span style={{ background: color }} className="w-2 h-2 inline-block rounded" />
|
|
<span>{label}</span>
|
|
</span>
|
|
)
|
|
}
|