diff --git a/components/header/Header.tsx b/components/header/Header.tsx index 9d11edf..151f91e 100644 --- a/components/header/Header.tsx +++ b/components/header/Header.tsx @@ -4,6 +4,7 @@ import Image from "next/image"; import { useRouter } from "next/router"; import "bootstrap-icons/font/bootstrap-icons.css"; import SettingsModal from "./settingsModal/SettingsModal"; +import { RootState } from "../../redux/store"; import { useSelector } from "react-redux"; import decodeToken from "../../utils/decodeToken"; @@ -11,7 +12,9 @@ function Header() { const router = useRouter(); const [showSettingsModal, setShowSettingsModal] = useState(false); const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); - const deviceName = useSelector((state) => state.variables.deviceName); + const deviceName = useSelector( + (state: RootState) => state.systemSettings.deviceName + ); const handleSettingsClick = () => setShowSettingsModal(true); const handleCloseSettingsModal = () => setShowSettingsModal(false); diff --git a/components/header/settingsModal/SettingsModal.tsx b/components/header/settingsModal/SettingsModal.tsx index 29ed796..619daf8 100644 --- a/components/header/settingsModal/SettingsModal.tsx +++ b/components/header/settingsModal/SettingsModal.tsx @@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react"; import ReactModal from "react-modal"; import "bootstrap-icons/font/bootstrap-icons.css"; +import { RootState } from "../../../redux/store"; import { useSelector } from "react-redux"; import handleClearDatabase from "./handlers/handleClearDatabase"; import handleReboot from "./handlers/handleReboot"; @@ -99,19 +100,37 @@ function SettingModal({ showModal, onClose }) { } } }, [showModal]); - const deviceName_Redux = useSelector((state) => state.variables.deviceName); - const mac1_Redux = useSelector((state) => state.variables.mac1); - const ip_Redux = useSelector((state) => state.variables.ip); - const subnet_Redux = useSelector((state) => state.variables.subnet); - const gateway_Redux = useSelector((state) => state.variables.gateway); - const datetime_Redux = useSelector( - (state) => state.variables.cplInternalTimestamp + const deviceName_Redux = useSelector( + (state: RootState) => state.systemSettings.deviceName + ); + const mac1_Redux = useSelector( + (state: RootState) => state.systemSettings.mac1 + ); + const ip_Redux = useSelector((state: RootState) => state.systemSettings.ip); + const subnet_Redux = useSelector( + (state: RootState) => state.systemSettings.subnet + ); + const gateway_Redux = useSelector( + (state: RootState) => state.systemSettings.gateway + ); + const datetime_Redux = useSelector( + (state: RootState) => state.systemSettings.cplInternalTimestamp + ); + const ntp1_Redux = useSelector( + (state: RootState) => state.systemSettings.ntp1 + ); + const ntp2_Redux = useSelector( + (state: RootState) => state.systemSettings.ntp2 + ); + const ntp3_Redux = useSelector( + (state: RootState) => state.systemSettings.ntp3 + ); + const ntpTimezone_Redux = useSelector( + (state: RootState) => state.systemSettings.ntpTimezone + ); + const active_Redux = useSelector( + (state: RootState) => state.systemSettings.ntpActive ); - const ntp1_Redux = useSelector((state) => state.variables.ntp1); - const ntp2_Redux = useSelector((state) => state.variables.ntp2); - const ntp3_Redux = useSelector((state) => state.variables.ntp3); - const ntpTimezone_Redux = useSelector((state) => state.variables.ntpTimezone); - const active_Redux = useSelector((state) => state.variables.ntpActive); const [name, setName] = useState(deviceName_Redux || ""); const [mac1, setMac1] = useState(mac1_Redux || ""); diff --git a/components/main/settingsPageComponents/GeneralSettings.tsx b/components/main/settingsPageComponents/GeneralSettings.tsx index 3b2cc35..e329ebc 100644 --- a/components/main/settingsPageComponents/GeneralSettings.tsx +++ b/components/main/settingsPageComponents/GeneralSettings.tsx @@ -1,117 +1,180 @@ -import React, { useState, useEffect } from "react"; +"use client"; +import React, { useState } from "react"; +import { RootState } from "../../../redux/store"; import { useSelector } from "react-redux"; -import handleClearDatabase from "../../header/settingsModal/handlers/handleReboot"; +import handleClearDatabase from "../../header/settingsModal/handlers/handleClearDatabase"; import handleReboot from "../../header/settingsModal/handlers/handleReboot"; -import handleSetDateTime from "../../header/settingsModal/handlers/handleReboot"; -import handleSubmit from "../../header/settingsModal/handlers/handleReboot"; +import handleSetDateTime from "../../header/settingsModal/handlers/handleSetDateTime"; +import handleSubmit from "../../header/settingsModal/handlers/handleSubmit"; const GeneralSettings = () => { - const deviceName_Redux = useSelector((state) => state.variables.deviceName); - const ip_Redux = useSelector((state) => state.variables.ip); - const subnet_Redux = useSelector((state) => state.variables.subnet); - const gateway_Redux = useSelector((state) => state.variables.gateway); - const datetime_Redux = useSelector( - (state) => state.variables.cplInternalTimestamp + const systemSettings = useSelector( + (state: RootState) => state.systemSettings ); - const ntp1_Redux = useSelector((state) => state.variables.ntp1); - const ntp2_Redux = useSelector((state) => state.variables.ntp2); - const ntp3_Redux = useSelector((state) => state.variables.ntp3); - const ntpTimezone_Redux = useSelector((state) => state.variables.ntpTimezone); - const active_Redux = useSelector((state) => state.variables.ntpActive); + console.log("Redux SystemSettings:", systemSettings); - const [name, setName] = useState(deviceName_Redux || ""); - const [ip, setIp] = useState(ip_Redux || ""); - const [subnet, setSubnet] = useState(subnet_Redux || ""); - const [gateway, setGateway] = useState(gateway_Redux || ""); - const [systemUhr, setSystemUhr] = useState(datetime_Redux || ""); - const [ntp1, setNtp1] = useState(ntp1_Redux || ""); - const [ntp2, setNtp2] = useState(ntp2_Redux || ""); - const [ntp3, setNtp3] = useState(ntp3_Redux || ""); - const [ntpTimezone, setNtpTimezone] = useState(ntpTimezone_Redux || ""); - const [active, setActive] = useState(active_Redux || ""); - - useEffect(() => { - setName(deviceName_Redux || ""); - setIp(ip_Redux || ""); - setSubnet(subnet_Redux || ""); - setGateway(gateway_Redux || ""); - setSystemUhr(datetime_Redux || ""); - setNtp1(ntp1_Redux || ""); - setNtp2(ntp2_Redux || ""); - setNtp3(ntp3_Redux || ""); - setNtpTimezone(ntpTimezone_Redux || ""); - setActive(active_Redux || ""); - }, [ - deviceName_Redux, - ip_Redux, - subnet_Redux, - gateway_Redux, - datetime_Redux, - ntp1_Redux, - ntp2_Redux, - ntp3_Redux, - ntpTimezone_Redux, - active_Redux, - ]); + const [name, setName] = useState(systemSettings.deviceName || ""); + const [ip, setIp] = useState(systemSettings.ip || ""); + const [subnet, setSubnet] = useState(systemSettings.subnet || ""); + const [gateway, setGateway] = useState(systemSettings.gateway || ""); + const [systemUhr, setSystemUhr] = useState( + systemSettings.cplInternalTimestamp || "" + ); + const [ntp1, setNtp1] = useState(systemSettings.ntp1 || ""); + const [ntp2, setNtp2] = useState(systemSettings.ntp2 || ""); + const [ntp3, setNtp3] = useState(systemSettings.ntp3 || ""); + const [ntpTimezone, setNtpTimezone] = useState( + systemSettings.ntpTimezone || "" + ); + const [active, setActive] = useState(systemSettings.ntpActive || false); return ( -
-

