Files
CPLv4.0/components/main/settingsPageComponents/OPCUAInterfaceSettings.tsx
Ismail Ali 772ef50af5 feat: OPC-UA Einstellungen in eigenen Redux Slice ausgelagert
- OPC-UA bezogene Variablen aus `variablesSlice` entfernt und in `opcuaSettingsSlice` ausgelagert
- Neue Redux Actions für:
  - `setOpcUaZustand` (OPC-UA Zustand setzen)
  - `setOpcUaEncryption` (Verschlüsselung setzen)
  - `setOpcUaActiveClientCount` (Anzahl aktiver Clients setzen)
  - `setOpcUaNodesetName` (Nodeset-Name setzen)
  - `addOpcUaUser` & `removeOpcUaUser` (Benutzerverwaltung)
- `loadWindowVariables.ts` angepasst, um OPC-UA-Daten in `opcuaSettingsSlice` zu speichern
- Benutzerverwaltung optimiert:
  - Manuell hinzugefügte Benutzer bleiben erhalten
  - Benutzer werden nur aktualisiert, wenn sich `window.win_opcUaUsers` ändert
- Keine automatische Statusumschaltung mehr beim OPC-UA-Server-Button

Jetzt ist die OPC-UA Verwaltung sauber getrennt und stabil! 🚀
2025-02-23 11:06:15 +01:00

152 lines
5.0 KiB
TypeScript

"use client"; // /components/main/settingsPageComponents/OPCUAInterfaceSettings.tsx
import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { RootState } from "../../../redux/store";
import {
setOpcUaEncryption,
toggleOpcUaServer,
setOpcUaNodesetName,
addOpcUaUser,
removeOpcUaUser,
} from "../../../redux/slices/opcuaSettingsSlice";
export default function OPCUAInterfaceSettings() {
const dispatch = useDispatch();
const opcuaSettings = useSelector((state: RootState) => state.opcuaSettings);
// Lokale Zustände für das neue Benutzerformular
const [newUsername, setNewUsername] = useState("");
const [newPassword, setNewPassword] = useState("");
const [nodesetName, setNodesetName] = useState(
opcuaSettings.opcUaNodesetName
);
const handleAddUser = () => {
if (newUsername.trim() && newPassword.trim()) {
dispatch(addOpcUaUser({ username: newUsername, password: newPassword }));
setNewUsername("");
setNewPassword("");
}
};
const handleNodesetUpdate = () => {
dispatch(setOpcUaNodesetName(nodesetName));
};
return (
<div className="max-w-3xl mx-auto p-4 bg-gray-100 shadow-md rounded-lg">
<h2 className="text-lg font-semibold mb-4">OPCUA Server Einstellungen</h2>
{/* ✅ Server Aktivierung */}
<div className="mb-4 flex items-center">
<label className="mr-4 font-medium">Server Status:</label>
<button
onClick={() => dispatch(toggleOpcUaServer())}
className={`px-4 py-2 rounded ${
opcuaSettings.isEnabled ? "bg-green-500" : "bg-gray-300"
} text-white`}
>
{opcuaSettings.isEnabled ? "Aktiviert" : "Deaktiviert"}
</button>
</div>
{/* ✅ Verschlüsselung */}
<div className="mb-4">
<label className="block font-medium mb-1">Verschlüsselung</label>
<select
value={opcuaSettings.encryption}
onChange={(e) => dispatch(setOpcUaEncryption(e.target.value))}
className="w-full p-2 border border-gray-300 rounded-md"
>
<option value="None">Keine</option>
<option value="Basic256">Basic256</option>
<option value="Basic256Sha256">Basic256Sha256</option>
</select>
</div>
{/* ✅ OPCUA Zustand (nur Anzeige) */}
<div className="mb-4">
<label className="block font-medium mb-1">OPCUA Zustand</label>
<div className="p-2 border border-gray-300 rounded-md bg-white">
{opcuaSettings.opcUaZustand}
</div>
</div>
{/* ✅ Aktive Clients (nur Anzeige) */}
<div className="mb-4">
<label className="block font-medium mb-1">Aktive Clients</label>
<div className="p-2 border border-gray-300 rounded-md bg-white">
{opcuaSettings.opcUaActiveClientCount}
</div>
</div>
{/* ✅ Nodeset Name */}
<div className="mb-4">
<label className="block font-medium mb-1">Nodeset Name</label>
<div className="flex">
<input
type="text"
className="flex-grow p-2 border border-gray-300 rounded-l-md"
value={nodesetName}
onChange={(e) => setNodesetName(e.target.value)}
/>
<button
onClick={handleNodesetUpdate}
className="px-4 py-2 bg-blue-500 text-white rounded-r-md"
>
Übernehmen
</button>
</div>
</div>
{/* ✅ Benutzerverwaltung */}
<div className="mb-4">
<h3 className="text-lg font-semibold mb-2">Benutzer</h3>
<ul className="space-y-2">
{opcuaSettings.users.map((user) => (
<li
key={user.id}
className="p-2 bg-white shadow-sm rounded-md flex justify-between items-center"
>
<span className="font-medium">{user.username}</span>
<span className="text-gray-600 ml-2">
(Passwort: {user.password})
</span>
<button
onClick={() => dispatch(removeOpcUaUser(user.id))}
className="text-red-500"
>
Löschen
</button>
</li>
))}
</ul>
{/* ✅ Neuen Benutzer hinzufügen */}
<div className="mt-4 flex space-x-2">
<input
type="text"
placeholder="Benutzername"
value={newUsername}
onChange={(e) => setNewUsername(e.target.value)}
className="p-2 border rounded w-1/3"
/>
<input
type="password"
placeholder="Passwort"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
className="p-2 border rounded w-1/3"
/>
<button
onClick={handleAddUser}
className="bg-blue-500 text-white p-2 rounded w-1/3"
>
Hinzufügen
</button>
</div>
</div>
</div>
);
}