Files
CPLv4.0/components/main/kabelueberwachung/kue705FO/Charts/TDRChart/TDRChartActionBar.tsx

240 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// /components/main/kabelueberwachung/kue705FO/Charts/TDRChart/TDRChartActionBar.tsx
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { useAppDispatch } from "@/redux/store";
import { RootState } from "@/redux/store";
import { fetchTDMDataBySlotThunk } from "@/redux/thunks/getTDMListBySlotThunk";
import { getTDRChartDataByIdThunk } from "@/redux/thunks/getTDRChartDataByIdThunk";
import { getReferenceCurveBySlotThunk } from "@/redux/thunks/getReferenceCurveBySlotThunk"; // ⬅ import ergänzen
import { Listbox } from "@headlessui/react";
const TDRChartActionBar: React.FC = () => {
const dispatch = useAppDispatch();
// ✅ Redux: selectedSlot aus kueChartMode (0-basiert)
const selectedSlot = useSelector(
(state: RootState) => state.kueChartModeSlice.selectedSlot
);
const tdmChartData = useSelector(
(state: RootState) => state.tdmSingleChartSlice.data
);
const idsForSlot =
selectedSlot !== null ? tdmChartData[selectedSlot] ?? [] : [];
const tdrDataById = useSelector(
(state: RootState) => state.tdrDataByIdSlice.dataById
);
const [selectedId, setSelectedId] = useState<number | null>(null);
const currentChartData = selectedId !== null ? tdrDataById[selectedId] : [];
// 📌 Referenz setzen (nutzt Slotnummer + 1 für die API)
const handleSetReference = async () => {
if (
selectedSlot === null ||
selectedId === null ||
!currentChartData?.length
)
return;
try {
const slotNumber = selectedSlot + 1; // Slot ist 0-basiert, API will 1-basiert
const isDev = process.env.NEXT_PUBLIC_NODE_ENV === "development";
if (isDev) {
await fetch("/api/cpl/updateTdrReferenceCurveAPIHandler", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
slot: slotNumber,
data: currentChartData,
}),
});
} else {
const url = `/CPL?/${window.location.pathname}&KTR${slotNumber}=${selectedId}`;
await fetch(url, { method: "GET" });
}
if (!isDev) {
const url = `/CPL?KTR${slotNumber}=${selectedId}`;
const response = await fetch(url, { method: "GET" });
if (!response.ok) {
throw new Error(
`Fehler beim Setzen der Referenz: ${response.statusText}`
);
}
}
// Optional: lokale Speicherung und Redux-Update
localStorage.setItem(
`ref-curve-slot${selectedSlot}`,
JSON.stringify(currentChartData)
);
dispatch(getReferenceCurveBySlotThunk(selectedSlot));
alert("Referenzkurve wurde erfolgreich gesetzt!");
} catch (error) {
console.error("Fehler beim Setzen der Referenzkurve:", error);
alert("Fehler beim Setzen der Referenzkurve.");
}
};
// 📌 TDR Messung starten
const handleStartTDR = async () => {
if (selectedSlot === null) {
alert("⚠️ Bitte zuerst einen KÜ auswählen!");
return;
}
const cgiUrl = `${window.location.origin}/CPL?/${window.location.pathname}&KTT${selectedSlot}=1`;
try {
console.log("🚀 Starte TDR Messung für Slot:", selectedSlot);
console.log("📡 CGI URL:", cgiUrl);
const response = await fetch(cgiUrl);
if (!response.ok) {
throw new Error(`CGI-Fehler: ${response.status}`);
}
console.log("✅ TDR Messung gestartet für Slot", selectedSlot);
alert(`✅ TDR Messung für Slot ${selectedSlot + 1} gestartet`);
} catch (err) {
console.error("❌ Fehler beim Starten der TDR Messung:", err);
alert("❌ Fehler beim Starten der TDR Messung.");
}
};
// 📥 Beim Slot-Wechsel TDM-Liste + letzte ID laden
useEffect(() => {
if (selectedSlot !== null) {
dispatch(fetchTDMDataBySlotThunk(selectedSlot)).then((action) => {
// action can be a PayloadAction with payload or a rejected action
const payload = (
action as {
payload?: { data?: { id: number; t: string; d: number }[] };
}
).payload;
const slotData = payload?.data;
if ((slotData ?? []).length > 0) {
const lastId = (slotData ?? [])[0].id;
setSelectedId(lastId);
dispatch(getTDRChartDataByIdThunk(lastId));
}
});
}
}, [selectedSlot, dispatch]);
return (
<div className="flex justify-between items-center p-2 bg-gray-100 rounded-lg space-x-4">
{/* 🧩 Slot-Anzeige (1-basiert für Benutzer) */}
<div className="text-sm font-semibold">
{selectedSlot !== null ? `${selectedSlot + 1}` : "Kein KÜ gewählt"}
</div>
{/* ✅ Referenz setzen */}
{selectedId !== null && (
<button
onClick={handleSetReference}
className="border border-littwin-blue text-littwin-blue bg-white rounded px-3 py-1 text-sm hover:bg-gray-200"
>
TDR-Kurve als Referenz speichern
</button>
)}
{/* 🚀 TDR starten */}
<button
onClick={handleStartTDR}
className="px-4 py-1 bg-littwin-blue text-white rounded text-sm whitespace-nowrap "
disabled={selectedSlot === null}
>
Messung aktivieren
</button>
{/* 🔽 Dropdown für Messungen */}
<div className="flex items-center space-x-2">
<Listbox
value={selectedId}
onChange={(id) => {
setSelectedId(id);
if (id !== null) {
dispatch(getTDRChartDataByIdThunk(id));
}
}}
disabled={idsForSlot.length === 0}
>
<div className="relative w-96">
<Listbox.Button className="w-full border px-2 py-1 rounded text-left bg-white flex justify-between items-center text-sm">
<span className="whitespace-nowrap overflow-hidden text-ellipsis">
{selectedId
? (() => {
const selected = idsForSlot.find(
(e) => e.id === selectedId
);
return selected
? `${new Date(selected.t).toLocaleString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
})} Fehlerstelle: ${selected.d} m`
: "Wähle Messung";
})()
: "Wähle Messung"}
</span>
<svg
className="w-5 h-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M5.23 7.21a.75.75 0 011.06.02L10 10.585l3.71-3.355a.75.75 0 111.02 1.1l-4.25 3.85a.75.75 0 01-1.02 0l-4.25-3.85a.75.75 0 01.02-1.06z"
clipRule="evenodd"
/>
</svg>
</Listbox.Button>
<Listbox.Options className="absolute z-50 mt-1 w-full border rounded bg-white shadow max-h-60 overflow-auto text-sm">
{idsForSlot.map((entry) => (
<Listbox.Option
key={entry.id}
value={entry.id}
className={({ selected, active }) =>
`px-4 py-1 cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis ${
selected
? "bg-littwin-blue text-white"
: active
? "bg-gray-200"
: ""
}`
}
>
{new Date(entry.t).toLocaleString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
})}{" "}
Fehlerstelle: {entry.d} m
</Listbox.Option>
))}
</Listbox.Options>
</div>
</Listbox>
</div>
</div>
);
};
export default TDRChartActionBar;