Files
CPLv4.0/components/main/kabelueberwachung/kue705FO/Kue705FO.tsx
Ismail Ali c0101b35ab refactor: Umbenennung von 'chartData' in Redux kabelueberwachung Slice zu 'loopMeasurementCurveChartData' für bessere Klarheit
Die Variable 'chartData' wurde in 'loopMeasurementCurveChartData' umbenannt, um den Inhalt und Zweck der Daten klarer zu definieren. Diese Änderung verbessert die Lesbarkeit und Wartbarkeit des Codes, indem sie die Bedeutung der Variablen präziser beschreibt.
2025-02-22 16:32:40 +01:00

464 lines
17 KiB
TypeScript

"use client"; // components/modules/kue705FO/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 "./KueModal";
import "bootstrap-icons/font/bootstrap-icons.css"; // Import Bootstrap Icons
import { RootState } from "../../../../redux/store";
import { DataTDR } from "../../../../redux/types/chartDataTypesTDR";
import { useDispatch } from "react-redux";
import {
setSelectedChartData,
setSelectedFileName,
} from "../../../../redux/slices/variablesSlice";
import { createLoopChart, createTDRChart } from "../../../../utils/chartUtils";
import { getAlarmDisplayText } from "../../../../utils/alarmUtils";
import { goLoop } from "../../../../utils/goLoop";
import { goTDR } from "../../../../utils/goTDR";
import { loadTDRChartData } from "../../../../utils/loadTDRChartData";
import { loadLoopChartData } from "../../../../utils/loadLoopChartData";
import { Kue705FOProps } from "../../../../types/components/Kue705FOProps";
import ChartSwitcher from "./Charts/ChartSwitcher";
import { setActiveMode } from "../../../../redux/slices/chartDataSlice";
import LoopMeasurementChart from "./Charts/LoopMeasurementChart/LoopMeasurementChart";
import TDRChart from "./Charts/TDRChart/TDRChart";
import handleButtonClick from "./kue705FO-Funktionen/handleButtonClick";
import { setChartOpen } from "../../../../redux/slices/kabelueberwachungChartSlice";
import { setSlotNumber } from "../../../../redux/slices/kabelueberwachungChartSlice";
const Kue705FO: React.FC<Kue705FOProps> = ({
isolationswert,
schleifenwiderstand,
modulName,
kueOnline,
slotIndex,
tdrLocation,
alarmStatus,
}) => {
/* console.log(
`Rendering Kue705FO - SlotIndex: ${slotIndex}, ModulName: ${modulName}`
); */
const selectedChartData = useSelector(
(state: RootState) => state.variables.selectedChartData
);
const dispatch = useDispatch();
const chartRef = useRef(null);
const [zoomPlugin, setZoomPlugin] = useState<any>(null); // Plugin-Status für Chart.js
const [kueVersion, setKueVersion] = useState("V4.19");
const [currentAlarmStatus, setCurrentAlarmStatus] = useState(false);
const [currentModulName, setCurrentModulName] = useState(modulName);
const [activeButton, setActiveButton] = useState<"Schleife" | "TDR">(
"Schleife"
);
const [loopTitleText, setloopTitleText] = useState(
"Schleifenwiderstand [kOhm]"
);
const [loopDisplayValue, setLoopDisplayValue] = useState(schleifenwiderstand); // Initialisiere den loopDisplayValue mit schleifenwiderstand
const [isoDisplayText, setIsoDisplayText] = useState("Aderbruch");
const [groundFaultDisplayText, setGroundFaultDisplayText] =
useState("Erdschluss");
const [loopFaultDisplayText, setLoopFaultDisplayText] =
useState("Schleifenfehler");
const [isoFaultDisplayText, setIsoFaultDisplayText] =
useState("Isolationsfehler");
const [isoGreaterThan200, setIsoGreaterThan200] = useState(">200 MOhm");
const [loading, setLoading] = useState(false);
const [isoDisplayValue, setIsoDisplayValue] = useState<
string | JSX.Element
>(); //Test erstmal leer ohne isolationswert
const [showModal, setShowModal] = useState(false);
const [showChartModal, setShowChartModal] = useState(false);
const [loopMeasurementCurveChartData, setLoopMeasurementCurveChartData] =
useState(null);
useEffect(() => {
if (loopMeasurementCurveChartData) {
dispatch(setSelectedChartData(loopMeasurementCurveChartData));
}
}, [loopMeasurementCurveChartData, dispatch]); // Führe dispatch nur aus, wenn loopMeasurementCurveChartData sich ändert
// Redux-Variablen abrufen
const {
kuePSTmMinus96V,
kueCableBreak,
kueGroundFault,
kueAlarm1,
kueAlarm2,
kueOverflow,
kueVersion: reduxKueVersion,
tdrActive,
} = useSelector((state: RootState) => state.variables);
const handleOpenModal = () => setShowModal(true);
const handleCloseModal = () => setShowModal(false);
const handleOpenChartModal = () => {
setShowChartModal(true);
dispatch(setChartOpen(true));
dispatch(setSlotNumber(slotIndex + 1)); // Slot-Nummer speichern
if (activeButton === "TDR") {
dispatch(setActiveMode("TDR"));
} else {
dispatch(setActiveMode("Schleife"));
}
};
// Funktion aufrufen in handleRefreshClick
const handleRefreshClick = () => {
if (activeButton === "Schleife") {
goLoop(slotIndex, setLoading);
} else if (activeButton === "TDR") {
goTDR(slotIndex, setLoading);
}
};
const handleCloseChartModal = () => {
if (chartInstance.current) {
console.log("Chart wird beim Schließen des Modals zerstört.");
chartInstance.current.destroy();
chartInstance.current = null;
}
setShowChartModal(false);
};
// Funktion zum Erstellen des TDR-Charts
const chartInstance = useRef<Chart | null>(null);
const selectedFileName = useSelector(
(state: RootState) => state.variables.selectedFileName
);
// Füge das Plugin zu Chart.js hinzu
useEffect(() => {
// Lade das Plugin nur, wenn `window` verfügbar ist
if (typeof window !== "undefined") {
import("chartjs-plugin-zoom").then((mod) => {
setZoomPlugin(mod.default); // Setze das Plugin
Chart.register(mod.default); // Plugin zur Chart.js-Instanz registrieren
});
}
}, []);
interface DataLoop {
t: number; // Zeit oder Index
m: number; // Isolationswiderstand
n: number; // Schleifenwiderstand
}
useEffect(() => {
const updateAlarmStatus = () => {
const alarmStatus =
(kueAlarm1 && kueAlarm1[slotIndex]) ||
(kueAlarm2 && kueAlarm2[slotIndex]) ||
(kueCableBreak && kueCableBreak[slotIndex]) ||
(kueGroundFault && kueGroundFault[slotIndex]);
setCurrentAlarmStatus(!!alarmStatus); // Wandelt string oder undefined in boolean um
};
updateAlarmStatus();
const interval = setInterval(updateAlarmStatus, 10000);
return () => clearInterval(interval);
}, [slotIndex, kueAlarm1, kueAlarm2, kueCableBreak, kueGroundFault]);
useEffect(() => {
if (reduxKueVersion?.[slotIndex]) {
setKueVersion("V" + Number(reduxKueVersion[slotIndex]) / 100);
}
}, [slotIndex, reduxKueVersion]);
//---------------------------------------------------
// 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(() => {
setIsoDisplayValue(
getAlarmDisplayText(
slotIndex,
kuePSTmMinus96V,
kueCableBreak,
kueGroundFault,
kueAlarm1,
kueAlarm2,
kueOverflow ?? undefined,
isolationswert,
isoDisplayText,
groundFaultDisplayText,
isoFaultDisplayText,
loopFaultDisplayText,
isoGreaterThan200
)
);
}, [
slotIndex,
isolationswert,
isoDisplayText,
groundFaultDisplayText,
isoFaultDisplayText,
loopFaultDisplayText,
isoGreaterThan200,
kuePSTmMinus96V,
kueCableBreak,
kueGroundFault,
kueAlarm1,
kueAlarm2,
kueOverflow,
]);
//---------------------------------------------------
// Effekt, um Modulnamen zu aktualisieren, wenn sich der Prop ändert
useEffect(() => {
setCurrentModulName(modulName);
//console.log(`Modulname aktualisiert für Slot ${slotIndex}:`, modulName);
}, [modulName, slotIndex]);
//---------------------------------------------------
// Aktualisiert den Schleifenwiderstand, wenn sich der `schleifenwiderstand`-Prop ändert
useEffect(() => {
if (activeButton === "Schleife") {
setLoopDisplayValue(schleifenwiderstand);
}
}, [schleifenwiderstand, activeButton]);
//---------------------------------------------------
const noLetter = (e: React.KeyboardEvent<HTMLInputElement>) => {
const input = e.currentTarget;
input.value = input.value.replace(/[^0-9]/g, "");
};
//---------------------------------------------------
//Auswahlmenü für Jahr, Monat und Sortierung
const [jahr, setJahr] = useState(new Date().getFullYear());
const [monat, setMonat] = useState(new Date().getMonth() + 1);
const [sortAscending, setSortAscending] = useState(true);
const handleSortToggle = () => {
setSortAscending(!sortAscending);
console.log(
"Sortierung umkehren:",
sortAscending ? "Absteigend" : "Aufsteigend"
);
};
const handleAktualisieren = () => {
console.log("Aktualisieren mit Jahr:", jahr, "Monat:", monat);
// Logik für die Aktualisierung hinzufügen
};
//---------------------------------------------------
//----------------------------------
useEffect(() => {
if (selectedChartData) {
createTDRChart(selectedChartData); // Neues Chart erstellen
}
return () => {
// Cleanup beim Komponentenwechsel
if (chartInstance.current) {
console.log("Chart wird beim Komponentenwechsel zerstört.");
chartInstance.current.destroy();
chartInstance.current = null;
}
};
}, [selectedChartData]);
//----------------------------------
return (
<div
className="relative bg-gray-300 w-[7.25rem] h-[24.375rem] border border-gray-400 transform laptop:-translate-y-12 2xl:-translate-y-0
scale-100 sm:scale-95 md:scale-100 lg:scale-105 xl:scale-90 2xl:scale-125 top-3
"
>
{kueOnline === 1 ? (
<>
<div className="relative w-[7.075rem] h-[15.156rem] bg-littwin-blue border-[0.094rem] border-gray-400 z-0">
<div className="flex items-start justify-between h-[1.875rem]">
<div className="relative w-[1.25rem] h-[1.25rem] bg-gray-800 flex items-center justify-center">
<span className="text-white text-[0.625rem]">
{slotIndex + 1}
</span>
</div>
<h3 className="text-white font-bold text-[0.563rem] mr-[1rem]">
KÜ705-FO
</h3>
<button
onClick={handleOpenModal}
className="w-[0.938rem] h-[0.938rem] bg-gray-400 flex items-center justify-center"
>
<span className="text-white text-[1.25rem]"></span>
</button>
</div>
{}
<KueModal
showModal={showModal}
onClose={handleCloseModal}
slot={slotIndex}
onModulNameChange={setCurrentModulName}
/>
<div className="flex flex-col mt-[0.625rem] ml-[0.625rem]">
<div className="flex items-center space-x-[0.25rem] mt-[0.625rem]">
<div className="flex flex-col items-start space-y-[0.063rem] mr-[0.063rem]">
<span className="text-white text-[0.625rem]">Betrieb</span>
<span className="text-white text-[0.625rem]">Alarm</span>
</div>
<div className="flex flex-col items-center space-y-[0.188rem]">
<div className="w-[0.625rem] h-[0.625rem] bg-green-500 rounded-full"></div>
<div
className={`w-[0.625rem] h-[0.625rem] rounded-full ${
currentAlarmStatus ? "bg-red-500" : "bg-gray-300"
}`}
></div>
</div>
</div>
</div>
{/* Anzeige des Isolation */}
<div className="relative mt-[3.125rem] mx-auto bg-black text-white w-[6.25rem] h-[2.5rem] flex items-center justify-center text-[1.125rem] z-10">
<div className="text-center">
<span
className={
Number(kuePSTmMinus96V?.[slotIndex]) === 1 ||
Number(kueCableBreak?.[slotIndex]) === 1 ||
Number(kueGroundFault?.[slotIndex]) === 1 ||
Number(kueAlarm1?.[slotIndex]) === 1 ||
Number(kueAlarm2?.[slotIndex]) === 1
? "text-red-500 text-[0.875rem]"
: Number(kueOverflow?.[slotIndex]) === 1
? "text-white text-[0.875rem]"
: ""
}
>
{isoDisplayValue}
</span>
{Number(kuePSTmMinus96V?.[slotIndex]) !== 1 &&
Number(kueCableBreak?.[slotIndex]) !== 1 &&
Number(kueGroundFault?.[slotIndex]) !== 1 &&
Number(kueAlarm1?.[slotIndex]) !== 1 &&
Number(kueAlarm2?.[slotIndex]) !== 1 &&
Number(kueOverflow?.[slotIndex]) !== 1 && (
<div className="text-[0.5rem]">ISO MOhm</div>
)}
</div>
</div>
<div className="absolute top-0 left-[4.688rem] w-[0.188rem] h-full bg-white z-0"></div>
<div className="absolute top-[2.5rem] left-[4.688rem] w-[2.5rem] h-[0.188rem] bg-white z-0"></div>
<div className="absolute bottom-[1.25rem] left-0 right-0 text-black text-[0.625rem] bg-gray-300 p-[0.063rem] text-center">
{currentModulName || `Modul ${slotIndex + 1}`}
</div>
<div className="absolute bottom-[0.063rem] right-[0.063rem] text-black text-[0.5rem]">
{kueVersion}
</div>
</div>
{/* loopDisplay: Zeigt Schleifenwiderstand oder TDR-Distanz an, je nach Modus */}
<div className="absolute bottom-[0.063rem] left-[0.068rem] w-[7.074rem] h-[8.125rem] bg-gray-300 border-[0.094rem] border-gray-400 p-[0.063rem]">
<span className="text-black text-[0.438rem] absolute top-[0.125rem] left-[0.063rem] mt-1">
{loopTitleText}
</span>
<div className="relative w-full h-[2.813rem] bg-gray-100 border border-gray-400 flex items-center justify-center mt-4">
<button
onClick={handleRefreshClick} // Dynamische Funktion basierend auf aktivem Button
className="absolute -top-[0.063rem] -right-[0.063rem] w-[1.25rem] h-[1.25rem] bg-gray-400 flex items-center justify-center"
disabled={loading} // Disable button while loading
>
<span className="text-white text-[1.125rem]"></span>
</button>
<div className="absolute bottom-[0.313rem] left-1/2 transform -translate-x-1/2 w-[6.25rem] flex justify-center items-center">
<div className="text-center text-black text-[0.625rem]">
<p>
{loopDisplayValue +
(activeButton === "Schleife" ? " KOhm" : " Km")}
</p>
</div>
</div>
</div>
<div className="flex mt-1 space-x-[0.063rem] ">
<button
onClick={() =>
handleButtonClick(
"Schleife",
setActiveButton,
setloopTitleText,
setLoopDisplayValue,
Number(schleifenwiderstand), // <- Stelle sicher, dass es eine Zahl ist
tdrLocation,
slotIndex,
dispatch
)
}
className={`w-[50%] h-[1.563rem] text-white text-[0.625rem] flex items-center justify-center ${
activeButton === "Schleife"
? "bg-littwin-blue"
: "bg-gray-400"
}`}
>
Schleife
</button>
<button
onClick={() =>
handleButtonClick(
"TDR",
setActiveButton,
setloopTitleText,
setLoopDisplayValue,
Number(schleifenwiderstand), // <- Stelle sicher, dass es eine Zahl ist
tdrLocation,
slotIndex,
dispatch
)
}
className={`w-[50%] h-[1.563rem] text-white text-[0.625rem] flex items-center justify-center ${
Array.isArray(tdrActive) && tdrActive[slotIndex] === 0
? "bg-gray-200 cursor-not-allowed" // Deaktiviert: Hellgrau
: activeButton === "TDR"
? "bg-littwin-blue" // Aktiviert: Littwin Blau
: "bg-gray-400" // Nicht geklickt: Dunkelgrau
}`}
disabled={
Array.isArray(tdrActive) && tdrActive[slotIndex] === 0
} // Button deaktiviert, wenn TDR für diesen Slot nicht aktiv ist
>
TDR
</button>
</div>
<button
onClick={handleOpenChartModal} // Öffnet das Chart-Modal
className="w-full h-[1.563rem] bg-littwin-blue text-white text-[0.625rem] flex items-center justify-center mt-[0.063rem]"
>
Messkurve
</button>
</div>
{/* Modal für Messkurve */}
{showChartModal && (
<ChartSwitcher
isOpen={showChartModal}
onClose={handleCloseChartModal}
/>
)}
</>
) : (
<div className="flex items-center justify-center h-full text-gray-500">
<p>Kein Modul im Slot {slotIndex + 1}</p>
</div>
)}
</div>
);
};
export default Kue705FO;