feat(iace-ui): component presence/CE review + machine-type dropdown
- Components view: three presence sections (Vorhanden / Nicht vorhanden / Geloescht) with bidirectional move + soft-delete (audit-visible, restorable), so the expert corrects the engine's best-effort negation in both directions. - CE marking per component (bought robot/actuator/SPS) with a clear "validate the integrated safety function (PL/SIL)" note when also safety-relevant. Safe semantics: hazards are not suppressed, only provenance is surfaced. - Project-create form: machine type is now a grouped dropdown from the engine's controlled vocabulary (GET /machine-types) instead of free text. - Knowledge graph: component→hazard edges use the real component_id. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+8
-4
@@ -3,7 +3,7 @@
|
||||
import { useState, useEffect, useMemo } from 'react'
|
||||
|
||||
interface Component { id: string; name: string; component_type: string }
|
||||
interface Hazard { id: string; name: string; category: string; operational_states?: string[] }
|
||||
interface Hazard { id: string; name: string; category: string; operational_states?: string[]; component_id?: string }
|
||||
interface Mitigation { id: string; name?: string; title?: string; reduction_type: string; hazard_id?: string; linked_hazard_ids?: string[] }
|
||||
|
||||
export interface GraphNode {
|
||||
@@ -56,6 +56,7 @@ export function useKnowledgeGraph(projectId: string) {
|
||||
setHazards((j.hazards || j || []).map((h: Record<string, unknown>) => ({
|
||||
id: h.id as string, name: h.name as string, category: h.category as string || '',
|
||||
operational_states: (h.operational_states || []) as string[],
|
||||
component_id: (h.component_id || '') as string,
|
||||
})))
|
||||
}
|
||||
if (mitRes.ok) {
|
||||
@@ -89,17 +90,20 @@ export function useKnowledgeGraph(projectId: string) {
|
||||
})
|
||||
|
||||
// Hazard nodes
|
||||
const compIdSet = new Set(components.map((c) => c.id))
|
||||
hazards.forEach((h) => {
|
||||
graphNodes.push({
|
||||
id: `haz-${h.id}`, type: 'hazard',
|
||||
label: h.name, subLabel: h.category,
|
||||
color: NODE_COLORS.hazard,
|
||||
})
|
||||
// Edge: first component → hazard (simplified — could be per component_id)
|
||||
if (components.length > 0) {
|
||||
// Edge: the component that actually causes this hazard → hazard.
|
||||
// Only drawn when the hazard carries a component_id that maps to a known
|
||||
// component node (no synthetic "all from the first component" edges).
|
||||
if (h.component_id && compIdSet.has(h.component_id)) {
|
||||
graphEdges.push({
|
||||
id: `e-comp-haz-${h.id}`,
|
||||
source: `comp-${components[0].id}`,
|
||||
source: `comp-${h.component_id}`,
|
||||
target: `haz-${h.id}`,
|
||||
label: 'erzeugt',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user