feat: 7 Analyse-Module auf 100% — Backend-Endpoints, DB-Model, Frontend-Persistenz
Alle 7 Analyse-Module (Requirements → Report) von ~80% auf 100% gebracht: - Modul 1 (Requirements): POST/DELETE Endpoints + Frontend-Anbindung + Rollback - Modul 2 (Controls): Evidence-Linking UI mit Validity-Badge - Modul 3 (Evidence): Pagination (Frontend + Backend) - Modul 4 (Risk Matrix): Mitigation-UI, Residual Risk, Status-Workflow - Modul 5 (AI Act): AISystemDB Model, 6 CRUD-Endpoints, Backend-Persistenz - Modul 6 (Audit Checklist): PDF-Download + Session-History - Modul 7 (Audit Report): Detail-Seite mit Checklist Sign-Off + Navigation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -310,15 +310,19 @@ export default function EvidencePage() {
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [uploading, setUploading] = useState(false)
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const [page, setPage] = useState(1)
|
||||
const [pageSize] = useState(20)
|
||||
const [total, setTotal] = useState(0)
|
||||
|
||||
// Fetch evidence from backend on mount
|
||||
// Fetch evidence from backend on mount and when page changes
|
||||
useEffect(() => {
|
||||
const fetchEvidence = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const res = await fetch('/api/sdk/v1/compliance/evidence')
|
||||
const res = await fetch(`/api/sdk/v1/compliance/evidence?page=${page}&limit=${pageSize}`)
|
||||
if (res.ok) {
|
||||
const data = await res.json()
|
||||
if (data.total !== undefined) setTotal(data.total)
|
||||
const backendEvidence = data.evidence || data
|
||||
if (Array.isArray(backendEvidence) && backendEvidence.length > 0) {
|
||||
const mapped: SDKEvidence[] = backendEvidence.map((e: Record<string, unknown>) => ({
|
||||
@@ -380,7 +384,7 @@ export default function EvidencePage() {
|
||||
}
|
||||
|
||||
fetchEvidence()
|
||||
}, []) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
}, [page, pageSize]) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// Convert SDK evidence to display evidence
|
||||
const displayEvidence: DisplayEvidence[] = state.evidence.map(ev => {
|
||||
@@ -638,6 +642,34 @@ export default function EvidencePage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Pagination */}
|
||||
{!loading && total > pageSize && (
|
||||
<div className="flex items-center justify-between bg-white rounded-xl border border-gray-200 p-4">
|
||||
<span className="text-sm text-gray-500">
|
||||
Zeige {((page - 1) * pageSize) + 1}–{Math.min(page * pageSize, total)} von {total} Nachweisen
|
||||
</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => setPage(p => Math.max(1, p - 1))}
|
||||
disabled={page <= 1}
|
||||
className="px-3 py-1 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 disabled:opacity-40 disabled:cursor-not-allowed"
|
||||
>
|
||||
Zurueck
|
||||
</button>
|
||||
<span className="text-sm text-gray-700">
|
||||
Seite {page} von {Math.ceil(total / pageSize)}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => setPage(p => Math.min(Math.ceil(total / pageSize), p + 1))}
|
||||
disabled={page >= Math.ceil(total / pageSize)}
|
||||
className="px-3 py-1 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 disabled:opacity-40 disabled:cursor-not-allowed"
|
||||
>
|
||||
Weiter
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!loading && filteredEvidence.length === 0 && state.controls.length > 0 && (
|
||||
<div className="bg-white rounded-xl border border-gray-200 p-12 text-center">
|
||||
<div className="w-16 h-16 mx-auto bg-gray-100 rounded-full flex items-center justify-center mb-4">
|
||||
|
||||
Reference in New Issue
Block a user