Ladebalken in Schleifenmessung
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
"use client"; // components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartActionBar.tsx
|
"use client";
|
||||||
import React, { useEffect, useMemo } from "react";
|
import React from "react";
|
||||||
import DateRangePicker from "./DateRangePicker";
|
import DateRangePicker from "./DateRangePicker";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { RootState } from "../../../../../../redux/store";
|
import { RootState } from "../../../../../../redux/store";
|
||||||
@@ -10,6 +10,8 @@ import {
|
|||||||
setSelectedMode,
|
setSelectedMode,
|
||||||
setSelectedSlotType,
|
setSelectedSlotType,
|
||||||
setChartOpen,
|
setChartOpen,
|
||||||
|
setFullScreen,
|
||||||
|
setLoading,
|
||||||
} from "../../../../../../redux/slices/kabelueberwachungChartSlice";
|
} from "../../../../../../redux/slices/kabelueberwachungChartSlice";
|
||||||
import { setBrushRange } from "../../../../../../redux/slices/brushSlice";
|
import { setBrushRange } from "../../../../../../redux/slices/brushSlice";
|
||||||
import { setChartTitle } from "../../../../../../redux/slices/loopChartTypeSlice";
|
import { setChartTitle } from "../../../../../../redux/slices/loopChartTypeSlice";
|
||||||
@@ -17,7 +19,6 @@ import { setChartTitle } from "../../../../../../redux/slices/loopChartTypeSlice
|
|||||||
const LoopChartActionBar: React.FC = () => {
|
const LoopChartActionBar: React.FC = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
// Redux-Status abrufen
|
|
||||||
const {
|
const {
|
||||||
vonDatum,
|
vonDatum,
|
||||||
bisDatum,
|
bisDatum,
|
||||||
@@ -26,21 +27,14 @@ const LoopChartActionBar: React.FC = () => {
|
|||||||
isChartOpen,
|
isChartOpen,
|
||||||
slotNumber,
|
slotNumber,
|
||||||
loopMeasurementCurveChartData,
|
loopMeasurementCurveChartData,
|
||||||
|
isLoading,
|
||||||
} = useSelector((state: RootState) => state.kabelueberwachungChartSlice);
|
} = useSelector((state: RootState) => state.kabelueberwachungChartSlice);
|
||||||
|
|
||||||
/**
|
|
||||||
* API-URL-Erstellung für Entwicklung und Produktion
|
|
||||||
*/
|
|
||||||
const getApiUrl = (
|
const getApiUrl = (
|
||||||
mode: "DIA0" | "DIA1" | "DIA2",
|
mode: "DIA0" | "DIA1" | "DIA2",
|
||||||
type: number,
|
type: number,
|
||||||
slotNumber: number
|
slotNumber: number
|
||||||
) => {
|
) => {
|
||||||
if (!slotNumber) {
|
|
||||||
console.error("⚠️ Slot-Nummer nicht gesetzt!");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const typeFolder =
|
const typeFolder =
|
||||||
type === 3 ? "isolationswiderstand" : "schleifenwiderstand";
|
type === 3 ? "isolationswiderstand" : "schleifenwiderstand";
|
||||||
|
|
||||||
@@ -54,27 +48,31 @@ const LoopChartActionBar: React.FC = () => {
|
|||||||
return baseUrl;
|
return baseUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Funktion zur Umformatierung des Datums von "YYYY-MM-DD" zu "YYYY;MM;DD"
|
|
||||||
const formatDate = (dateString: string) => {
|
const formatDate = (dateString: string) => {
|
||||||
const dateParts = dateString.split("-");
|
const [year, month, day] = dateString.split("-");
|
||||||
return `${dateParts[0]};${dateParts[1]};${dateParts[2]}`;
|
return `${year};${month};${day}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Funktion zum Laden der Messwerte
|
|
||||||
*/
|
|
||||||
const handleFetchData = async () => {
|
const handleFetchData = async () => {
|
||||||
const type = selectedSlotType === "schleifenwiderstand" ? 4 : 3;
|
const type = selectedSlotType === "schleifenwiderstand" ? 4 : 3;
|
||||||
|
|
||||||
if (slotNumber === null) {
|
if (slotNumber === null) {
|
||||||
console.error("⚠️ Slot-Nummer nicht gesetzt!");
|
alert("⚠️ Bitte zuerst einen Slot auswählen!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const apiUrl = getApiUrl(selectedMode, type, slotNumber); // ✅ slotNumber ergänzt
|
|
||||||
|
|
||||||
|
const apiUrl = getApiUrl(selectedMode, type, slotNumber);
|
||||||
if (!apiUrl) return;
|
if (!apiUrl) return;
|
||||||
|
|
||||||
|
dispatch(setLoading(true));
|
||||||
|
dispatch(setChartOpen(false));
|
||||||
|
dispatch(setLoopMeasurementCurveChartData([]));
|
||||||
|
dispatch(setFullScreen(false));
|
||||||
|
|
||||||
|
const MIN_LOADING_TIME_MS = 1000;
|
||||||
|
const startTime = Date.now();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// console.log("📡 API-Request an:", apiUrl);
|
|
||||||
const response = await fetch(apiUrl, {
|
const response = await fetch(apiUrl, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
@@ -83,53 +81,28 @@ const LoopChartActionBar: React.FC = () => {
|
|||||||
if (!response.ok) throw new Error(`Fehler: ${response.status}`);
|
if (!response.ok) throw new Error(`Fehler: ${response.status}`);
|
||||||
|
|
||||||
const jsonData = await response.json();
|
const jsonData = await response.json();
|
||||||
console.log("✅ API URL ", apiUrl);
|
const elapsedTime = Date.now() - startTime;
|
||||||
console.log("✅ Daten erfolgreich geladen:", jsonData);
|
const waitTime = Math.max(0, MIN_LOADING_TIME_MS - elapsedTime);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
||||||
|
|
||||||
if (Array.isArray(jsonData)) {
|
if (Array.isArray(jsonData) && jsonData.length > 0) {
|
||||||
dispatch(setLoopMeasurementCurveChartData([...jsonData]));
|
dispatch(setLoopMeasurementCurveChartData(jsonData));
|
||||||
|
dispatch(setChartOpen(true));
|
||||||
// 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 {
|
} else {
|
||||||
console.error("⚠️ Erwartetes Array, aber erhalten:", jsonData);
|
alert("⚠️ Keine Messdaten im gewählten Zeitraum gefunden.");
|
||||||
|
dispatch(setLoopMeasurementCurveChartData([]));
|
||||||
|
dispatch(setChartOpen(false));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
console.error("❌ Fehler beim Laden der Daten:", error);
|
console.error("❌ Fehler beim Laden der Daten:", err);
|
||||||
|
alert("❌ Fehler beim Laden der Daten.");
|
||||||
|
} finally {
|
||||||
|
dispatch(setLoading(false));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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 (
|
return (
|
||||||
<div className="flex justify-between items-center p-2 bg-gray-100 rounded-lg space-x-2">
|
<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">
|
<div className="flex items-center">
|
||||||
<label className="text-sm font-semibold">
|
<label className="text-sm font-semibold">
|
||||||
Slot {slotNumber ?? "-"}
|
Slot {slotNumber ?? "-"}
|
||||||
@@ -145,7 +118,7 @@ const LoopChartActionBar: React.FC = () => {
|
|||||||
dispatch(
|
dispatch(
|
||||||
setSelectedMode(e.target.value as "DIA0" | "DIA1" | "DIA2")
|
setSelectedMode(e.target.value as "DIA0" | "DIA1" | "DIA2")
|
||||||
);
|
);
|
||||||
dispatch(setBrushRange({ startIndex: 0, endIndex: 0 })); // Zurücksetzen
|
dispatch(setBrushRange({ startIndex: 0, endIndex: 0 }));
|
||||||
}}
|
}}
|
||||||
className="px-3 py-1 bg-white border rounded text-sm"
|
className="px-3 py-1 bg-white border rounded text-sm"
|
||||||
>
|
>
|
||||||
@@ -174,6 +147,20 @@ const LoopChartActionBar: React.FC = () => {
|
|||||||
<option value="schleifenwiderstand">Schleifenwiderstand</option>
|
<option value="schleifenwiderstand">Schleifenwiderstand</option>
|
||||||
<option value="isolationswiderstand">Isolationswiderstand</option>
|
<option value="isolationswiderstand">Isolationswiderstand</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleFetchData}
|
||||||
|
className="px-4 py-1 bg-blue-500 hover:bg-blue-600 text-white rounded text-sm"
|
||||||
|
>
|
||||||
|
Daten laden
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{isLoading && (
|
||||||
|
<div className="flex items-center space-x-2 text-sm text-gray-500">
|
||||||
|
<div className="w-4 h-4 border-2 border-t-2 border-blue-500 rounded-full animate-spin" />
|
||||||
|
<span>Lade Daten...</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,5 +6,5 @@
|
|||||||
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
|
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
const webVersion = "1.6.210";
|
const webVersion = "1.6.211";
|
||||||
export default webVersion;
|
export default webVersion;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ interface KabelueberwachungChartState {
|
|||||||
tdrChartData: TDRData[];
|
tdrChartData: TDRData[];
|
||||||
isFullScreen: boolean;
|
isFullScreen: boolean;
|
||||||
unit: "kOhm" | "MOhm";
|
unit: "kOhm" | "MOhm";
|
||||||
|
isLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamische Initialisierung der Datumswerte
|
// Dynamische Initialisierung der Datumswerte
|
||||||
@@ -29,6 +30,7 @@ thirtyDaysAgo.setDate(today.getDate() - 30);
|
|||||||
|
|
||||||
// Initialer Zustand des Slices
|
// Initialer Zustand des Slices
|
||||||
const initialState: KabelueberwachungChartState = {
|
const initialState: KabelueberwachungChartState = {
|
||||||
|
isLoading: false,
|
||||||
loopMeasurementCurveChartData: [],
|
loopMeasurementCurveChartData: [],
|
||||||
vonDatum: thirtyDaysAgo.toISOString().split("T")[0], // 30 Tage zurück
|
vonDatum: thirtyDaysAgo.toISOString().split("T")[0], // 30 Tage zurück
|
||||||
bisDatum: today.toISOString().split("T")[0], // Heute
|
bisDatum: today.toISOString().split("T")[0], // Heute
|
||||||
@@ -83,6 +85,9 @@ const kabelueberwachungChartSlice = createSlice({
|
|||||||
setFullScreen: (state, action: PayloadAction<boolean>) => {
|
setFullScreen: (state, action: PayloadAction<boolean>) => {
|
||||||
state.isFullScreen = action.payload;
|
state.isFullScreen = action.payload;
|
||||||
},
|
},
|
||||||
|
setLoading: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.isLoading = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -97,6 +102,7 @@ export const {
|
|||||||
setChartOpen,
|
setChartOpen,
|
||||||
setTDRChartData,
|
setTDRChartData,
|
||||||
setFullScreen,
|
setFullScreen,
|
||||||
|
setLoading,
|
||||||
} = kabelueberwachungChartSlice.actions;
|
} = kabelueberwachungChartSlice.actions;
|
||||||
|
|
||||||
// Export des Reducers
|
// Export des Reducers
|
||||||
|
|||||||
Reference in New Issue
Block a user