feat(agent): PreScanWizard im ComplianceCheckTab (P79 sichtbar)
Wizard war bisher nur im DocCheckTab eingebaut, der aber nirgends im UI gemountet ist. Daher: alle Compliance-Checks schickten scan_context=null, P72 Branchen-Filter wirkte nie. Fix: PreScanWizard ins ComplianceCheckTab über die Document-Rows gestellt. Submit-Button disabled bis alle 8 Felder (Branche, B2B/B2C, Direkt-Vertrieb, Rechtsform, Konzern, MA, Besondere Daten, Drittland) gesetzt sind. scan_context wird im POST body mitgesendet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import React, { useState, useCallback } from 'react'
|
|||||||
import { ChecklistView } from './ChecklistView'
|
import { ChecklistView } from './ChecklistView'
|
||||||
import { DocumentRow } from './DocumentRow'
|
import { DocumentRow } from './DocumentRow'
|
||||||
import { MigrationPanel } from './MigrationPanel'
|
import { MigrationPanel } from './MigrationPanel'
|
||||||
|
import { PreScanWizard, useScanContext, isContextComplete } from './PreScanWizard'
|
||||||
|
|
||||||
const DOCUMENT_TYPES = [
|
const DOCUMENT_TYPES = [
|
||||||
{ id: 'dse', label: 'DSI (Datenschutzinformation)', required: true },
|
{ id: 'dse', label: 'DSI (Datenschutzinformation)', required: true },
|
||||||
@@ -72,6 +73,7 @@ interface HistoryEntry {
|
|||||||
|
|
||||||
export function ComplianceCheckTab() {
|
export function ComplianceCheckTab() {
|
||||||
const [docs, setDocs] = useState<DocsState>(initState)
|
const [docs, setDocs] = useState<DocsState>(initState)
|
||||||
|
const [scanContext, setScanContext] = useScanContext()
|
||||||
const [useAgent, setUseAgent] = useState(false)
|
const [useAgent, setUseAgent] = useState(false)
|
||||||
const [tdmOverride, setTdmOverride] = useState(false)
|
const [tdmOverride, setTdmOverride] = useState(false)
|
||||||
const [tdmOverrideReason, setTdmOverrideReason] = useState('')
|
const [tdmOverrideReason, setTdmOverrideReason] = useState('')
|
||||||
@@ -201,6 +203,8 @@ export function ComplianceCheckTab() {
|
|||||||
use_agent: useAgent,
|
use_agent: useAgent,
|
||||||
tdm_override: tdmOverride && tdmOverrideReason.trim().length >= 10,
|
tdm_override: tdmOverride && tdmOverrideReason.trim().length >= 10,
|
||||||
tdm_override_reason: tdmOverrideReason.trim(),
|
tdm_override_reason: tdmOverrideReason.trim(),
|
||||||
|
// P79 — Pre-Scan-Wizard 8 Pflichtfelder; treibt MC-Scope-Filter (P72)
|
||||||
|
scan_context: scanContext,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
if (!startRes.ok) throw new Error(`Pruefung konnte nicht gestartet werden: ${startRes.status}`)
|
if (!startRes.ok) throw new Error(`Pruefung konnte nicht gestartet werden: ${startRes.status}`)
|
||||||
@@ -270,6 +274,8 @@ export function ComplianceCheckTab() {
|
|||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contextReady = isContextComplete(scanContext)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{/* Info box */}
|
{/* Info box */}
|
||||||
@@ -282,6 +288,9 @@ export function ComplianceCheckTab() {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* P79 Pre-Scan-Wizard — 8 Pflichtfelder zum MC-Scope-Filter (P72) */}
|
||||||
|
<PreScanWizard value={scanContext} onChange={setScanContext} />
|
||||||
|
|
||||||
{/* Document rows */}
|
{/* Document rows */}
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{DOCUMENT_TYPES.map(dt => (
|
{DOCUMENT_TYPES.map(dt => (
|
||||||
@@ -328,10 +337,11 @@ export function ComplianceCheckTab() {
|
|||||||
{tdmOverride && <input type="text" value={tdmOverrideReason} onChange={e => setTdmOverrideReason(e.target.value)} placeholder="z.B. Auftragsbeziehung Safetykon GmbH, Email Hr. X vom 18.05.2026" className="w-full px-3 py-2 text-xs border border-amber-300 rounded bg-white" />}
|
{tdmOverride && <input type="text" value={tdmOverrideReason} onChange={e => setTdmOverrideReason(e.target.value)} placeholder="z.B. Auftragsbeziehung Safetykon GmbH, Email Hr. X vom 18.05.2026" className="w-full px-3 py-2 text-xs border border-amber-300 rounded bg-white" />}
|
||||||
{tdmOverride && tdmOverrideReason.trim().length < 10 && <p className="text-[10px] text-amber-700">Pflicht: Reason mit min. 10 Zeichen (Audit-Spur).</p>}
|
{tdmOverride && tdmOverrideReason.trim().length < 10 && <p className="text-[10px] text-amber-700">Pflicht: Reason mit min. 10 Zeichen (Audit-Spur).</p>}
|
||||||
</div>
|
</div>
|
||||||
{/* Submit button */}
|
{/* Submit button — Wizard muss vollstaendig sein (P79) */}
|
||||||
<button
|
<button
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
disabled={loading || filledCount === 0 || (tdmOverride && tdmOverrideReason.trim().length < 10)}
|
disabled={loading || filledCount === 0 || !contextReady || (tdmOverride && tdmOverrideReason.trim().length < 10)}
|
||||||
|
title={!contextReady ? 'Pre-Scan-Wizard zuerst vollstaendig ausfuellen' : ''}
|
||||||
className="w-full px-4 py-3 bg-purple-600 text-white rounded-lg font-medium hover:bg-purple-700 disabled:opacity-50 transition-colors text-sm flex items-center justify-center gap-2"
|
className="w-full px-4 py-3 bg-purple-600 text-white rounded-lg font-medium hover:bg-purple-700 disabled:opacity-50 transition-colors text-sm flex items-center justify-center gap-2"
|
||||||
>
|
>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@@ -342,6 +352,8 @@ export function ComplianceCheckTab() {
|
|||||||
</svg>
|
</svg>
|
||||||
Pruefe...
|
Pruefe...
|
||||||
</>
|
</>
|
||||||
|
) : !contextReady ? (
|
||||||
|
'Pre-Scan-Wizard vollstaendig ausfuellen (oben)'
|
||||||
) : (
|
) : (
|
||||||
`Compliance-Check starten (${filledCount} Dokument${filledCount !== 1 ? 'e' : ''})`
|
`Compliance-Check starten (${filledCount} Dokument${filledCount !== 1 ? 'e' : ''})`
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user