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

204 lines
7.1 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?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.");
}
};
// 📥 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>
)}
{/* 🔽 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-72">
<Listbox.Button className="w-full border px-2 py-1 rounded text-left bg-white flex justify-between items-center text-sm">
<span>
{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 ${
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;