Files
CPLv4.0/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartActionBar.tsx
Ismail Ali e0379c24a6 feat(ui): Slot-Nummer nach links verschoben und Datumsauswahl horizontal ausgerichtet
- Slot-Nr.-Anzeige nach links im ActionBar verschoben.
- Datum-Labels („Von“ & „Bis“) und Eingabefelder horizontal ausgerichtet.
- Verbesserte UI/UX der Chart-Steuerungskomponenten.
2025-03-14 21:30:21 +01:00

192 lines
5.9 KiB
TypeScript

"use client"; // components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartActionBar.tsx
import React, { useEffect, useMemo } from "react";
import DateRangePicker from "../DateRangePicker";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../../../../../redux/store";
import {
setVonDatum,
setBisDatum,
setLoopMeasurementCurveChartData,
setSelectedMode,
setSelectedSlotType,
setChartOpen,
} from "../../../../../../redux/slices/kabelueberwachungChartSlice";
const LoopChartActionBar: React.FC = () => {
const dispatch = useDispatch();
// Redux-Status abrufen
const {
vonDatum,
bisDatum,
selectedMode,
selectedSlotType,
isChartOpen,
slotNumber,
loopMeasurementCurveChartData,
} = useSelector((state: RootState) => state.kabelueberwachungChart);
/**
* API-URL-Erstellung für Entwicklung und Produktion
*/
const getApiUrl = (
mode: "DIA0" | "DIA1" | "DIA2",
type: number,
slotNumber: number
) => {
if (!slotNumber) {
console.error("⚠️ Slot-Nummer nicht gesetzt!");
return "";
}
const typeFolder =
type === 3 ? "isolationswiderstand" : "schleifenwiderstand";
const baseUrl =
process.env.NODE_ENV === "development"
? `/CPLmockData/kuesChartData/slot${slotNumber}/${typeFolder}/${mode}.json`
: `${window.location.origin}/CPL?seite.ACP&${mode}=${formatDate(
vonDatum
)};${formatDate(bisDatum)};${slotNumber};${type};`;
return baseUrl;
};
// Funktion zur Umformatierung des Datums von "YYYY-MM-DD" zu "YYYY;MM;DD"
const formatDate = (dateString: string) => {
const dateParts = dateString.split("-");
return `${dateParts[0]};${dateParts[1]};${dateParts[2]}`;
};
/**
* Funktion zum Laden der Messwerte
*/
const handleFetchData = async () => {
const type = selectedSlotType === "schleifenwiderstand" ? 4 : 3;
if (slotNumber === null) {
console.error("⚠️ Slot-Nummer nicht gesetzt!");
return;
}
const apiUrl = getApiUrl(selectedMode, type, slotNumber); // ✅ slotNumber ergänzt
if (!apiUrl) return;
try {
console.log("📡 API-Request an:", apiUrl);
const response = await fetch(apiUrl, {
method: "GET",
headers: { "Content-Type": "application/json" },
});
if (!response.ok) throw new Error(`Fehler: ${response.status}`);
const jsonData = await response.json();
console.log("✅ Daten erfolgreich geladen:", jsonData);
if (Array.isArray(jsonData)) {
dispatch(setLoopMeasurementCurveChartData([...jsonData]));
// Falls das Chart zum ersten Mal geöffnet wird, setze vonDatum & bisDatum
if (!isChartOpen && jsonData.length > 0) {
const firstDate = new Date(jsonData[jsonData.length - 1].t);
const lastDate = new Date(jsonData[0].t);
dispatch(setVonDatum(firstDate.toISOString().split("T")[0]));
dispatch(setBisDatum(lastDate.toISOString().split("T")[0]));
dispatch(setChartOpen(true));
}
} else {
console.error("⚠️ Erwartetes Array, aber erhalten:", jsonData);
}
} catch (error) {
console.error("❌ Fehler beim Laden der Daten:", error);
}
};
const minDate = useMemo(() => {
if (!loopMeasurementCurveChartData?.length) return "";
return new Date(
loopMeasurementCurveChartData[loopMeasurementCurveChartData.length - 1].t
)
.toISOString()
.split("T")[0];
}, [loopMeasurementCurveChartData]);
const maxDate = useMemo(() => {
if (!loopMeasurementCurveChartData?.length) return "";
return new Date(loopMeasurementCurveChartData[0].t)
.toISOString()
.split("T")[0];
}, [loopMeasurementCurveChartData]);
// Automatische Datenaktualisierung bei Auswahländerung
useEffect(() => {
handleFetchData();
// Wenn sich slotNumber, Zeitraum oder Auswahl ändert, neu laden:
}, [selectedMode, selectedSlotType, slotNumber, vonDatum, bisDatum]);
return (
<div className="flex justify-between items-center p-2 bg-gray-100 rounded-lg space-x-2">
{/* Slot Nummer links positioniert */}
<div className="flex items-center">
<label className="text-sm font-semibold">
Slot-Nr.: {slotNumber ?? "-"}
</label>
</div>
<div className="flex items-center space-x-2">
<DateRangePicker
setVonDatum={(date) => {
const isoDate = date.toISOString().split("T")[0];
if (isoDate < minDate || isoDate > maxDate) return;
dispatch(setVonDatum(isoDate));
if (isoDate > bisDatum) dispatch(setBisDatum(isoDate));
}}
setBisDatum={(date) => {
const isoDate = date.toISOString().split("T")[0];
if (isoDate < minDate || isoDate > maxDate) return;
if (isoDate >= vonDatum) dispatch(setBisDatum(isoDate));
}}
minDate={minDate}
maxDate={maxDate}
/>
<select
value={selectedMode}
onChange={(e) =>
dispatch(
setSelectedMode(e.target.value as "DIA0" | "DIA1" | "DIA2")
)
}
className="px-3 py-1 bg-white border rounded text-sm"
>
<option value="DIA0">Alle Messwerte</option>
<option value="DIA1">Stündliche Werte</option>
<option value="DIA2">Tägliche Werte</option>
</select>
<select
value={selectedSlotType}
onChange={(e) =>
dispatch(
setSelectedSlotType(
e.target.value as "isolationswiderstand" | "schleifenwiderstand"
)
)
}
className="px-3 py-1 bg-white border rounded text-sm"
>
<option value="schleifenwiderstand">Schleifenwiderstand</option>
<option value="isolationswiderstand">Isolationswiderstand</option>
</select>
</div>
</div>
);
};
export default LoopChartActionBar;