diff --git a/components/Footer.jsx b/components/Footer.tsx similarity index 93% rename from components/Footer.jsx rename to components/Footer.tsx index af4d339..58c9a0c 100644 --- a/components/Footer.jsx +++ b/components/Footer.tsx @@ -4,7 +4,7 @@ import { Icon } from "@iconify/react"; function Footer() { const [showSlider, setShowSlider] = useState(false); - const sliderRef = useRef(null); + const sliderRef = useRef(null); const pdfFiles = [ // "ACCESS.PDF", @@ -26,7 +26,7 @@ function Footer() { ]; // Funktion zum Laden der PDFs direkt aus dem öffentlichen Verzeichnis - const loadPDF = (fileName) => { + const loadPDF = (fileName: string) => { const pdfUrl = `/doku/${fileName}`; // Annahme: Die PDFs liegen im Ordner "public/doku" window.open(pdfUrl, "_blank"); // Öffnet die PDF in einem neuen Tab setShowSlider(false); @@ -34,8 +34,11 @@ function Footer() { // Schließt den Slider, wenn außerhalb geklickt wird useEffect(() => { - function handleClickOutside(event) { - if (sliderRef.current && !sliderRef.current.contains(event.target)) { + function handleClickOutside(event: MouseEvent) { + if ( + sliderRef.current && + !sliderRef.current.contains(event.target as Node) + ) { setShowSlider(false); } } diff --git a/components/Header.jsx b/components/Header.tsx similarity index 100% rename from components/Header.jsx rename to components/Header.tsx diff --git a/components/Navigation.jsx b/components/Navigation.tsx similarity index 90% rename from components/Navigation.jsx rename to components/Navigation.tsx index 30b726b..b249a37 100644 --- a/components/Navigation.jsx +++ b/components/Navigation.tsx @@ -3,7 +3,11 @@ import React, { useEffect, useState } from "react"; import Link from "next/link"; import { usePathname } from "next/navigation"; -function Navigation() { +interface NavigationProps { + className?: string; +} + +const Navigation: React.FC = ({ className }) => { const pathname = usePathname(); const [activeLink, setActiveLink] = useState(""); @@ -13,7 +17,7 @@ function Navigation() { } }, [pathname]); - const formatPath = (path) => { + const formatPath = (path: string) => { return process.env.NODE_ENV === "production" ? `${path}.html` : path; }; @@ -44,6 +48,6 @@ function Navigation() { ); -} +}; export default Navigation; diff --git a/components/modales/kueModal/KueModal.jsx b/components/modales/kueModal/KueModal.tsx similarity index 87% rename from components/modales/kueModal/KueModal.jsx rename to components/modales/kueModal/KueModal.tsx index c244bdb..3435505 100644 --- a/components/modales/kueModal/KueModal.jsx +++ b/components/modales/kueModal/KueModal.tsx @@ -2,16 +2,28 @@ import ReactModal from "react-modal"; import { useState, useEffect } from "react"; import { useSelector, useDispatch } from "react-redux"; -import { updateValues } from "../../../store/variablesSlice"; +import { setVariables } from "../../../store/variablesSlice"; import "bootstrap-icons/font/bootstrap-icons.css"; // Import Bootstrap Icons -import handleSave from "./handlers/handleSave"; +import handleSave , { OriginalValues } from "./handlers/handleSave"; import handleDisplayEinschalten from "./handlers/handleDisplayEinschalten"; import handleChange from "./handlers/handleChange"; import firmwareUpdate from "./handlers/firmwareUpdate"; import decodeToken from "../../../utils/decodeToken"; +// Props-Typen definieren +interface KueModalProps { + showModal: boolean; + onClose: () => void; + slot: number; + onModulNameChange: (id: string) => void; +} -function KueModal({ showModal, onClose, slot, onModulNameChange }) { - const isAdminLoggedIn = useSelector((state) => state.auth.isAdminLoggedIn); +function KueModal({ + showModal, + onClose, + slot, + onModulNameChange, +}: KueModalProps): JSX.Element { + const isAdminLoggedIn = useSelector((state: any) => state.auth.isAdminLoggedIn); const [isAdmin, setIsAdmin] = useState(false); const dispatch = useDispatch(); const [ids, setIds] = useState(Array(32).fill("")); @@ -30,17 +42,26 @@ function KueModal({ showModal, onClose, slot, onModulNameChange }) { Array(32).fill(24) ); - const [originalValues, setOriginalValues] = useState({}); + const [originalValues, setOriginalValues] = useState({ + kueID: Array(32).fill(""), + kueBezeichnungen: Array(32).fill(""), + isolationsgrenzwerte: Array(32).fill(10.0), + verzoegerung: Array(32).fill(1.0), + untereSchleifenGrenzwerte: Array(32).fill(0.1), + obereSchleifenGrenzwerte: Array(32).fill(1.0), + schleifenintervall: Array(32).fill(24), + }); + - // Werte aus dem Redux-Store abrufen - const { + // Werte aus dem Redux-Store abrufen + const { kueID, kueLimit1, kueDelay1, kueLimit2Low, kueLimit2High, kueLoopInterval, - } = useSelector((state) => state.variables); + } = useSelector((state: any) => state.variables); const handleSaveWrapper = () => { handleSave({ @@ -66,9 +87,9 @@ function KueModal({ showModal, onClose, slot, onModulNameChange }) { // Initiale Werte festlegen, nur einmal beim Öffnen des Modals useEffect(() => { if (showModal) { - setIds(kueID ? kueID.map((id) => id.trim() || "---") : ids); + setIds(kueID ? kueID.map((id: string) => id.trim() || "---") : ids); setBezeichnungen( - kueID ? kueID.map((name) => name.trim() || "---") : bezeichnungen + kueID ? kueID.map((name: string) => name.trim() || "---") : bezeichnungen ); setIsolationsgrenzwerte(kueLimit1 || isolationsgrenzwerte); setVerzoegerung(kueDelay1 || verzoegerung); @@ -77,14 +98,15 @@ function KueModal({ showModal, onClose, slot, onModulNameChange }) { setSchleifenintervall(kueLoopInterval || schleifenintervall); setOriginalValues({ - ids: [...ids], - bezeichnungen: [...bezeichnungen], + kueID: [...ids], + kueBezeichnungen: [...bezeichnungen], isolationsgrenzwerte: [...isolationsgrenzwerte], verzoegerung: [...verzoegerung], untereSchleifenGrenzwerte: [...untereSchleifenGrenzwerte], obereSchleifenGrenzwerte: [...obereSchleifenGrenzwerte], schleifenintervall: [...schleifenintervall], }); + } }, [showModal]); // nur von showModal abhängig ansonsten wird alle 10 Sekunden die Werte zurückgesetzt in Modal //------------------------------------------------------------------------------------------------------------ @@ -110,7 +132,7 @@ function KueModal({ showModal, onClose, slot, onModulNameChange }) { overlay: { backgroundColor: "rgba(0, 0, 0, 0.5)", zIndex: 100, - text: "black", + }, content: { top: "50%", diff --git a/components/modales/kueModal/handlers/firmwareUpdate.js b/components/modales/kueModal/handlers/firmwareUpdate.ts similarity index 91% rename from components/modales/kueModal/handlers/firmwareUpdate.js rename to components/modales/kueModal/handlers/firmwareUpdate.ts index d7e8df1..fc76215 100644 --- a/components/modales/kueModal/handlers/firmwareUpdate.js +++ b/components/modales/kueModal/handlers/firmwareUpdate.ts @@ -1,4 +1,4 @@ -const firmwareUpdate = (slot) => { +const firmwareUpdate = (slot: number) => { const url = `${window.location.origin}/CPL?/kabelueberwachung.html&KSU${slot}=1`; fetch(url, { method: "GET" }) .then((response) => { diff --git a/components/modales/kueModal/handlers/handleChange.js b/components/modales/kueModal/handlers/handleChange.js deleted file mode 100644 index 215ce8f..0000000 --- a/components/modales/kueModal/handlers/handleChange.js +++ /dev/null @@ -1,10 +0,0 @@ -// Funktionen zur Änderung der Werte -const handleChange = (setter, e, slot) => { - const value = e.target.value; - setter((prev) => { - const updated = [...prev]; - updated[slot] = value; - return updated; - }); -}; -export default handleChange; diff --git a/components/modales/kueModal/handlers/handleChange.ts b/components/modales/kueModal/handlers/handleChange.ts new file mode 100644 index 0000000..8391e42 --- /dev/null +++ b/components/modales/kueModal/handlers/handleChange.ts @@ -0,0 +1,18 @@ +import { Dispatch, SetStateAction } from "react"; + +// Funktion zur Änderung der Werte +const handleChange = ( + setter: Dispatch>, // Typ für den Setter + e: React.ChangeEvent, // Typ für das Event + slot: number // Typ für den Slot +) => { + const value = e.target.value; + setter((prev: any[]) => { + // Typ für den vorherigen Zustand + const updated = [...prev]; + updated[slot] = value; + return updated; + }); +}; + +export default handleChange; diff --git a/components/modales/kueModal/handlers/handleDisplayEinschalten.js b/components/modales/kueModal/handlers/handleDisplayEinschalten.ts similarity index 89% rename from components/modales/kueModal/handlers/handleDisplayEinschalten.js rename to components/modales/kueModal/handlers/handleDisplayEinschalten.ts index 6f45537..1f4c406 100644 --- a/components/modales/kueModal/handlers/handleDisplayEinschalten.js +++ b/components/modales/kueModal/handlers/handleDisplayEinschalten.ts @@ -1,4 +1,4 @@ -const handleDisplayEinschalten = (slot) => { +const handleDisplayEinschalten = (slot: number) => { const url = `/CPL?/kabelueberwachung.html&KSD${slot}=1`; fetch(url, { method: "GET" }) .then((response) => { diff --git a/components/modales/kueModal/handlers/handleSave.js b/components/modales/kueModal/handlers/handleSave.ts similarity index 56% rename from components/modales/kueModal/handlers/handleSave.js rename to components/modales/kueModal/handlers/handleSave.ts index 0da96d4..1f525f2 100644 --- a/components/modales/kueModal/handlers/handleSave.js +++ b/components/modales/kueModal/handlers/handleSave.ts @@ -1,4 +1,31 @@ -import { updateValues } from "../../../../store/variablesSlice"; +// components/modales/kueModal/handlers/handleSave.ts +import { setVariables } from "../../../../store/variablesSlice"; + +export interface OriginalValues { + kueID: string[]; + kueBezeichnungen: string[]; + isolationsgrenzwerte: number[]; + verzoegerung: number[]; + untereSchleifenGrenzwerte: number[]; + obereSchleifenGrenzwerte: number[]; + schleifenintervall: number[]; +} + +interface HandleSaveParams { + ids: string[]; // kueID im Redux-Slice + bezeichnungen: string[]; // kueBezeichnungen im Redux-Slice + isolationsgrenzwerte: number[]; + verzoegerung: number[]; + untereSchleifenGrenzwerte: number[]; + obereSchleifenGrenzwerte: number[]; + schleifenintervall: number[]; + originalValues: OriginalValues; + slot: number; + dispatch: (action: any) => void; + onModulNameChange: (id: string) => void; + onClose: () => void; +} + const handleSave = ({ ids, bezeichnungen, @@ -12,14 +39,21 @@ const handleSave = ({ dispatch, onModulNameChange, onClose, -}) => { - const changes = {}; +}: HandleSaveParams): void => { + const changes: Partial<{ + KID: string; + KIA: string; + KL_: number; + KD_: number; + KR_: number; + KRO_: number; + KRI: number; + }> = {}; - // Überprüfen, ob Änderungen gegenüber den Originalwerten vorliegen - if (ids[slot] !== originalValues.ids[slot]) { + if (ids[slot] !== originalValues.kueID[slot]) { changes.KID = ids[slot]; } - if (bezeichnungen[slot] !== originalValues.bezeichnungen[slot]) { + if (bezeichnungen[slot] !== originalValues.kueBezeichnungen[slot]) { changes.KIA = bezeichnungen[slot]; } if ( @@ -48,8 +82,10 @@ const handleSave = ({ if (Object.keys(changes).length > 0) { let url = `/cpl?/kabelueberwachung.html&slot=${slot}`; - Object.keys(changes).forEach((paramKey) => { - url += `&${paramKey}${slot}=${encodeURIComponent(changes[paramKey])}`; + Object.entries(changes).forEach(([paramKey, paramValue]) => { + if (paramValue !== undefined) { + url += `&${paramKey}${slot}=${encodeURIComponent(paramValue)}`; + } }); fetch(url, { method: "GET" }) @@ -58,11 +94,10 @@ const handleSave = ({ alert("Daten erfolgreich gespeichert!"); onModulNameChange(ids[slot]); - // Aktualisiere Redux-Store mit neuen Werten dispatch( - updateValues({ - ids: [...ids], - bezeichnungen: [...bezeichnungen], + setVariables({ + kueID: [...ids], + kueBezeichnungen: [...bezeichnungen], isolationsgrenzwerte: [...isolationsgrenzwerte], verzoegerung: [...verzoegerung], untereSchleifenGrenzwerte: [...untereSchleifenGrenzwerte], @@ -76,7 +111,7 @@ const handleSave = ({ }) .catch((error) => { console.error("Fehler:", error); - //alert("Fehler beim Senden der Daten!"); + alert("Fehler beim Senden der Daten!"); }); } else { alert("Keine Änderungen vorgenommen."); diff --git a/components/modales/settingsModal/SettingsModal.jsx b/components/modales/settingsModal/SettingsModal.tsx similarity index 100% rename from components/modales/settingsModal/SettingsModal.jsx rename to components/modales/settingsModal/SettingsModal.tsx diff --git a/components/modales/settingsModal/handlers/handleClearDatabase.js b/components/modales/settingsModal/handlers/handleClearDatabase.ts similarity index 100% rename from components/modales/settingsModal/handlers/handleClearDatabase.js rename to components/modales/settingsModal/handlers/handleClearDatabase.ts diff --git a/components/modales/settingsModal/handlers/handleReboot.js b/components/modales/settingsModal/handlers/handleReboot.ts similarity index 79% rename from components/modales/settingsModal/handlers/handleReboot.js rename to components/modales/settingsModal/handlers/handleReboot.ts index 681efe3..06f16ae 100644 --- a/components/modales/settingsModal/handlers/handleReboot.js +++ b/components/modales/settingsModal/handlers/handleReboot.ts @@ -1,4 +1,5 @@ -const handleReboot = async (newIp = null) => { +// components/modales/settingsModal/handlers/handleReboot.ts +const handleReboot = async (newIp: string | null = null): Promise => { const showWaitPage = () => { const waitHTML = ` @@ -48,21 +49,22 @@ const handleReboot = async (newIp = null) => { `; document.documentElement.innerHTML = waitHTML; - // JavaScript für die Progress-Bar-Animation nach dem Hinzufügen der HTML-Struktur let progress = 0; const progressBar = document.getElementById("progress-bar"); - const interval = setInterval(() => { - progress += 1; - progressBar.style.width = progress + "%"; - if (progress >= 100) { - clearInterval(interval); - } - }, 300); // 300ms x 100 = 30 Sekunden + if (progressBar) { + const interval = setInterval(() => { + progress += 1; + progressBar.style.width = progress + "%"; + if (progress >= 100) { + clearInterval(interval); + } + }, 300); + } else { + console.error("Progress-Bar-Element nicht gefunden."); + } }; - if ( - window.confirm("Sind Sie sicher, dass Sie den CPL neu starten möchten?") - ) { + if (window.confirm("Sind Sie sicher, dass Sie den CPL neu starten möchten?")) { showWaitPage(); const baseRedirectURL = newIp ? `https://${newIp}` : window.location.origin; diff --git a/components/modales/settingsModal/handlers/handleSetDateTime.js b/components/modales/settingsModal/handlers/handleSetDateTime.ts similarity index 100% rename from components/modales/settingsModal/handlers/handleSetDateTime.js rename to components/modales/settingsModal/handlers/handleSetDateTime.ts diff --git a/components/modales/settingsModal/handlers/handleSubmit.js b/components/modales/settingsModal/handlers/handleSubmit.ts similarity index 55% rename from components/modales/settingsModal/handlers/handleSubmit.js rename to components/modales/settingsModal/handlers/handleSubmit.ts index ff82b5e..44490df 100644 --- a/components/modales/settingsModal/handlers/handleSubmit.js +++ b/components/modales/settingsModal/handlers/handleSubmit.ts @@ -1,10 +1,37 @@ -// components/modales/handlers/handleSubmit.js +// components/modales/handlers/handleSubmit.ts import handleReboot from "./handleReboot"; -const handleSubmit = (originalValues, currentValues) => { - const changes = {}; +interface OriginalValues { + name: string; + ip: string; + subnet: string; + gateway: string; + ntp1: string; + ntp2: string; + ntp3: string; + ntpTimezone: string; + active: boolean; +} + +interface CurrentValues { + name: string; + ip: string; + subnet: string; + gateway: string; + ntp1: string; + ntp2: string; + ntp3: string; + ntpTimezone: string; + active: boolean; +} + +const handleSubmit = ( + originalValues: OriginalValues, + currentValues: CurrentValues +): void => { + const changes: { [key: string]: string | boolean } = {}; let networkChanges = false; - let newIp = null; + let newIp: string | null = null; // Überprüfe, welche Werte sich geändert haben if (currentValues.name !== originalValues.name) { @@ -44,21 +71,25 @@ const handleSubmit = (originalValues, currentValues) => { // URL für die Änderungen erstellen let url = `${window.location.origin}/CPL?${window.location.pathname}`; Object.keys(changes).forEach((paramKey) => { - url += `&${paramKey}=${encodeURIComponent(changes[paramKey])}`; + url += `&${paramKey}=${encodeURIComponent(String(changes[paramKey]))}`; }); console.log(url); - fetch(url, { method: "GET" }); - - alert("Daten erfolgreich gesendet!"); - - if (networkChanges) { - alert( - "Hinweis: Die Änderungen in CPL-Name und den Netzwerkeinstellungen werden erst nach einem Neustart des CPL wirksam." - ); - handleReboot(newIp); // handleReboot mit neuer IP aufrufen - } + fetch(url, { method: "GET" }) + .then(() => { + alert("Daten erfolgreich gesendet!"); + if (networkChanges) { + alert( + "Hinweis: Die Änderungen in CPL-Name und den Netzwerkeinstellungen werden erst nach einem Neustart des CPL wirksam." + ); + handleReboot(newIp); // handleReboot mit neuer IP aufrufen + } + }) + .catch((error) => { + console.error("Fehler beim Senden der Daten:", error); + alert("Fehler beim Senden der Daten."); + }); } else { alert("Keine Änderungen vorgenommen."); } diff --git a/components/modules/Kue705FO.jsx b/components/modules/Kue705FO.tsx similarity index 78% rename from components/modules/Kue705FO.jsx rename to components/modules/Kue705FO.tsx index ab8f5f4..9cd2da7 100644 --- a/components/modules/Kue705FO.jsx +++ b/components/modules/Kue705FO.tsx @@ -1,12 +1,18 @@ -"use client"; // components/modules/Kue705FO.jsx +"use client"; // components/modules/Kue705FO.tsx import React, { useState, useEffect, useRef } from "react"; import ReactModal from "react-modal"; import Chart from "chart.js/auto"; import { useSelector } from "react-redux"; import KueModal from "../modales/kueModal/KueModal"; import "bootstrap-icons/font/bootstrap-icons.css"; // Import Bootstrap Icons +import { RootState } from "../../store/store"; -function Kue705FO({ +interface DataTDR { + t: number; // Oder Date, falls t ein Datum ist + m: number; // Der Wert für den Pegel +} + +const Kue705FO: React.FC = ({ isolationswert, schleifenwiderstand, modulName, @@ -14,13 +20,13 @@ function Kue705FO({ slotIndex, tdrLocation, alarmStatus, -}) { +}) => { /* console.log( `Rendering Kue705FO - SlotIndex: ${slotIndex}, ModulName: ${modulName}` ); */ const chartRef = useRef(null); - const [zoomPlugin, setZoomPlugin] = useState(null); // Plugin-Status für Chart.js + const [zoomPlugin, setZoomPlugin] = useState(null); // Plugin-Status für Chart.js const [kueVersion, setKueVersion] = useState("V4.19"); const [currentAlarmStatus, setCurrentAlarmStatus] = useState(false); const [currentModulName, setCurrentModulName] = useState(modulName); @@ -40,7 +46,9 @@ function Kue705FO({ const [isoGreaterThan200, setIsoGreaterThan200] = useState(">200 MOhm"); const [loading, setLoading] = useState(false); - const [isoDisplayValue, setIsoDisplayValue] = useState(); //Test erstmal leer ohne isolationswert + const [isoDisplayValue, setIsoDisplayValue] = useState< + string | JSX.Element + >(); //Test erstmal leer ohne isolationswert const [showModal, setShowModal] = useState(false); const [showChartModal, setShowChartModal] = useState(false); const [chartData, setChartData] = useState(null); @@ -55,7 +63,7 @@ function Kue705FO({ kueOverflow, kueVersion: reduxKueVersion, tdrActive, - } = useSelector((state) => state.variables); + } = useSelector((state: RootState) => state.variables); const handleOpenModal = () => setShowModal(true); const handleCloseModal = () => setShowModal(false); @@ -68,7 +76,7 @@ function Kue705FO({ loadLoopChartData(); } }; - const handleButtonClick = (button) => { + const handleButtonClick = (button: "Schleife" | "TDR") => { if (button === "Schleife") { setActiveButton("Schleife"); setloopTitleText("Schleifenwiderstand [kOhm]"); @@ -86,14 +94,14 @@ function Kue705FO({ // Funktion für die Schleifenmessung const goLoop = () => { - let slot = slotIndex; + let slot: number = slotIndex; if (slot >= 32) { return; } // Entfernt führende Nullen, falls vorhanden - let slotFormat = slot < 10 ? `${parseInt(slot, 10)}` : `${slot}`; + let slotFormat = slot < 10 ? `${slot}` : `${slot}`; setLoading(true); // Setze den Ladezustand auf true alert(`Schleifenmessung wird für Slot ${slot + 1} gestartet...`); @@ -120,14 +128,14 @@ function Kue705FO({ // Funktion für die TDR-Messung const goTDR = () => { //------------------------------------------------- - let slot = slotIndex; + let slot: number = slotIndex; if (slot >= 32) { return; } // Entfernt führende Nullen, falls vorhanden - let slotFormat = slot < 10 ? `${parseInt(slot, 10)}` : `${slot}`; + let slotFormat = slot < 10 ? `${slot}` : `${slot}`; setLoading(true); alert(`TDR wird für Slot ${slot + 1} gestartet...`); @@ -162,8 +170,13 @@ function Kue705FO({ const handleCloseChartModal = () => setShowChartModal(false); // Funktion zum Erstellen des TDR-Charts - const createTDRChart = (dataTDR) => { - const ctx = document.getElementById("myChart").getContext("2d"); + const createTDRChart = (dataTDR: DataTDR[]) => { + const canvas = document.getElementById("myChart") as HTMLCanvasElement; + const ctx = canvas?.getContext("2d"); + if (!ctx) { + console.error("Canvas context konnte nicht gefunden werden"); + return; + } new Chart(ctx, { type: "line", @@ -260,71 +273,90 @@ function Kue705FO({ } }, []); - const createLoopChart = (data) => { - const ctx = document.getElementById("myChart").getContext("2d"); - new Chart(ctx, { - type: "line", - data: { - labels: data - .map((row) => new Date(row.t).toLocaleString("de-DE")) - .reverse(), - datasets: [ - { - label: "Isolationswiderstand (MOhm)", - data: data.map((row) => row.m).reverse(), - borderColor: "#00AEEF", - borderWidth: 1, - lineTension: 0.1, - pointRadius: 0.3, - pointHoverRadius: 5, - fill: false, - yAxisID: "y", - }, - { - label: "Schleifenwiderstand (kOhm)", - data: data.map((row) => row.n).reverse(), - borderColor: "black", - borderWidth: 1, - lineTension: 0.1, - pointRadius: 0.3, - pointHoverRadius: 5, - fill: false, - yAxisID: "y1", - }, - ], - }, - options: { - scales: { - y: { - type: "linear", - position: "left", - title: { display: true, text: "MOhm" }, - }, - y1: { - type: "linear", - position: "right", - title: { display: true, text: "kOhm" }, - }, - }, - plugins: { - zoom: { - pan: { - enabled: true, - mode: "xy", + interface DataLoop { + t: number; // Zeit oder Index + m: number; // Isolationswiderstand + n: number; // Schleifenwiderstand + } + + const createLoopChart = (data: DataLoop[], title: string) => { + const canvas = document.getElementById("myChart") as HTMLCanvasElement; + const ctx = canvas?.getContext("2d"); + if (!ctx) { + console.error("Canvas context konnte nicht gefunden werden"); + return; + } + + const createLoopChart = (data: DataLoop[], title: string) => { + const canvas = document.getElementById("myChart") as HTMLCanvasElement; + const ctx = canvas?.getContext("2d"); + if (!ctx) { + console.error("Canvas context konnte nicht gefunden werden"); + return; + } + + new Chart(ctx, { + type: "line", + data: { + labels: data.map((row) => new Date(row.t).toLocaleString("de-DE")), + datasets: [ + { + label: "Isolationswiderstand (MOhm)", + data: data.map((row) => row.m), + borderColor: "#00AEEF", + borderWidth: 1, + tension: 0.1, // Ersatz für lineTension + pointRadius: 0.3, + pointHoverRadius: 5, + fill: false, + yAxisID: "y", }, + { + label: "Schleifenwiderstand (kOhm)", + data: data.map((row) => row.n), + borderColor: "black", + borderWidth: 1, + tension: 0.1, // Ersatz für lineTension + pointRadius: 0.3, + pointHoverRadius: 5, + fill: false, + yAxisID: "y1", + }, + ], + }, + options: { + scales: { + y: { + type: "linear", + position: "left", + title: { display: true, text: "MOhm" }, + }, + y1: { + type: "linear", + position: "right", + title: { display: true, text: "kOhm" }, + }, + }, + plugins: { zoom: { - wheel: { - enabled: true, // Zoom mit Mausrad + pan: { + enabled: true, + mode: "xy", }, - pinch: { - enabled: true, // Pinch-Zoom für Touchgeräte + zoom: { + wheel: { + enabled: true, + }, + pinch: { + enabled: true, + }, + mode: "xy", }, - mode: "xy", // x und y Achsen zoomen }, }, }, - }, - }); + }); + }; }; useEffect(() => { @@ -335,7 +367,7 @@ function Kue705FO({ (kueCableBreak && kueCableBreak[slotIndex]) || (kueGroundFault && kueGroundFault[slotIndex]); - setCurrentAlarmStatus(alarmStatus); + setCurrentAlarmStatus(!!alarmStatus); // Wandelt string oder undefined in boolean um }; updateAlarmStatus(); @@ -352,10 +384,10 @@ function Kue705FO({ // Funktion zum Aktualisieren der Anzeige basierend auf dem Alarmstatus mit Icon und Blinken // Funktion zum Aktualisieren der Anzeige basierend auf dem Alarmstatus mit Icon und Blinken useEffect(() => { - let intervalId; + let intervalId: NodeJS.Timeout | undefined; // Funktion zum Blinken des Textes oder Icons - const setBlinkingText = (text) => { + const setBlinkingText = (text: string | JSX.Element) => { // Setze den Text direkt beim ersten Aufruf, ohne auf das Intervall zu warten setIsoDisplayValue(text); @@ -375,27 +407,27 @@ function Kue705FO({ }; // Priorisierte Alarmanzeige - if (kuePSTmMinus96V?.[slotIndex] === 1) { + if (Number(kuePSTmMinus96V?.[slotIndex]) === 1) { clearInterval(intervalId); // Stoppt das vorherige Intervall, falls aktiv setBlinkingText("PST-M prüfen"); - } else if (kueCableBreak?.[slotIndex] === 1) { + } else if (Number(kueCableBreak?.[slotIndex]) === 1) { clearInterval(intervalId); setBlinkingText(isoDisplayText); - } else if (kueGroundFault?.[slotIndex] === 1) { + } else if (Number(kueGroundFault?.[slotIndex]) === 1) { clearInterval(intervalId); setBlinkingText(groundFaultDisplayText); - } else if (kueAlarm1?.[slotIndex] === 1) { + } else if (Number(kueAlarm1?.[slotIndex]) === 1) { clearInterval(intervalId); setBlinkingText(isoFaultDisplayText); - } else if (kueAlarm2?.[slotIndex] === 1) { + } else if (Number(kueAlarm2?.[slotIndex]) === 1) { clearInterval(intervalId); setBlinkingText(loopFaultDisplayText); - } else if (kueOverflow?.[slotIndex] === 1) { + } else if (Number(kueOverflow?.[slotIndex]) === 1) { clearInterval(intervalId); setIsoDisplayValue(isoGreaterThan200); } else { clearInterval(intervalId); - setIsoDisplayValue(isolationswert); // Standardanzeige ohne Alarm + setIsoDisplayValue(isolationswert.toString()); // Standardanzeige ohne Alarm } // Cleanup bei Änderungen des Status oder Schließen des Effekts @@ -487,13 +519,13 @@ function Kue705FO({
- {kuePSTmMinus96V?.[slotIndex] !== 1 && - kueCableBreak?.[slotIndex] !== 1 && - kueGroundFault?.[slotIndex] !== 1 && - kueAlarm1?.[slotIndex] !== 1 && - kueAlarm2?.[slotIndex] !== 1 && - kueOverflow?.[slotIndex] !== 1 && ( + {Number(kuePSTmMinus96V?.[slotIndex]) !== 1 && + Number(kueCableBreak?.[slotIndex]) !== 1 && + Number(kueGroundFault?.[slotIndex]) !== 1 && + Number(kueAlarm1?.[slotIndex]) !== 1 && + Number(kueAlarm2?.[slotIndex]) !== 1 && + Number(kueOverflow?.[slotIndex]) !== 1 && (
ISO MOhm
)}
@@ -563,13 +595,15 @@ function Kue705FO({ @@ -636,6 +670,16 @@ function Kue705FO({ )} ); -} +}; export default Kue705FO; + +interface Kue705FOProps { + isolationswert: number | string | JSX.Element; + schleifenwiderstand: number | string; + modulName: string; + kueOnline: number; + slotIndex: number; + tdrLocation: number[]; + alarmStatus?: boolean; +} diff --git a/components/modulesStatus/Access1Status.jsx b/components/modulesStatus/Access1Status.tsx similarity index 100% rename from components/modulesStatus/Access1Status.jsx rename to components/modulesStatus/Access1Status.tsx diff --git a/components/modulesStatus/Access2Status.jsx b/components/modulesStatus/Access2Status.tsx similarity index 100% rename from components/modulesStatus/Access2Status.jsx rename to components/modulesStatus/Access2Status.tsx diff --git a/components/modulesStatus/CPLStatus.jsx b/components/modulesStatus/CPLStatus.tsx similarity index 100% rename from components/modulesStatus/CPLStatus.jsx rename to components/modulesStatus/CPLStatus.tsx diff --git a/components/modulesStatus/KabelModulStatus.jsx b/components/modulesStatus/KabelModulStatus.tsx similarity index 86% rename from components/modulesStatus/KabelModulStatus.jsx rename to components/modulesStatus/KabelModulStatus.tsx index d0b7b27..492fb56 100644 --- a/components/modulesStatus/KabelModulStatus.jsx +++ b/components/modulesStatus/KabelModulStatus.tsx @@ -1,4 +1,4 @@ -const KabelModulStatus = ({ +const KabelModulStatus: React.FC = ({ slot, kueCableBreak, kueAlarm1, @@ -56,3 +56,13 @@ const KabelModulStatus = ({ }; export default KabelModulStatus; + +interface KabelModulStatusProps { + slot: number; + kueCableBreak: number[]; + kueAlarm1: number[]; + kueAlarm2: number[]; + kueGroundFault: number[]; + isOnline: boolean; + moduleVersion: number; +} diff --git a/components/modulesStatus/XioPM1Status.jsx b/components/modulesStatus/XioPM1Status.tsx similarity index 100% rename from components/modulesStatus/XioPM1Status.jsx rename to components/modulesStatus/XioPM1Status.tsx diff --git a/components/modulesStatus/XioPM2Status.jsx b/components/modulesStatus/XioPM2Status.tsx similarity index 100% rename from components/modulesStatus/XioPM2Status.jsx rename to components/modulesStatus/XioPM2Status.tsx diff --git a/package-lock.json b/package-lock.json index 32ac8cd..f005a76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "@types/node": "22.10.10", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", + "@types/react-modal": "^3.16.3", "postcss": "^8.4.47", "rimraf": "^5.0.10", "tailwindcss": "^3.4.12", @@ -426,6 +427,15 @@ "@types/react": "^18.0.0" } }, + "node_modules/@types/react-modal": { + "version": "3.16.3", + "resolved": "https://registry.npmjs.org/@types/react-modal/-/react-modal-3.16.3.tgz", + "integrity": "sha512-xXuGavyEGaFQDgBv4UVm8/ZsG+qxeQ7f77yNrW3n+1J6XAstUy5rYHeIHPh1KzsGc6IkCIdu6lQ2xWzu1jBTLg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/use-sync-external-store": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", diff --git a/package.json b/package.json index e260348..3cd4f1b 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@types/node": "22.10.10", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", + "@types/react-modal": "^3.16.3", "postcss": "^8.4.47", "rimraf": "^5.0.10", "tailwindcss": "^3.4.12", diff --git a/pages/_app.js b/pages/_app.tsx similarity index 95% rename from pages/_app.js rename to pages/_app.tsx index 74e1e1d..1f825d1 100644 --- a/pages/_app.js +++ b/pages/_app.tsx @@ -1,4 +1,4 @@ -// _app.js +// pages/_app.tsx import { useEffect, useState } from "react"; import { loadWindowVariables } from "../utils/loadWindowVariables"; import Header from "../components/Header"; @@ -8,8 +8,9 @@ import "../styles/globals.css"; import { Provider } from "react-redux"; import { setVariables } from "../store/variablesSlice"; import store from "../store/store"; +import { AppProps } from "next/app"; -function MyApp({ Component, pageProps }) { +function MyApp({ Component, pageProps }: AppProps) { const [sessionExpired, setSessionExpired] = useState(false); useEffect(() => { diff --git a/pages/_document.js b/pages/_document.tsx similarity index 100% rename from pages/_document.js rename to pages/_document.tsx diff --git a/pages/_error.js b/pages/_error.js deleted file mode 100644 index 8584b0a..0000000 --- a/pages/_error.js +++ /dev/null @@ -1,19 +0,0 @@ -// pages/_error.js -import React from "react"; - -function Error({ statusCode }) { - return ( -

- {statusCode - ? `An error ${statusCode} occurred on server` - : "An error occurred on client"} -

- ); -} - -Error.getInitialProps = ({ res, err }) => { - const statusCode = res ? res.statusCode : err ? err.statusCode : 404; - return { statusCode }; -}; - -export default Error; diff --git a/pages/_error.tsx b/pages/_error.tsx new file mode 100644 index 0000000..fb2a94a --- /dev/null +++ b/pages/_error.tsx @@ -0,0 +1,24 @@ +// pages/_error.tsx +import React from "react"; +import { NextPage, NextPageContext } from "next"; + +interface ErrorProps { + statusCode?: number; +} + +const Error: NextPage = ({ statusCode }) => { + return ( +

+ {statusCode + ? `An error ${statusCode} occurred on server` + : "An error occurred on client"} +

+ ); +}; + +Error.getInitialProps = ({ res, err }: NextPageContext): ErrorProps => { + const statusCode = res?.statusCode || err?.statusCode || 404; + return { statusCode }; +}; + +export default Error; diff --git a/pages/access.js b/pages/access.tsx similarity index 100% rename from pages/access.js rename to pages/access.tsx diff --git a/pages/analogeEingaenge.js b/pages/analogeEingaenge.tsx similarity index 97% rename from pages/analogeEingaenge.js rename to pages/analogeEingaenge.tsx index 5cb83bc..608eb2a 100644 --- a/pages/analogeEingaenge.js +++ b/pages/analogeEingaenge.tsx @@ -4,7 +4,7 @@ import AnalogeEingaengeComponent from "../components/modules/AnalogeEingaengeCom import XioPM from "../components/modules/XioPM"; function AnalogeEingaenge() { - const [activeConfig, setActiveConfig] = useState(null); + const [activeConfig, setActiveConfig] = useState(null); // Mock-Daten für XIO-PM 1 const xioPm1Inputs = [ diff --git a/pages/dashboard.js b/pages/dashboard.tsx similarity index 100% rename from pages/dashboard.js rename to pages/dashboard.tsx diff --git a/pages/einausgaenge.js b/pages/einausgaenge.tsx similarity index 100% rename from pages/einausgaenge.js rename to pages/einausgaenge.tsx diff --git a/pages/generate-hash.js b/pages/generate-hash.ts similarity index 100% rename from pages/generate-hash.js rename to pages/generate-hash.ts diff --git a/pages/index.js b/pages/index.tsx similarity index 100% rename from pages/index.js rename to pages/index.tsx diff --git a/pages/kabelueberwachung.js b/pages/kabelueberwachung.tsx similarity index 100% rename from pages/kabelueberwachung.js rename to pages/kabelueberwachung.tsx diff --git a/pages/meldungen.js b/pages/meldungen.tsx similarity index 100% rename from pages/meldungen.js rename to pages/meldungen.tsx diff --git a/store/authSlice.js b/store/authSlice.ts similarity index 97% rename from store/authSlice.js rename to store/authSlice.ts index ac360bb..e91c009 100644 --- a/store/authSlice.js +++ b/store/authSlice.ts @@ -1,4 +1,4 @@ -// redux/authSlice.js +// redux/authSlice.ts import { createSlice } from "@reduxjs/toolkit"; const authSlice = createSlice({ diff --git a/store/rootReducer.ts b/store/rootReducer.ts new file mode 100644 index 0000000..45d07a1 --- /dev/null +++ b/store/rootReducer.ts @@ -0,0 +1,11 @@ +// store/rootReducer.ts +import { combineReducers } from "redux"; +import variablesReducer from "./variablesSlice"; +import authReducer from "./authSlice"; + +const rootReducer = combineReducers({ + variables: variablesReducer, + auth: authReducer, +}); + +export default rootReducer; diff --git a/store/store.js b/store/store.js deleted file mode 100644 index 1868adb..0000000 --- a/store/store.js +++ /dev/null @@ -1,14 +0,0 @@ -// store/store.js -import { configureStore } from "@reduxjs/toolkit"; -import variablesReducer from "./variablesSlice"; -import authReducer from "./authSlice"; - -const store = configureStore({ - reducer: { - variables: variablesReducer, - auth: authReducer, - }, - //devTools: process.env.NODE_ENV !== "production", // Aktiviert DevTools nur in der Entwicklung -}); - -export default store; diff --git a/store/store.ts b/store/store.ts new file mode 100644 index 0000000..7eee69b --- /dev/null +++ b/store/store.ts @@ -0,0 +1,16 @@ +// store/store.ts +import { configureStore } from "@reduxjs/toolkit"; +import rootReducer from "./rootReducer"; + +const store = configureStore({ + reducer: rootReducer, + //devTools: process.env.NODE_ENV !== "production", +}); + +// Exportiere den Typ RootState für den gesamten State +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; + +export default store; + +//devTools: process.env.NODE_ENV !== "production", // Aktiviert DevTools nur in der Entwicklung diff --git a/store/variablesSlice.js b/store/variablesSlice.js deleted file mode 100644 index 00f9b93..0000000 --- a/store/variablesSlice.js +++ /dev/null @@ -1,64 +0,0 @@ -// store/variablesSlice.js -import { createSlice } from "@reduxjs/toolkit"; - -const initialState = { - last20Messages: null, - 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, - kueOnline: [], - kueID: [], - kueIso: [], - kuePSTmMinus96V: [], - kueAlarm1: [], - kueAlarm2: [], - kueResidence: [], - kueCableBreak: [], - kueGroundFault: [], - kueLimit1: null, - kueLimit2Low: null, - kueDelay1: null, - kueLoopInterval: null, - kueVersion: null, - tdrAtten: null, - tdrPulse: null, - tdrSpeed: null, - tdrAmp: null, - tdrTrigger: null, - tdrLocation: null, - tdrActive: null, - kueOverflow: null, - tdrLast: null, - appVersion: null, -}; - -const variablesSlice = createSlice({ - name: "variables", - initialState, - reducers: { - setVariable(state, action) { - const { key, value } = action.payload; - state[key] = value; - }, - setVariables(state, action) { - Object.entries(action.payload).forEach(([key, value]) => { - state[key] = value; - }); - }, - }, -}); - -export const { setVariable, setVariables, updateValues } = - variablesSlice.actions; -export default variablesSlice.reducer; diff --git a/store/variablesSlice.ts b/store/variablesSlice.ts new file mode 100644 index 0000000..892dc28 --- /dev/null +++ b/store/variablesSlice.ts @@ -0,0 +1,148 @@ +// store/variablesSlice.ts +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; + +// Typ für den State +export interface VariablesState { + //------------ + kueBezeichnungen: string[]; + isolationsgrenzwerte: number[]; + verzoegerung: number[]; + untereSchleifenGrenzwerte: number[]; + obereSchleifenGrenzwerte: number[]; + schleifenintervall: number[]; + //--------------- + last20Messages: string | null; + 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; + kueOnline: string[]; + kueID: string[]; + kueIso: string[]; + kuePSTmMinus96V: string[]; + kueAlarm1: string[]; + kueAlarm2: string[]; + kueResidence: string[]; + kueCableBreak: string[]; + kueGroundFault: string[]; + kueLimit1: number | null; + kueLimit2Low: number | null; + kueDelay1: number | null; + kueLoopInterval: number | null; + kueVersion: number[] | null; + tdrAtten: number | null; + tdrPulse: number | null; + tdrSpeed: number | null; + tdrAmp: number | null; + tdrTrigger: number | null; + tdrLocation: number | null; + tdrActive: boolean | null; + kueOverflow: string | null; + tdrLast: string | null; + appVersion: string | null; + win_analogeEingaenge1: string | null; + win_analogeEingaenge2: string | null; + win_analogeEingaenge3: string | null; + win_analogeEingaenge4: string | null; + win_analogeEingaenge5: string | null; + win_analogeEingaenge6: string | null; + win_analogeEingaenge7: string | null; + win_analogeEingaenge8: string | null; +} + +// Initialer Zustand +const initialState: VariablesState = { + //------------ + kueBezeichnungen: [], + isolationsgrenzwerte: [], + verzoegerung: [], + untereSchleifenGrenzwerte: [], + obereSchleifenGrenzwerte: [], + schleifenintervall: [], + //--------------- + last20Messages: null, + 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, + kueOnline: [], + kueID: [], + kueIso: [], + kuePSTmMinus96V: [], + kueAlarm1: [], + kueAlarm2: [], + kueResidence: [], + kueCableBreak: [], + kueGroundFault: [], + kueLimit1: null, + kueLimit2Low: null, + kueDelay1: null, + kueLoopInterval: null, + kueVersion: null, + tdrAtten: null, + tdrPulse: null, + tdrSpeed: null, + tdrAmp: null, + tdrTrigger: null, + tdrLocation: null, + tdrActive: null, + kueOverflow: null, + tdrLast: null, + appVersion: null, + win_analogeEingaenge1: null, + win_analogeEingaenge2: null, + win_analogeEingaenge3: null, + win_analogeEingaenge4: null, + win_analogeEingaenge5: null, + win_analogeEingaenge6: null, + win_analogeEingaenge7: null, + win_analogeEingaenge8: null, +}; + +// Slice erstellen +const variablesSlice = createSlice({ + name: "variables", + initialState, + reducers: { + setVariable( + state, + action: PayloadAction<{ + key: keyof VariablesState; + value: VariablesState[keyof VariablesState]; + }> + ) { + const { key, value } = action.payload; + (state[key] as VariablesState[keyof VariablesState]) = value; + }, + setVariables(state, action: PayloadAction>) { + Object.entries(action.payload).forEach(([key, value]) => { + (state[ + key as keyof VariablesState + ] as VariablesState[keyof VariablesState]) = value!; + }); + }, + }, +}); + +export const { setVariable, setVariables } = variablesSlice.actions; +export default variablesSlice.reducer; diff --git a/tsconfig.json b/tsconfig.json index b38a6ae..5eeadd9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,7 +24,7 @@ "next-env.d.ts", "**/*.ts", "**/*.tsx" - ], +, "public/CPLmockData/SERVICE/System.js", "public/CPLmockData/SERVICE/Start.js", "public/CPLmockData/SERVICE/kueData.js", "public/CPLmockData/SERVICE/de.js", "public/CPLmockData/SERVICE/ae.js", "public/CPL/SERVICE/System.js", "public/CPL/SERVICE/Start.js", "public/CPL/SERVICE/kueData.js", "public/CPL/SERVICE/de.js", "public/CPL/SERVICE/ae.js" ], "exclude": [ "node_modules" ] diff --git a/utils/decodeToken.js b/utils/decodeToken.ts similarity index 87% rename from utils/decodeToken.js rename to utils/decodeToken.ts index 89d2756..0785b32 100644 --- a/utils/decodeToken.js +++ b/utils/decodeToken.ts @@ -1,4 +1,4 @@ -function decodeToken(token) { +function decodeToken(token: string) { try { const base64Payload = token.split(".")[1]; const payload = JSON.parse(atob(base64Payload)); diff --git a/utils/indexedDB.js b/utils/indexedDB.ts similarity index 100% rename from utils/indexedDB.js rename to utils/indexedDB.ts diff --git a/utils/loadWindowVariables.js b/utils/loadWindowVariables.ts similarity index 59% rename from utils/loadWindowVariables.js rename to utils/loadWindowVariables.ts index f711a52..837ad90 100644 --- a/utils/loadWindowVariables.js +++ b/utils/loadWindowVariables.ts @@ -1,7 +1,11 @@ -// utils/loadWindowVariables.js -export async function loadWindowVariables() { +// utils/loadWindowVariables.ts +interface WindowVariables { + [key: string]: any; // Allgemeiner Typ für die Dynamik, kann spezifischer angepasst werden, falls bekannt +} + +export async function loadWindowVariables(): Promise { return new Promise((resolve, reject) => { - const requiredVars = [ + const requiredVars: string[] = [ "win_last20Messages", "win_deviceName", "win_mac1", @@ -52,7 +56,7 @@ export async function loadWindowVariables() { "win_analogeEingaenge8", ]; - const loadScript = (src) => { + const loadScript = (src: string): Promise => { return new Promise((resolve, reject) => { const script = document.createElement("script"); const environment = process.env.NEXT_PUBLIC_NODE_ENV || "production"; @@ -61,13 +65,19 @@ export async function loadWindowVariables() { ? `/CPL?/CPL/SERVICE/${src}` : `/CPLmockData/SERVICE/${src}`; script.async = true; - script.onload = resolve; - script.onerror = reject; + script.onload = () => resolve(); + script.onerror = () => reject(new Error(`Script load error: ${src}`)); document.head.appendChild(script); }); }; - const scripts = ["de.js", "ae.js", "kueData.js", "Start.js", "System.js"]; + const scripts: string[] = [ + "de.js", + "ae.js", + "kueData.js", + "Start.js", + "System.js", + ]; scripts .reduce( @@ -75,19 +85,24 @@ export async function loadWindowVariables() { Promise.resolve() ) .then(() => { - const variablesObj = requiredVars.reduce((acc, variable) => { - if (window[variable] !== undefined) { - // Wenn es sich um kueID handelt, ersetze %20 durch Leerzeichen - if (variable === "win_kueID" && Array.isArray(window[variable])) { - acc[variable.replace("win_", "")] = window[variable].map((id) => - id.replace(/%20/g, " ") - ); - } else { - acc[variable.replace("win_", "")] = window[variable]; + 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; + } } - } - return acc; - }, {}); + return acc; + }, + {} + ); resolve(variablesObj); }) .catch((error) => {