General Settings

-
-
- +
+

General Settings

+ + {/* ✅ Geräte-Name */} +
+ setName(e.target.value)} />
-
-
- - setIp(e.target.value)} - /> -
-
- - setSubnet(e.target.value)} - /> -
+ {/* ✅ Netzwerk-Einstellungen */} +
+ + setIp(e.target.value)} + /> +
+
+ + setSubnet(e.target.value)} + /> +
+
+ + setGateway(e.target.value)} + />
-
+ {/* ✅ System-Zeit */} +
+
+ + +
+
+ + {/* ✅ NTP-Server */} +
+ + setNtp1(e.target.value)} + /> +
+
+ + setNtp2(e.target.value)} + /> +
+
+ + setNtp3(e.target.value)} + /> +
+
+ + setNtpTimezone(e.target.value)} + /> +
+
+ + setActive(e.target.checked)} + /> +
+ + {/* ✅ Buttons */} +
+
diff --git a/config/webVersion.ts b/config/webVersion.ts index c057537..0800972 100644 --- a/config/webVersion.ts +++ b/config/webVersion.ts @@ -6,5 +6,5 @@ 2: Patch oder Hotfix (Bugfixes oder kleine Änderungen). */ -const webVersion = "1.6.90"; +const webVersion = "1.6.91"; export default webVersion; diff --git a/pages/_app.tsx b/pages/_app.tsx index 3ab77e8..663336c 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -8,6 +8,7 @@ import Footer from "../components/footer/Footer"; import "../styles/globals.css"; import { Provider } from "react-redux"; import { setVariables } from "../redux/slices/variablesSlice"; +import { setSystemSettings } from "../redux/slices/systemSettingsSlice"; // ✅ Für System-Settings import store from "../redux/store"; import { AppProps } from "next/app"; import WindowVariablesInitializer from "../components/WindowVariablesInitializer"; @@ -21,10 +22,43 @@ function MyApp({ Component, pageProps }: AppProps) { const variables = await loadWindowVariables(); if (!variables) throw new Error("Sitzungsfehler"); - // last20Messages entfernen, falls es noch in variables existiert - const { last20Messages, ...restVariables } = variables; + // ✅ System-Settings und last20Messages separat speichern + const { + last20Messages, // Entfernen für eigenes Redux-Slice + deviceName, + mac1, + ip, + subnet, + gateway, + cplInternalTimestamp, + ntp1, + ntp2, + ntp3, + ntpTimezone, + ntpActive, + ...restVariables + } = variables; + // ✅ Speichere System-Settings in systemSettingsSlice + store.dispatch( + setSystemSettings({ + deviceName, + mac1, + ip, + subnet, + gateway, + cplInternalTimestamp, + ntp1, + ntp2, + ntp3, + ntpTimezone, + ntpActive, + }) + ); + + // ✅ Speichere alle anderen Variablen in variablesSlice store.dispatch(setVariables(restVariables)); + setSessionExpired(false); } catch (error) { console.error("Fehler beim Laden der Sitzung:", error); diff --git a/pages/einstellungen.tsx b/pages/einstellungen.tsx index eaff7f4..4b456a4 100644 --- a/pages/einstellungen.tsx +++ b/pages/einstellungen.tsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import GeneralSettings from "../components/main/settingsPageComponents/generalSettings"; +import GeneralSettings from "../components/main/settingsPageComponents/GeneralSettings"; import OPCUAInterfaceSettings from "../components/main/settingsPageComponents/OPCUAInterfaceSettings"; export default function Settings() { diff --git a/redux/slices/systemSettingsSlice.ts b/redux/slices/systemSettingsSlice.ts new file mode 100644 index 0000000..d061240 --- /dev/null +++ b/redux/slices/systemSettingsSlice.ts @@ -0,0 +1,48 @@ +// /redux/slices/systemSettingsSlice.ts +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; + +interface SystemSettingsState { + deviceName: string | null; + mac1: string | null; + ip: string | null; + subnet: string | null; + gateway: string | null; + cplInternalTimestamp: string | null; + ntp1: string | null; + ntp2: string | null; + ntp3: string | null; + ntpTimezone: string | null; + ntpActive: boolean | null; +} + +const initialState: SystemSettingsState = { + deviceName: "", + mac1: "", + ip: "", + subnet: "", + gateway: "", + cplInternalTimestamp: "", + ntp1: "", + ntp2: "", + ntp3: "", + ntpTimezone: "", + ntpActive: false, +}; + +const systemSettingsSlice = createSlice({ + name: "systemSettings", + initialState, + reducers: { + setSystemSettings: ( + state, + action: PayloadAction> + ) => { + return { ...state, ...action.payload }; + }, + resetSystemSettings: () => initialState, + }, +}); + +export const { setSystemSettings, resetSystemSettings } = + systemSettingsSlice.actions; +export default systemSettingsSlice.reducer; diff --git a/redux/slices/variablesSlice.ts b/redux/slices/variablesSlice.ts index ccea116..e18b1db 100644 --- a/redux/slices/variablesSlice.ts +++ b/redux/slices/variablesSlice.ts @@ -15,17 +15,6 @@ export interface VariablesState { schleifenintervall: number[]; //--------------- - deviceName: string | null; - mac1: string | null; - ip: string | null; - subnet: string | null; - gateway: string | null; - cplInternalTimestamp: string | null; - ntp1: string | null; - ntp2: string | null; - ntp3: string | null; - ntpTimezone: string | null; - ntpActive: boolean | null; de: string | null; counter: number | null; flutter: string | null; @@ -79,17 +68,6 @@ const initialState: VariablesState = { schleifenintervall: [], //--------------- - deviceName: null, - mac1: null, - ip: null, - subnet: null, - gateway: null, - cplInternalTimestamp: null, - ntp1: null, - ntp2: null, - ntp3: null, - ntpTimezone: null, - ntpActive: null, de: null, counter: null, flutter: null, diff --git a/redux/store.ts b/redux/store.ts index e9028c9..75a1543 100644 --- a/redux/store.ts +++ b/redux/store.ts @@ -7,6 +7,7 @@ import webVersionReducer from "./slices/webVersionSlice"; import digitalInputsReducer from "./slices/digitalInputsSlice"; import kabelueberwachungChartReducer from "./slices/kabelueberwachungChartSlice"; import dashboardReducer from "./slices/dashboardSlice"; +import systemSettingsReducer from "./slices/systemSettingsSlice"; const store = configureStore({ reducer: { @@ -17,6 +18,7 @@ const store = configureStore({ digitalInputs: digitalInputsReducer, kabelueberwachungChart: kabelueberwachungChartReducer, dashboard: dashboardReducer, + systemSettings: systemSettingsReducer, }, }); diff --git a/utils/loadWindowVariables.ts b/utils/loadWindowVariables.ts index 1df6c4a..2b814b5 100644 --- a/utils/loadWindowVariables.ts +++ b/utils/loadWindowVariables.ts @@ -1,9 +1,28 @@ -// utils/loadWindowVariables.ts -interface WindowVariables { - [key: string]: any; // Allgemeiner Typ für die Dynamik, kann spezifischer angepasst werden, falls bekannt +import store from "../redux/store"; +import { setSystemSettings } from "../redux/slices/systemSettingsSlice"; + +// ✅ Interface für `window`-Objekt zur TypeScript-Sicherheit +interface CustomWindow extends Window { + [key: string]: any; } -export async function loadWindowVariables(): Promise { +// ✅ Interface für System-Einstellungen im Redux-Store +interface SystemSettings { + deviceName: string; + mac1: string; + ip: string; + subnet: string; + gateway: string; + cplInternalTimestamp: string; + ntp1: string; + ntp2: string; + ntp3: string; + ntpTimezone: string; + ntpActive: boolean; +} + +// ✅ Hauptfunktion zum Laden von `window`-Variablen +export async function loadWindowVariables(): Promise> { return new Promise((resolve, reject) => { const requiredVars: string[] = [ "win_last20Messages", @@ -61,6 +80,16 @@ export async function loadWindowVariables(): Promise { "win_da_bezeichnung", ]; + const scripts: string[] = [ + "da.js", + "de.js", + "ae.js", + "kueData.js", + "Start.js", + "System.js", + "opcua.js", + ]; + const loadScript = (src: string): Promise => { return new Promise((resolve, reject) => { const script = document.createElement("script"); @@ -76,40 +105,29 @@ export async function loadWindowVariables(): Promise { }); }; - const scripts: string[] = [ - "da.js", - "de.js", - "ae.js", - "kueData.js", - "Start.js", - "System.js", - "opcua.js", - ]; - + // ✅ Lade alle Skripte nacheinander scripts .reduce( (promise, script) => promise.then(() => loadScript(script)), Promise.resolve() ) .then(() => { - const variablesObj: WindowVariables = requiredVars.reduce( - (acc: WindowVariables, variable: string) => { - // Prüfe, ob die Variable auf dem window-Objekt existiert - const winVar = (window as any)[variable]; - if (winVar !== undefined) { - // Wenn es sich um kueID handelt, ersetze %20 durch Leerzeichen - if (variable === "win_kueID" && Array.isArray(winVar)) { - acc[variable.replace("win_", "")] = winVar.map((id: string) => - id.replace(/%20/g, " ") - ); - } else { - acc[variable.replace("win_", "")] = winVar; - } + const win = window as unknown as CustomWindow; + + // ✅ Erstelle ein Objekt mit allen geladenen Variablen + const variablesObj: Record = requiredVars.reduce( + (acc, variable) => { + if (win[variable] !== undefined) { + acc[variable.replace("win_", "")] = win[variable]; } return acc; }, {} ); + + // ✅ Redux mit Systemvariablen aktualisieren + loadAndStoreSystemSettings(win); + resolve(variablesObj); }) .catch((error) => { @@ -118,3 +136,22 @@ export async function loadWindowVariables(): Promise { }); }); } + +// ✅ Funktion zum Speichern von System-Variablen in Redux +const loadAndStoreSystemSettings = (win: CustomWindow) => { + const settings: SystemSettings = { + deviceName: win.win_deviceName || "", + mac1: win.win_mac1 || "", + ip: win.win_ip || "", + subnet: win.win_subnet || "", + gateway: win.win_gateway || "", + cplInternalTimestamp: win.win_cplInternalTimestamp || "", + ntp1: win.win_ntp1 || "", + ntp2: win.win_ntp2 || "", + ntp3: win.win_ntp3 || "", + ntpTimezone: win.win_ntpTimezone || "", + ntpActive: win.win_ntpActive || false, + }; + + store.dispatch(setSystemSettings(settings)); +};