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:
@@ -134,9 +134,14 @@ export default function IACEDashboardPage() {
|
||||
machine_type: '',
|
||||
manufacturer: '',
|
||||
})
|
||||
const [machineTypes, setMachineTypes] = useState<{ key: string; label_de: string; group: string }[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
fetchProjects()
|
||||
fetch('/api/sdk/v1/iace/machine-types')
|
||||
.then((r) => (r.ok ? r.json() : null))
|
||||
.then((j) => j && setMachineTypes(j.machine_types || []))
|
||||
.catch((err) => console.error('Failed to fetch machine types:', err))
|
||||
}, [])
|
||||
|
||||
async function fetchProjects() {
|
||||
@@ -308,13 +313,23 @@ export default function IACEDashboardPage() {
|
||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Maschinentyp
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
<select
|
||||
value={formData.machine_type}
|
||||
onChange={(e) => setFormData({ ...formData, machine_type: e.target.value })}
|
||||
placeholder="z.B. Industrieroboter"
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent dark:bg-gray-700 dark:border-gray-600 dark:text-white"
|
||||
/>
|
||||
>
|
||||
<option value="">— Maschinentyp wählen —</option>
|
||||
{Array.from(new Set(machineTypes.map((m) => m.group))).map((group) => (
|
||||
<optgroup key={group} label={group}>
|
||||
{machineTypes.filter((m) => m.group === group).map((m) => (
|
||||
<option key={m.key} value={m.key}>{m.label_de}</option>
|
||||
))}
|
||||
</optgroup>
|
||||
))}
|
||||
</select>
|
||||
<p className="mt-1 text-xs text-gray-400">
|
||||
Steuert, welche maschinenspezifischen Gefährdungs-Patterns greifen — bitte aus der Liste wählen.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
|
||||
Reference in New Issue
Block a user