From 58a3fb285f31db3897798c08781c156abac8eb84 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Thu, 7 May 2026 17:51:59 +0200 Subject: [PATCH] fix: Erstbewertung aus risk_assessment + Pagination + Projektname - Erstbewertung S/E/P liest jetzt aus risk_assessment statt hazard - Hazards: Pagination 50 pro Seite mit < > Navigation - Massnahmen: Lazy-Load 50 pro Accordion mit "Mehr laden" - Sidebar: Projektname (z.B. "Kniehebelpresse HP-500") prominent - Uebersicht: Nur 2 API-Calls (keine schweren Listen) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../_components/RiskAssessmentTable.tsx | 34 +++++++++++++++---- .../sdk/iace/[projectId]/mitigations/page.tsx | 11 ++++-- admin-compliance/app/sdk/iace/layout.tsx | 18 ++++++++-- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/admin-compliance/app/sdk/iace/[projectId]/hazards/_components/RiskAssessmentTable.tsx b/admin-compliance/app/sdk/iace/[projectId]/hazards/_components/RiskAssessmentTable.tsx index 66b6958..ed4f704 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/hazards/_components/RiskAssessmentTable.tsx +++ b/admin-compliance/app/sdk/iace/[projectId]/hazards/_components/RiskAssessmentTable.tsx @@ -139,13 +139,28 @@ export function RiskAssessmentTable({ projectId, hazards, onReassess, decisions, finally { setSaving(null) } } + const PAGE_SIZE = 50 + const [page, setPage] = useState(0) const sorted = [...hazards].sort((a, b) => (b.r_inherent || 0) - (a.r_inherent || 0)) + const totalPages = Math.ceil(sorted.length / PAGE_SIZE) + const paged = sorted.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE) return (

Risikobewertungstabelle (ISO 12100)

- {hazards.length} Gefaehrdungen +
+ {totalPages > 1 && ( +
+ + Seite {page + 1} / {totalPages} + +
+ )} + {hazards.length} Gefaehrdungen +
@@ -185,15 +200,20 @@ export function RiskAssessmentTable({ projectId, hazards, onReassess, decisions, - {sorted.map(h => { + {paged.map(h => { + const ra = (h as Record).risk_assessment as Record | null + const initS = ra?.severity || h.severity || 3 + const initE = ra?.exposure || h.exposure || 3 + const initP = ra?.probability || h.probability || 3 + const initA = h.avoidance || 0 const e = edits[h.id] - const initRpz = h.r_inherent || rpz(h.severity, h.exposure, h.probability, h.avoidance) + const initRpz = rpz(initS, initE, initP, initA) const afterRpz = e ? rpz(e.severity, e.exposure, e.probability, e.avoidance) : initRpz const afterLevel = getRiskLevelISO(afterRpz) const sil = silFromRpz(afterRpz) const pl = plFromRpz(afterRpz) const mc = mitCounts[h.id] || 0 - const changed = e && (e.severity !== h.severity || e.exposure !== h.exposure || e.probability !== h.probability || e.avoidance !== (h.avoidance || 3)) + const changed = e && (e.severity !== initS || e.exposure !== initE || e.probability !== initP) return ( @@ -208,9 +228,9 @@ export function RiskAssessmentTable({ projectId, hazards, onReassess, decisions, {/* Initial S/E/P/RPZ/Risk */} - {h.severity} - {h.exposure} - {h.probability} + {initS} + {initE} + {initP} {initRpz} diff --git a/admin-compliance/app/sdk/iace/[projectId]/mitigations/page.tsx b/admin-compliance/app/sdk/iace/[projectId]/mitigations/page.tsx index e657895..b88f2f2 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/mitigations/page.tsx +++ b/admin-compliance/app/sdk/iace/[projectId]/mitigations/page.tsx @@ -27,6 +27,7 @@ export default function MitigationsPage() { const [libraryFilter, setLibraryFilter] = useState() const [showSuggest, setShowSuggest] = useState(false) const [expanded, setExpanded] = useState>({ design: true, protection: true, information: true }) + const [mitPages, setMitPages] = useState>({ design: 1, protection: 1, information: 1 }) const [selected, setSelected] = useState>(new Set()) const [batchAction, setBatchAction] = useState<'verify' | 'delete' | null>(null) @@ -183,8 +184,8 @@ export default function MitigationsPage() {
Gefaehrdung
Status
- {/* Rows */} - {items.map((m) => ( + {/* Rows — paginated */} + {items.slice(0, (mitPages[type] || 1) * 50).map((m) => (
@@ -203,6 +204,12 @@ export default function MitigationsPage() {
))} + {items.length > (mitPages[type] || 1) * 50 && ( + + )}
)} diff --git a/admin-compliance/app/sdk/iace/layout.tsx b/admin-compliance/app/sdk/iace/layout.tsx index 13386d8..d14bff8 100644 --- a/admin-compliance/app/sdk/iace/layout.tsx +++ b/admin-compliance/app/sdk/iace/layout.tsx @@ -100,6 +100,15 @@ export default function IACELayout({ children }: { children: React.ReactNode }) const pathname = usePathname() const params = useParams() const projectId = params?.projectId as string | undefined + const [projectName, setProjectName] = React.useState('') + + React.useEffect(() => { + if (!projectId) return + fetch(`/api/sdk/v1/iace/projects/${projectId}`) + .then(r => r.ok ? r.json() : null) + .then(d => { if (d?.machine_name) setProjectName(d.machine_name) }) + .catch(() => {}) + }, [projectId]) const basePath = projectId ? `/sdk/iace/${projectId}` : '' @@ -127,9 +136,12 @@ export default function IACELayout({ children }: { children: React.ReactNode }) Alle Projekte -

- CE-Compliance -

+ {projectName && ( +

+ {projectName} +

+ )} +

CE-Compliance