"use client"; // components/modules/kue705FO/Kue705FO.tsx import React, { useState, useMemo, useEffect, useRef } from "react"; import dynamic from "next/dynamic"; // eslint-disable-next-line @typescript-eslint/no-explicit-any const Marquee: any = dynamic(() => import("react-fast-marquee"), { ssr: false, }); import { useSelector } from "react-redux"; import KueModal from "./modals/SettingsModalWrapper"; // import FallSensors from "../../fall-detection-sensors/FallSensors"; import "bootstrap-icons/font/bootstrap-icons.css"; // Import Bootstrap Icons import { Kue705FOProps } from "../../../../types/Kue705FOProps"; // Import the new specialized ChartView components import IsoChartView from "./Charts/IsoMeasurementChart/IsoChartView"; import LoopChartView from "./Charts/LoopMeasurementChart/LoopChartView"; import TDRChartView from "./Charts/TDRChart/TDRChartView"; import KVZChartView from "./Charts/KVZChart/KVZChartView"; import SlotActivityOverlay from "./SlotActivityOverlay"; // Keep ChartSwitcher import for backwards compatibility if needed // import ChartSwitcher from "./Charts/ChartSwitcher"; // Remove separate chart imports since we use ChartView components // import IsoMeasurementChart from "./Charts/IsoMeasurementChart/IsoMeasurementChart"; // import LoopMeasurementChart from "./Charts/LoopMeasurementChart/LoopMeasurementChart"; //-------Redux Toolkit-------- import { RootState } from "../../../../redux/store"; import { useDispatch } from "react-redux"; //-------hooks---------------- import useAlarmStatus from "./hooks/useAlarmStatus"; import useKueVersion from "./hooks/useKueVersion"; import useIsoDisplay from "./hooks/useIsoDisplay"; import useLoopDisplay from "./hooks/useLoopDisplay"; import useModulName from "./hooks/useModulName"; //--------handlers---------------- // Keep needed imports import handleOpenModal from "./handlers/handleOpenModal"; import handleCloseModal from "./handlers/handleCloseModal"; // Remove unused chart modal handlers since we use direct ChartView components // import handleOpenChartModal from "./handlers/handleOpenChartModal"; // import handleCloseChartModal from "./handlers/handleCloseChartModal"; // import handleRefreshClick from "./handlers/handleRefreshClick"; const Kue705FO: React.FC = ({ isolationswert, schleifenwiderstand, modulName, kueOnline, slotIndex, }) => { /* console.log( `Rendering Kue705FO - SlotIndex: ${slotIndex}, ModulName: ${modulName}` ); */ const dispatch = useDispatch(); const { kueName } = useSelector((state: RootState) => state.kueDataSlice); // Admin authentication hook for security - using showModal as true for continuous auth check // Admin Auth hook retained (result not currently needed after KVZ visibility change) // const { isAdminLoggedIn } = useAdminAuth(true); // Modulname (max 48 Zeichen) vorbereiten const moduleNameRaw = useMemo( () => kueName?.[slotIndex] || `Modul ${slotIndex + 1}`, [kueName, slotIndex] ); const moduleName48 = useMemo( () => typeof moduleNameRaw === "string" ? moduleNameRaw.slice(0, 48) : String(moduleNameRaw), [moduleNameRaw] ); const [activeButton, setActiveButton] = useState<"Schleife" | "TDR" | "ISO">( "Schleife" ); const [, setloopTitleText] = useState("Schleifenwiderstand [kOhm]"); const [isoDisplayText] = useState("Aderbruch"); const [groundFaultDisplayText] = useState("Erdschluss"); const [loopFaultDisplayText] = useState("Schleifenfehler"); const [isoFaultDisplayText] = useState("Isolationsfehler"); const [isoGreaterThan200] = useState(">200 MOhm"); const [showModal, setShowModal] = useState(false); // Separate modal states for each ChartView const [showIsoModal, setShowIsoModal] = useState(false); const [showRslModal, setShowRslModal] = useState(false); const [showTdrModal, setShowTdrModal] = useState(false); const [showKvzModal, setShowKvzModal] = useState(false); // Keep original showChartModal for backwards compatibility if needed // const [showChartModal, setShowChartModal] = useState(false); // Removed unused loopMeasurementCurveChartData state //------- Redux-Variablen abrufen-------------------------------- const { kueVersion: reduxKueVersion, kueCableBreak: kueCableBreakRaw, kueGroundFault: kueGroundFaultRaw, kueAlarm1: kueAlarm1Raw, kueAlarm2: kueAlarm2Raw, kueOverflow: kueOverflowRaw, kuePSTmMinus96V, // <- richtig, weil so im State vorhanden tdrActive, // <- TDR aktiv Status hinzugefügt kvzPresence, // <- KVz Presence Array hinzugefügt kvzActive, // <- KVz Active Array hinzugefügt // kvzStatus, // <- KVz LED Status Array (jetzt nur im KVZ Modal verwendet) } = useSelector((state: RootState) => state.kueDataSlice); //--------------------------------------------- const kueCableBreak = useMemo( () => kueCableBreakRaw?.map(Number) ?? [], [kueCableBreakRaw] ); const kueGroundFault = useMemo( () => kueGroundFaultRaw?.map(Number) ?? [], [kueGroundFaultRaw] ); const kueAlarm1 = useMemo( () => kueAlarm1Raw?.map(Number) ?? [], [kueAlarm1Raw] ); const kueAlarm2 = useMemo( () => kueAlarm2Raw?.map(Number) ?? [], [kueAlarm2Raw] ); const kueOverflow = useMemo( () => kueOverflowRaw?.map(Number) ?? [], [kueOverflowRaw] ); //-------------------------handlers------------------------- const openModal = () => handleOpenModal(setShowModal); const closeModal = () => handleCloseModal(setShowModal); // New ChartView handlers - direct modal opening const openIsoModal = () => { setActiveButton("ISO"); // Set Redux state for ISO type dispatch({ type: "kabelueberwachungChart/setSelectedSlotType", payload: 1, // 1 = Isolationswiderstand }); dispatch({ type: "kabelueberwachungChart/setSlotNumber", payload: slotIndex, }); setShowIsoModal(true); }; const closeIsoModal = () => { setShowIsoModal(false); }; const openRslModal = () => { setActiveButton("Schleife"); setloopTitleText("Schleifenwiderstand [kOhm]"); setLoopDisplayValue(Number(schleifenwiderstand)); dispatch({ type: "kabelueberwachungChart/setSelectedSlotType", payload: 2, }); // RSL type dispatch({ type: "kabelueberwachungChart/setSlotNumber", payload: slotIndex, }); setShowRslModal(true); }; const closeRslModal = () => { setShowRslModal(false); }; const openTdrModal = () => { setActiveButton("TDR"); setloopTitleText("Entfernung [km]"); setShowTdrModal(true); }; const closeTdrModal = () => { setShowTdrModal(false); }; const openKvzModal = () => { setShowKvzModal(true); }; const closeKvzModal = () => setShowKvzModal(false); //---------------------------------- //hooks einbinden const kueVersion = useKueVersion(slotIndex, reduxKueVersion); const currentAlarmStatus = useAlarmStatus( slotIndex, kueAlarm1, kueAlarm2, kueCableBreak, kueGroundFault ); const isoDisplayValue = useIsoDisplay( slotIndex, !!kuePSTmMinus96V?.[slotIndex], !!kueCableBreak?.[slotIndex], !!kueGroundFault?.[slotIndex], !!kueAlarm1?.[slotIndex], !!kueAlarm2?.[slotIndex], !!kueOverflow?.[slotIndex], Number(isolationswert), isoDisplayText, groundFaultDisplayText, isoFaultDisplayText, loopFaultDisplayText, isoGreaterThan200 ); const { setCurrentModulName } = useModulName(slotIndex, modulName); //--------------------------------- // Version-gate für Laufschrift: erst ab V4.30 aktiv const parseVersion = (v?: string): [number, number, number] => { if (!v) return [0, 0, 0]; const m = String(v).match(/(\d+)(?:\.(\d+))?(?:\.(\d+))?/); if (!m) return [0, 0, 0]; const major = parseInt(m[1] || "0", 10) || 0; const minor = parseInt(m[2] || "0", 10) || 0; const patch = parseInt(m[3] || "0", 10) || 0; return [major, minor, patch]; }; const gte = (a: [number, number, number], b: [number, number, number]) => { if (a[0] !== b[0]) return a[0] > b[0]; if (a[1] !== b[1]) return a[1] > b[1]; return a[2] >= b[2]; }; const marqueeOverride = process.env.NEXT_PUBLIC_ENABLE_KUE_MARQUEE === "1" || process.env.NEXT_PUBLIC_ENABLE_KUE_MARQUEE === "true"; const scrollFeatureEnabled = useMemo( () => marqueeOverride || gte(parseVersion(kueVersion), [4, 30, 0]), [kueVersion, marqueeOverride] ); // Überlängen-Erkennung für Laufschrift const nameContainerRef = useRef(null); const measureTextRef = useRef(null); const [shouldScroll, setShouldScroll] = useState(false); useEffect(() => { const measure = () => { if (!scrollFeatureEnabled) { setShouldScroll(false); return; } const container = nameContainerRef.current; const text = measureTextRef.current; if (!container || !text) { setShouldScroll(false); return; } const needs = text.scrollWidth > container.clientWidth + 2; setShouldScroll(needs); }; measure(); window.addEventListener("resize", measure); return () => window.removeEventListener("resize", measure); }, [moduleName48, scrollFeatureEnabled]); //--------------------------------- // TDR Distanz wird im Display nicht angezeigt – Daten für Modal werden separat geladen //--------------------------------- const rslValue = typeof schleifenwiderstand === "number" ? schleifenwiderstand : Number(schleifenwiderstand); const { loopDisplayValue, setLoopDisplayValue } = useLoopDisplay( rslValue, activeButton ); // TDR aktiv Status für diesen Slot prüfen const isTdrActiveForSlot = tdrActive?.[slotIndex] === 1; // KVz aktiv Status für diesen Slot prüfen - nur wenn Admin authentifiziert ist, KVz vorhanden ist UND aktiviert ist // Anpassung: KVZ Button soll sichtbar/benutzbar bleiben, auch wenn Admin sich abmeldet, // sobald KVZ Präsenz + Aktiv-Flag gesetzt sind. Admin wird nur zum Aktivieren benötigt. const isKvzActiveForSlot = kvzPresence?.[slotIndex] === 1 && kvzActive?.[slotIndex] === 1; // Removed useChartData(loopMeasurementCurveChartData) as the state was unused //--------------------------------- return (
{/* Per-slot activity overlay */} {kueOnline === 1 ? ( <>
{slotIndex + 1}

KÜ705-FO

{} {showModal && ( )}
Betrieb Alarm
{/* Schwarzes Display mit drei Zeilen: Alarm, ISO, Schleife */}
{/* 1. Zeile: Alarmtext in Rot, sonst "Status: OK" */} {Number(kuePSTmMinus96V?.[slotIndex]) === 1 ? "Messpannung" : Number(kueCableBreak?.[slotIndex]) === 1 ? "Aderbruch" : Number(kueGroundFault?.[slotIndex]) === 1 ? "Erdschluss" : Number(kueAlarm1?.[slotIndex]) === 1 ? "Isolationsfehler" : Number(kueAlarm2?.[slotIndex]) === 1 ? "Schleifenfehler" : " "} {"\u00A0"} {/* Status: OK*/} {/* 2. Zeile: ISO-Wert, immer anzeigen */} {isoDisplayValue === "Abgleich" ? "ISO: Abgleich" : `ISO: ${Number(isolationswert) .toFixed(2) .replace(".", ",")} MOhm`} {/* 3. Zeile: Schleifenwert (RSL) immer anzeigen, unabhängig von aktivem Button */} {`RSL: ${Number(loopDisplayValue) .toFixed(3) .replace(".", ",")} kOhm`}
{/* Hidden measuring span for overflow detection (kept measurable) */} {moduleName48}
{shouldScroll && scrollFeatureEnabled ? ( {moduleName48} ) : ( {moduleName48} )}
{kueVersion}
{/* Modal für Einstellungen */} ) : (
{/* Das soll rausgenommen werden

Kein Modul im Slot {slotIndex + 0}

*/}
)} {/* Messkurven-Button unter dem Modul */} {kueOnline === 1 && ( <> {/* Überschrift: Detailansicht ISO und RSL als Buttons (Firmenblau) nebeneinander TDR und KVz Buttons (Firmenblau) nebeneinander Wenn kein TDR oder kein KVz: nur grauer Button ohne Text */}
{/* Detailansicht Header */} Detailansicht {/* ISO and RSL Buttons */}
{/* TDR and KVz Buttons */}
{/* TDR Button - blau mit Text wenn aktiv, grau ohne Text wenn inaktiv */} {/* KVz Button - blau mit Text wenn aktiv, grau ohne Text wenn inaktiv */}
{/* Messkurve Button */} {/* TDR Messkurve und Schleife Messkurve Buttons */}
{/* ISO Chart Modal */}
{/* ISO Chart Modal */} {/* RSL Chart Modal */} {/* TDR Chart Modal - nur wenn TDR aktiv ist */} {isTdrActiveForSlot && ( )} {isKvzActiveForSlot && ( )} )} {/* Früher inline Panel – jetzt eigenes Modal (KVZChartView) */} {/* {showKvzPanel && isKvzActiveForSlot && (
)} */} {/* Offline-View */} {kueOnline !== 1 && (
{/* Das soll rausgenommen werden

Kein Modul im Slot {slotIndex + 0}

*/}
)}
); }; export default Kue705FO;