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! 🚀
This commit is contained in:
@@ -1,57 +1,62 @@
|
||||
"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 [isEnabled, setIsEnabled] = useState(true);
|
||||
const [encryption, setEncryption] = useState("None");
|
||||
const [users, setUsers] = useState([
|
||||
{ id: 1, username: "admin", password: "admin123" },
|
||||
{ id: 2, username: "user1", password: "user123" },
|
||||
]);
|
||||
const [newUser, setNewUser] = useState({ username: "", password: "" });
|
||||
const dispatch = useDispatch();
|
||||
const opcuaSettings = useSelector((state: RootState) => state.opcuaSettings);
|
||||
|
||||
const toggleServer = () => setIsEnabled(!isEnabled);
|
||||
const updateEncryption = (event) => setEncryption(event.target.value);
|
||||
const addUser = () => {
|
||||
if (newUser.username && newUser.password) {
|
||||
setUsers([...users, { id: users.length + 1, ...newUser }]);
|
||||
setNewUser({ username: "", password: "" });
|
||||
// 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 removeUser = (id) => setUsers(users.filter((user) => user.id !== id));
|
||||
|
||||
const handleNodesetUpdate = () => {
|
||||
dispatch(setOpcUaNodesetName(nodesetName));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-3xl mx-auto p-6 bg-gray-100 shadow-md rounded-lg">
|
||||
<h2 className="text-xl font-semibold mb-4">OPCUA Server Einstellungen</h2>
|
||||
<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">
|
||||
<label className="flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isEnabled}
|
||||
onChange={toggleServer}
|
||||
className="hidden"
|
||||
/>
|
||||
<div
|
||||
className={`w-12 h-6 rounded-full transition-all ${
|
||||
isEnabled ? "bg-green-500" : "bg-gray-300"
|
||||
}`}
|
||||
></div>
|
||||
<span className="ml-2 text-sm">
|
||||
{isEnabled ? "Aktiviert" : "Deaktiviert"}
|
||||
</span>
|
||||
</label>
|
||||
{/* ✅ 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 */}
|
||||
{/* ✅ Verschlüsselung */}
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700">
|
||||
Verschlüsselung
|
||||
</label>
|
||||
<label className="block font-medium mb-1">Verschlüsselung</label>
|
||||
<select
|
||||
value={encryption}
|
||||
onChange={updateEncryption}
|
||||
className="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring focus:ring-blue-200"
|
||||
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>
|
||||
@@ -59,11 +64,46 @@ export default function OPCUAInterfaceSettings() {
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Benutzer & Passwörter */}
|
||||
{/* ✅ 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">
|
||||
{users.map((user) => (
|
||||
{opcuaSettings.users.map((user) => (
|
||||
<li
|
||||
key={user.id}
|
||||
className="p-2 bg-white shadow-sm rounded-md flex justify-between items-center"
|
||||
@@ -73,36 +113,34 @@ export default function OPCUAInterfaceSettings() {
|
||||
(Passwort: {user.password})
|
||||
</span>
|
||||
<button
|
||||
onClick={() => removeUser(user.id)}
|
||||
className="ml-4 text-red-500"
|
||||
onClick={() => dispatch(removeOpcUaUser(user.id))}
|
||||
className="text-red-500"
|
||||
>
|
||||
Löschen
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="mt-4">
|
||||
|
||||
{/* ✅ Neuen Benutzer hinzufügen */}
|
||||
<div className="mt-4 flex space-x-2">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Benutzername"
|
||||
value={newUser.username}
|
||||
onChange={(e) =>
|
||||
setNewUser({ ...newUser, username: e.target.value })
|
||||
}
|
||||
className="p-2 border rounded mr-2"
|
||||
value={newUsername}
|
||||
onChange={(e) => setNewUsername(e.target.value)}
|
||||
className="p-2 border rounded w-1/3"
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Passwort"
|
||||
value={newUser.password}
|
||||
onChange={(e) =>
|
||||
setNewUser({ ...newUser, password: e.target.value })
|
||||
}
|
||||
className="p-2 border rounded mr-2"
|
||||
value={newPassword}
|
||||
onChange={(e) => setNewPassword(e.target.value)}
|
||||
className="p-2 border rounded w-1/3"
|
||||
/>
|
||||
<button
|
||||
onClick={addUser}
|
||||
className="bg-blue-500 text-white p-2 rounded"
|
||||
onClick={handleAddUser}
|
||||
className="bg-blue-500 text-white p-2 rounded w-1/3"
|
||||
>
|
||||
Hinzufügen
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user