fix: KÜ slotnummer in der Messkurven Modal
This commit is contained in:
@@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
|
|||||||
NEXT_PUBLIC_EXPORT_STATIC=false
|
NEXT_PUBLIC_EXPORT_STATIC=false
|
||||||
NEXT_PUBLIC_USE_CGI=false
|
NEXT_PUBLIC_USE_CGI=false
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.6.651
|
NEXT_PUBLIC_APP_VERSION=1.6.652
|
||||||
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)
|
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)
|
||||||
|
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL
|
|||||||
NEXT_PUBLIC_EXPORT_STATIC=true
|
NEXT_PUBLIC_EXPORT_STATIC=true
|
||||||
NEXT_PUBLIC_USE_CGI=true
|
NEXT_PUBLIC_USE_CGI=true
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.6.651
|
NEXT_PUBLIC_APP_VERSION=1.6.652
|
||||||
NEXT_PUBLIC_CPL_MODE=production
|
NEXT_PUBLIC_CPL_MODE=production
|
||||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,3 +1,13 @@
|
|||||||
|
## [1.6.652] – 2025-07-28
|
||||||
|
|
||||||
|
- fix(Kue705FO): maintain consistent 3-line display layout
|
||||||
|
|
||||||
|
- Keep alarm status line with empty space when no alarm is present
|
||||||
|
- Use non-breaking space (\u00A0) to preserve line height and layout
|
||||||
|
- Remove green "Status: OK" text for cleaner display
|
||||||
|
- Ensure consistent 3-line structure: Alarm/Empty, ISO, RSL
|
||||||
|
|
||||||
|
---
|
||||||
## [1.6.651] – 2025-07-25
|
## [1.6.651] – 2025-07-25
|
||||||
|
|
||||||
- refactor(Kue705FO): integrate chart functionality into detail view buttons
|
- refactor(Kue705FO): integrate chart functionality into detail view buttons
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import React, { useEffect } from "react";
|
|||||||
import ReactModal from "react-modal";
|
import ReactModal from "react-modal";
|
||||||
import LoopChartActionBar from "./LoopMeasurementChart/LoopChartActionBar";
|
import LoopChartActionBar from "./LoopMeasurementChart/LoopChartActionBar";
|
||||||
import LoopMeasurementChart from "./LoopMeasurementChart/LoopMeasurementChart";
|
import LoopMeasurementChart from "./LoopMeasurementChart/LoopMeasurementChart";
|
||||||
|
import IsoMeasurementChart from "./IsoMeasurementChart/IsoMeasurementChart";
|
||||||
import TDRChart from "./TDRChart/TDRChart";
|
import TDRChart from "./TDRChart/TDRChart";
|
||||||
import { useSelector, useDispatch } from "react-redux";
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
import { AppDispatch } from "@/redux/store";
|
import { AppDispatch } from "@/redux/store";
|
||||||
@@ -86,9 +87,9 @@ const ChartSwitcher: React.FC<ChartSwitcherProps> = ({ isOpen, onClose }) => {
|
|||||||
(state: RootState) => state.kabelueberwachungChartSlice.slotNumber
|
(state: RootState) => state.kabelueberwachungChartSlice.slotNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
// immer beim Öffnen das Modal die letzten 30 Tage anzeigen
|
// immer beim Öffnen das Modal die letzten 30 Tage anzeigen und SlotType setzen
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen && activeMode === "Schleife" && slotNumber !== null) {
|
if (isOpen) {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const thirtyDaysAgo = new Date();
|
const thirtyDaysAgo = new Date();
|
||||||
thirtyDaysAgo.setDate(today.getDate() - 30);
|
thirtyDaysAgo.setDate(today.getDate() - 30);
|
||||||
@@ -98,10 +99,20 @@ const ChartSwitcher: React.FC<ChartSwitcherProps> = ({ isOpen, onClose }) => {
|
|||||||
dispatch(setVonDatum(toISO(thirtyDaysAgo)));
|
dispatch(setVonDatum(toISO(thirtyDaysAgo)));
|
||||||
dispatch(setBisDatum(toISO(today)));
|
dispatch(setBisDatum(toISO(today)));
|
||||||
|
|
||||||
// Warten, bis Redux gesetzt ist → dann Daten laden
|
// Set SlotType based on activeMode
|
||||||
setTimeout(() => {
|
if (activeMode === "ISO") {
|
||||||
loadLoopChartData.loadLoopChartData();
|
dispatch(setSelectedSlotType("isolationswiderstand"));
|
||||||
}, 10); // kleiner Delay, damit Redux-State sicher aktualisiert ist
|
} else if (activeMode === "Schleife") {
|
||||||
|
dispatch(setSelectedSlotType("schleifenwiderstand"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load data for Schleife mode
|
||||||
|
if (activeMode === "Schleife" && slotNumber !== null) {
|
||||||
|
// Warten, bis Redux gesetzt ist → dann Daten laden
|
||||||
|
setTimeout(() => {
|
||||||
|
loadLoopChartData.loadLoopChartData();
|
||||||
|
}, 10); // kleiner Delay, damit Redux-State sicher aktualisiert ist
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//ESLint ignore
|
//ESLint ignore
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
@@ -187,6 +198,14 @@ const ChartSwitcher: React.FC<ChartSwitcherProps> = ({ isOpen, onClose }) => {
|
|||||||
<LoopMeasurementChart />
|
<LoopMeasurementChart />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
) : activeMode === "ISO" ? (
|
||||||
|
<>
|
||||||
|
<h3 className="text-lg font-semibold">Isolationswiderstand</h3>
|
||||||
|
<LoopChartActionBar />
|
||||||
|
<div style={{ flex: 1, height: "90%" }}>
|
||||||
|
<IsoMeasurementChart />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<h3 className="text-lg font-semibold">TDR-Messung</h3>
|
<h3 className="text-lg font-semibold">TDR-Messung</h3>
|
||||||
|
|||||||
@@ -0,0 +1,340 @@
|
|||||||
|
"use client";
|
||||||
|
// /components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartActionBar.tsx
|
||||||
|
import React from "react";
|
||||||
|
import DateRangePicker from "@/components/common/DateRangePicker";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { RootState } from "@/redux/store";
|
||||||
|
import {
|
||||||
|
setLoopMeasurementCurveChartData,
|
||||||
|
setSelectedMode,
|
||||||
|
setSelectedSlotType,
|
||||||
|
setChartOpen,
|
||||||
|
setLoading,
|
||||||
|
} from "@/redux/slices/kabelueberwachungChartSlice";
|
||||||
|
import { setBrushRange } from "@/redux/slices/brushSlice";
|
||||||
|
import { setChartTitle } from "@/redux/slices/loopChartTypeSlice";
|
||||||
|
import { Listbox } from "@headlessui/react";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------useLoopChartLoader
|
||||||
|
export const useLoopChartLoader = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { vonDatum, bisDatum, selectedMode, selectedSlotType, slotNumber } =
|
||||||
|
useSelector((state: RootState) => state.kabelueberwachungChartSlice);
|
||||||
|
const hasShownNoDataAlert = React.useRef(false);
|
||||||
|
|
||||||
|
const formatDate = (dateString: string) => {
|
||||||
|
const [year, month, day] = dateString.split("-");
|
||||||
|
return `${year};${month};${day}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getApiUrl = (
|
||||||
|
mode: "DIA0" | "DIA1" | "DIA2",
|
||||||
|
type: number,
|
||||||
|
slotNumber: number
|
||||||
|
) => {
|
||||||
|
const typeFolder =
|
||||||
|
type === 3 ? "isolationswiderstand" : "schleifenwiderstand";
|
||||||
|
|
||||||
|
let url: string;
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
url = `/api/cpl/slotDataAPIHandler?slot=${slotNumber}&messart=${typeFolder}&dia=${mode}&vonDatum=${vonDatum}&bisDatum=${bisDatum}`;
|
||||||
|
} else {
|
||||||
|
url = `${window.location.origin}/CPL?seite.ACP&${mode}=${formatDate(
|
||||||
|
vonDatum
|
||||||
|
)};${formatDate(bisDatum)};${slotNumber};${type};`;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("API URL:", url); // Hier wird die URL in der Konsole ausgegeben
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadLoopChartData = async () => {
|
||||||
|
const type = selectedSlotType === "schleifenwiderstand" ? 4 : 3;
|
||||||
|
if (slotNumber === null) return;
|
||||||
|
|
||||||
|
dispatch(setLoading(true));
|
||||||
|
dispatch(setChartOpen(false));
|
||||||
|
dispatch(setLoopMeasurementCurveChartData([]));
|
||||||
|
|
||||||
|
const startTime = Date.now();
|
||||||
|
const MIN_LOADING_TIME_MS = 1000;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const apiUrl = getApiUrl(selectedMode, type, slotNumber);
|
||||||
|
const response = await fetch(apiUrl);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
const waitTime = Math.max(
|
||||||
|
0,
|
||||||
|
MIN_LOADING_TIME_MS - (Date.now() - startTime)
|
||||||
|
);
|
||||||
|
await new Promise((res) => setTimeout(res, waitTime));
|
||||||
|
|
||||||
|
if (Array.isArray(data) && data.length > 0) {
|
||||||
|
dispatch(setLoopMeasurementCurveChartData(data));
|
||||||
|
dispatch(setChartOpen(true));
|
||||||
|
} else {
|
||||||
|
dispatch(setLoopMeasurementCurveChartData([]));
|
||||||
|
dispatch(setChartOpen(false));
|
||||||
|
if (!hasShownNoDataAlert.current) {
|
||||||
|
alert("⚠️ Keine Messdaten im gewählten Zeitraum gefunden");
|
||||||
|
hasShownNoDataAlert.current = true; // ⬅️ Nur einmal zeigen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("❌ Fehler beim Laden:", err);
|
||||||
|
alert("❌ Fehler beim Laden.");
|
||||||
|
} finally {
|
||||||
|
dispatch(setLoading(false));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return { loadLoopChartData };
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------LoopChartActionBar
|
||||||
|
const LoopChartActionBar: React.FC = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const {
|
||||||
|
vonDatum,
|
||||||
|
bisDatum,
|
||||||
|
selectedMode,
|
||||||
|
selectedSlotType,
|
||||||
|
|
||||||
|
slotNumber,
|
||||||
|
|
||||||
|
isLoading,
|
||||||
|
} = useSelector((state: RootState) => state.kabelueberwachungChartSlice);
|
||||||
|
|
||||||
|
const getApiUrl = (
|
||||||
|
mode: "DIA0" | "DIA1" | "DIA2",
|
||||||
|
type: number,
|
||||||
|
slotNumber: number
|
||||||
|
) => {
|
||||||
|
const typeFolder =
|
||||||
|
type === 3 ? "isolationswiderstand" : "schleifenwiderstand";
|
||||||
|
|
||||||
|
const baseUrl =
|
||||||
|
process.env.NODE_ENV === "development"
|
||||||
|
? `/api/cpl/slotDataAPIHandler?slot=${slotNumber}&messart=${typeFolder}&dia=${mode}&vonDatum=${vonDatum}&bisDatum=${bisDatum}`
|
||||||
|
: `${window.location.origin}/CPL?seite.ACP&${mode}=${formatDate(
|
||||||
|
vonDatum
|
||||||
|
)};${formatDate(bisDatum)};${slotNumber};${type};`;
|
||||||
|
console.log("baseUrl", baseUrl);
|
||||||
|
|
||||||
|
return baseUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatDate = (dateString: string) => {
|
||||||
|
const [year, month, day] = dateString.split("-");
|
||||||
|
return `${year};${month};${day}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFetchData = async () => {
|
||||||
|
const type = selectedSlotType === "schleifenwiderstand" ? 4 : 3;
|
||||||
|
|
||||||
|
if (slotNumber === null) {
|
||||||
|
alert("⚠️ Bitte zuerst einen KÜ auswählen!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiUrl = getApiUrl(selectedMode, type, slotNumber);
|
||||||
|
if (!apiUrl) return;
|
||||||
|
|
||||||
|
dispatch(setLoading(true));
|
||||||
|
dispatch(setChartOpen(false));
|
||||||
|
dispatch(setLoopMeasurementCurveChartData([]));
|
||||||
|
|
||||||
|
const MIN_LOADING_TIME_MS = 1000;
|
||||||
|
const startTime = Date.now();
|
||||||
|
|
||||||
|
try {
|
||||||
|
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();
|
||||||
|
const elapsedTime = Date.now() - startTime;
|
||||||
|
const waitTime = Math.max(0, MIN_LOADING_TIME_MS - elapsedTime);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
||||||
|
//------------------------
|
||||||
|
console.log("▶️ Lade Daten für:");
|
||||||
|
console.log(" Slot:", slotNumber);
|
||||||
|
console.log(" Typ:", selectedSlotType, "→", type);
|
||||||
|
console.log(" Modus:", selectedMode);
|
||||||
|
console.log(" Von:", vonDatum);
|
||||||
|
console.log(" Bis:", bisDatum);
|
||||||
|
console.log(" URL:", apiUrl);
|
||||||
|
console.log(" Daten:", jsonData);
|
||||||
|
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
if (Array.isArray(jsonData) && jsonData.length > 0) {
|
||||||
|
dispatch(setLoopMeasurementCurveChartData(jsonData));
|
||||||
|
dispatch(setChartOpen(true));
|
||||||
|
} else {
|
||||||
|
alert("⚠️ Keine Messdaten im gewählten Zeitraum gefunden.");
|
||||||
|
dispatch(setLoopMeasurementCurveChartData([]));
|
||||||
|
dispatch(setChartOpen(false));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("❌ Fehler beim Laden der Daten:", err);
|
||||||
|
alert("❌ Fehler beim Laden der Daten.");
|
||||||
|
} finally {
|
||||||
|
dispatch(setLoading(false));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex justify-between items-center p-2 bg-gray-100 rounded-lg space-x-2">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<label className="text-sm font-semibold">KÜ {slotNumber ?? "-"}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<DateRangePicker />
|
||||||
|
|
||||||
|
<Listbox
|
||||||
|
value={selectedMode}
|
||||||
|
onChange={(value) => {
|
||||||
|
dispatch(setSelectedMode(value));
|
||||||
|
dispatch(setBrushRange({ startIndex: 0, endIndex: 0 }));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="relative w-48">
|
||||||
|
<Listbox.Button className="w-full border px-3 py-1 rounded text-left bg-white flex justify-between items-center text-sm">
|
||||||
|
<span>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
DIA0: "Alle Messwerte",
|
||||||
|
DIA1: "Stündliche Werte",
|
||||||
|
DIA2: "Tägliche Werte",
|
||||||
|
}[selectedMode]
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
<svg
|
||||||
|
className="w-5 h-5 text-gray-400"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
<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">
|
||||||
|
{["DIA0", "DIA1", "DIA2"].map((mode) => (
|
||||||
|
<Listbox.Option
|
||||||
|
key={mode}
|
||||||
|
value={mode}
|
||||||
|
className={({ selected, active }) =>
|
||||||
|
`px-4 py-1 cursor-pointer ${
|
||||||
|
selected
|
||||||
|
? "bg-littwin-blue text-white"
|
||||||
|
: active
|
||||||
|
? "bg-gray-200"
|
||||||
|
: ""
|
||||||
|
}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
DIA0: "Alle Messwerte",
|
||||||
|
DIA1: "Stündliche Werte",
|
||||||
|
DIA2: "Tägliche Werte",
|
||||||
|
}[mode]
|
||||||
|
}
|
||||||
|
</Listbox.Option>
|
||||||
|
))}
|
||||||
|
</Listbox.Options>
|
||||||
|
</div>
|
||||||
|
</Listbox>
|
||||||
|
|
||||||
|
<Listbox
|
||||||
|
value={selectedSlotType}
|
||||||
|
onChange={(value) => {
|
||||||
|
dispatch(setSelectedSlotType(value));
|
||||||
|
dispatch(
|
||||||
|
setChartTitle(
|
||||||
|
value === "isolationswiderstand"
|
||||||
|
? "Isolationsmessung"
|
||||||
|
: "Schleifenmessung"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="relative w-56">
|
||||||
|
<Listbox.Button className="w-full border px-3 py-1 rounded text-left bg-white flex justify-between items-center text-sm">
|
||||||
|
<span>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
isolationswiderstand: "Isolationswiderstand",
|
||||||
|
schleifenwiderstand: "Schleifenwiderstand",
|
||||||
|
}[selectedSlotType]
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
<svg
|
||||||
|
className="w-5 h-5 text-gray-400"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
<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">
|
||||||
|
{["isolationswiderstand", "schleifenwiderstand"].map((type) => (
|
||||||
|
<Listbox.Option
|
||||||
|
key={type}
|
||||||
|
value={type}
|
||||||
|
className={({ selected, active }) =>
|
||||||
|
`px-4 py-1 cursor-pointer ${
|
||||||
|
selected
|
||||||
|
? "bg-littwin-blue text-white"
|
||||||
|
: active
|
||||||
|
? "bg-gray-200"
|
||||||
|
: ""
|
||||||
|
}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
isolationswiderstand: "Isolationswiderstand",
|
||||||
|
schleifenwiderstand: "Schleifenwiderstand",
|
||||||
|
}[type]
|
||||||
|
}
|
||||||
|
</Listbox.Option>
|
||||||
|
))}
|
||||||
|
</Listbox.Options>
|
||||||
|
</div>
|
||||||
|
</Listbox>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleFetchData}
|
||||||
|
className="px-4 py-1 bg-littwin-blue 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>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoopChartActionBar;
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
"use client"; // /components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopMeasurementChart.tsx
|
||||||
|
|
||||||
|
import React, { useEffect, useRef } from "react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { RootState } from "@/redux/store";
|
||||||
|
import {
|
||||||
|
Chart as ChartJS,
|
||||||
|
LineController,
|
||||||
|
LineElement,
|
||||||
|
PointElement,
|
||||||
|
LinearScale,
|
||||||
|
TimeScale,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
Filler,
|
||||||
|
} from "chart.js";
|
||||||
|
|
||||||
|
import "chartjs-adapter-date-fns";
|
||||||
|
import { de } from "date-fns/locale";
|
||||||
|
import { differenceInHours, parseISO } from "date-fns";
|
||||||
|
|
||||||
|
ChartJS.register(
|
||||||
|
LineController,
|
||||||
|
LineElement,
|
||||||
|
PointElement,
|
||||||
|
LinearScale,
|
||||||
|
TimeScale,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
Filler
|
||||||
|
);
|
||||||
|
import { getColor } from "@/utils/colors";
|
||||||
|
import { PulseLoader } from "react-spinners";
|
||||||
|
|
||||||
|
type LoopMeasurementEntry = {
|
||||||
|
t: string;
|
||||||
|
i: number;
|
||||||
|
m: number;
|
||||||
|
g: number;
|
||||||
|
a: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const usePreviousData = (data: LoopMeasurementEntry[]) => {
|
||||||
|
const ref = useRef<LoopMeasurementEntry[]>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
ref.current = data;
|
||||||
|
}, [data]);
|
||||||
|
return ref.current;
|
||||||
|
};
|
||||||
|
|
||||||
|
const LoopMeasurementChart = () => {
|
||||||
|
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||||
|
const chartInstance = useRef<ChartJS | null>(null);
|
||||||
|
|
||||||
|
const {
|
||||||
|
loopMeasurementCurveChartData,
|
||||||
|
selectedMode,
|
||||||
|
unit,
|
||||||
|
isFullScreen,
|
||||||
|
isLoading,
|
||||||
|
vonDatum,
|
||||||
|
bisDatum,
|
||||||
|
} = useSelector((state: RootState) => state.kabelueberwachungChartSlice);
|
||||||
|
|
||||||
|
const previousData = usePreviousData(loopMeasurementCurveChartData);
|
||||||
|
|
||||||
|
// Vergleichsfunktion
|
||||||
|
const isEqual = (
|
||||||
|
a: LoopMeasurementEntry[],
|
||||||
|
b: LoopMeasurementEntry[]
|
||||||
|
): boolean => {
|
||||||
|
if (a.length !== b.length) return false;
|
||||||
|
for (let i = 0; i < a.length; i++) {
|
||||||
|
if (
|
||||||
|
a[i].t !== b[i].t ||
|
||||||
|
a[i].i !== b[i].i ||
|
||||||
|
a[i].m !== b[i].m ||
|
||||||
|
a[i].g !== b[i].g ||
|
||||||
|
a[i].a !== b[i].a
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ⏱ Zeitspanne in Stunden berechnen
|
||||||
|
const from = vonDatum ? parseISO(vonDatum) : null;
|
||||||
|
const to = bisDatum ? parseISO(bisDatum) : null;
|
||||||
|
const durationInHours = from && to ? differenceInHours(to, from) : 9999;
|
||||||
|
const timeUnit: "hour" | "day" = durationInHours <= 48 ? "hour" : "day";
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
import("chartjs-plugin-zoom").then((zoomPlugin) => {
|
||||||
|
if (!ChartJS.registry.plugins.get("zoom")) {
|
||||||
|
ChartJS.register(zoomPlugin.default);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canvasRef.current) return;
|
||||||
|
const ctx = canvasRef.current.getContext("2d");
|
||||||
|
if (!ctx) return;
|
||||||
|
|
||||||
|
if (isEqual(loopMeasurementCurveChartData, previousData)) {
|
||||||
|
return; // keine echte Datenänderung → nicht neu zeichnen
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chartInstance.current) {
|
||||||
|
chartInstance.current.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartData = {
|
||||||
|
labels: loopMeasurementCurveChartData
|
||||||
|
.map((entry) => new Date(entry.t))
|
||||||
|
.reverse(),
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Messwert Minimum",
|
||||||
|
data: loopMeasurementCurveChartData.map((e) => e.i).reverse(),
|
||||||
|
borderColor: "lightgrey",
|
||||||
|
backgroundColor: "rgba(211,211,211,0.5)",
|
||||||
|
borderWidth: 2,
|
||||||
|
pointRadius: 0,
|
||||||
|
pointHoverRadius: 10,
|
||||||
|
tension: 0.1,
|
||||||
|
order: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Messwert Maximum",
|
||||||
|
data: loopMeasurementCurveChartData.map((e) => e.a).reverse(),
|
||||||
|
borderColor: "lightgrey",
|
||||||
|
backgroundColor: "rgba(211,211,211,0.5)",
|
||||||
|
borderWidth: 2,
|
||||||
|
pointRadius: 0,
|
||||||
|
pointHoverRadius: 10,
|
||||||
|
tension: 0.1,
|
||||||
|
order: 1,
|
||||||
|
},
|
||||||
|
selectedMode === "DIA0"
|
||||||
|
? {
|
||||||
|
label: "Messwert",
|
||||||
|
data: loopMeasurementCurveChartData.map((e) => e.m).reverse(),
|
||||||
|
borderColor: getColor("littwin-blue"),
|
||||||
|
backgroundColor: "rgba(59,130,246,0.5)",
|
||||||
|
borderWidth: 3,
|
||||||
|
pointRadius: 0,
|
||||||
|
pointHoverRadius: 10,
|
||||||
|
tension: 0.1,
|
||||||
|
order: 3,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
label: "Messwert Durchschnitt",
|
||||||
|
data: loopMeasurementCurveChartData.map((e) => e.g).reverse(),
|
||||||
|
borderColor: getColor("littwin-blue"),
|
||||||
|
backgroundColor: "rgba(59,130,246,0.5)",
|
||||||
|
borderWidth: 3,
|
||||||
|
pointRadius: 0,
|
||||||
|
pointHoverRadius: 10,
|
||||||
|
tension: 0.1,
|
||||||
|
order: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: { position: "top" as const },
|
||||||
|
tooltip: {
|
||||||
|
yAlign: "bottom" as const,
|
||||||
|
mode: "index" as const,
|
||||||
|
intersect: false,
|
||||||
|
},
|
||||||
|
zoom: {
|
||||||
|
pan: { enabled: true, mode: "x" as const },
|
||||||
|
zoom: {
|
||||||
|
wheel: { enabled: true },
|
||||||
|
pinch: { enabled: true },
|
||||||
|
mode: "x" as const,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
type: "time" as const,
|
||||||
|
time: {
|
||||||
|
unit: timeUnit,
|
||||||
|
tooltipFormat: "dd.MM.yyyy HH:mm:ss",
|
||||||
|
displayFormats: {
|
||||||
|
hour: "HH:mm",
|
||||||
|
day: "dd.MM.",
|
||||||
|
},
|
||||||
|
locale: de,
|
||||||
|
},
|
||||||
|
title: { display: true, text: "Zeit" },
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
title: { display: true, text: unit },
|
||||||
|
ticks: { precision: 0 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
chartInstance.current = new ChartJS(ctx, {
|
||||||
|
type: "line",
|
||||||
|
data: chartData,
|
||||||
|
options,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [loopMeasurementCurveChartData, selectedMode, vonDatum, bisDatum]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ width: "100%", height: isFullScreen ? "90%" : "400px" }}>
|
||||||
|
{isLoading && (
|
||||||
|
<div className="flex items-center justify-center h-96">
|
||||||
|
<PulseLoader color="#3B82F6" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<canvas
|
||||||
|
ref={canvasRef}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
display: isLoading ? "none" : "block",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoopMeasurementChart;
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
### 🧭 Zoom-Verhalten beim Schleifen-/Isolationsdiagramm
|
||||||
|
|
||||||
|
In dieser Komponente wird das automatische Nachladen der Messwerte temporär deaktiviert, wenn der Benutzer per Maus in das Diagramm zoomt oder pannt. Nach 30 Sekunden ohne Zoom/Pan-Aktion wird die automatische Aktualisierung wieder aktiviert. Dieses Verhalten dient dazu, den Zoom-Zustand nicht durch neue Daten zu verlieren.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 📁 Enthaltene Komponenten
|
||||||
|
|
||||||
|
- `LoopChartActionBar.tsx`
|
||||||
|
→ Auswahlleiste für Slot-Nummer, Zeitraum (über `DateRangePicker`), Messmodus (`DIA0`, `DIA1`, `DIA2`) und Slot-Typ (Schleife/Isolation).
|
||||||
|
→ Ruft alle 10 Sekunden neue Messdaten ab – außer der Zoom-Modus pausiert das.
|
||||||
|
- `LoopMeasurementChart.tsx`
|
||||||
|
→ Das eigentliche Liniendiagramm mit Chart.js + Zoom-Plugin.
|
||||||
|
→ Erkennt Zoom/Pan und setzt `chartUpdatePaused`, bis 30 Sekunden Inaktivität vergangen sind.
|
||||||
|
|
||||||
|
- `DateRangePicker.tsx`
|
||||||
|
→ Zeigt zwei Felder für Von-/Bis-Datum. Nutzt Redux, um globale Zeitfenster zu setzen.
|
||||||
|
|
||||||
|
- `CustomTooltip.tsx`
|
||||||
|
→ Zeigt beim Hover über die Kurve kontextbezogene Werte wie Messwert, Min, Max und Durchschnitt (DIA0/1/2).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🟢 UML-Aktivitätsdiagramm (Zoom → Pause → Timer → Auto-Update)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
Start([Start])
|
||||||
|
ZoomEvent[[Zoom oder Pan erkannt]]
|
||||||
|
SetPause[Setze chartUpdatePaused = true]
|
||||||
|
StartTimer[Starte 30s Timer]
|
||||||
|
Check[Timer abgelaufen?]
|
||||||
|
SetResume[Setze chartUpdatePaused = false]
|
||||||
|
FetchData[[Datenabruf wieder erlaubt]]
|
||||||
|
End([Ende])
|
||||||
|
|
||||||
|
Start --> ZoomEvent --> SetPause --> StartTimer --> Check
|
||||||
|
Check -- Nein --> StartTimer
|
||||||
|
Check -- Ja --> SetResume --> FetchData --> End
|
||||||
|
```
|
||||||
|
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> AktualisierungAktiv
|
||||||
|
|
||||||
|
AktualisierungAktiv --> ZoomPause : Zoom/Pan erkannt
|
||||||
|
ZoomPause --> AktualisierungAktiv : 30 Sekunden Inaktivität
|
||||||
|
|
||||||
|
state AktualisierungAktiv {
|
||||||
|
[*] --> Normalbetrieb
|
||||||
|
}
|
||||||
|
|
||||||
|
state ZoomPause {
|
||||||
|
[*] --> CountdownLäuft
|
||||||
|
}
|
||||||
@@ -193,7 +193,9 @@ const LoopChartActionBar: React.FC = () => {
|
|||||||
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">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<label className="text-sm font-semibold">KÜ {slotNumber ?? "-"}</label>
|
<label className="text-sm font-semibold">
|
||||||
|
KÜ {slotNumber !== null ? slotNumber + 1 : "-"}
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
@@ -256,8 +258,10 @@ const LoopChartActionBar: React.FC = () => {
|
|||||||
</Listbox.Options>
|
</Listbox.Options>
|
||||||
</div>
|
</div>
|
||||||
</Listbox>
|
</Listbox>
|
||||||
|
<div className="relative w-48"> </div>
|
||||||
<Listbox
|
{/* Dropdown */}
|
||||||
|
{/*
|
||||||
|
<Listbox
|
||||||
value={selectedSlotType}
|
value={selectedSlotType}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
dispatch(setSelectedSlotType(value));
|
dispatch(setSelectedSlotType(value));
|
||||||
@@ -318,6 +322,7 @@ const LoopChartActionBar: React.FC = () => {
|
|||||||
</Listbox.Options>
|
</Listbox.Options>
|
||||||
</div>
|
</div>
|
||||||
</Listbox>
|
</Listbox>
|
||||||
|
*/}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={handleFetchData}
|
onClick={handleFetchData}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface CustomTooltipProps {
|
||||||
|
active?: boolean;
|
||||||
|
payload?: Array<{
|
||||||
|
dataKey: string;
|
||||||
|
value: number;
|
||||||
|
name?: string;
|
||||||
|
color?: string;
|
||||||
|
unit?: string;
|
||||||
|
// Add other known properties here as needed
|
||||||
|
}>;
|
||||||
|
label?: string;
|
||||||
|
unit?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomTooltip: React.FC<CustomTooltipProps> = ({
|
||||||
|
active,
|
||||||
|
payload,
|
||||||
|
label,
|
||||||
|
unit,
|
||||||
|
}) => {
|
||||||
|
if (active && payload && payload.length) {
|
||||||
|
const messwertMax = payload.find((p) => p.dataKey === "messwertMaximum");
|
||||||
|
const messwert = payload.find((p) => p.dataKey === "messwert");
|
||||||
|
const messwertMin = payload.find((p) => p.dataKey === "messwertMinimum");
|
||||||
|
const messwertDurchschnitt = payload.find(
|
||||||
|
(p) => p.dataKey === "messwertDurchschnitt"
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
background: "white",
|
||||||
|
padding: "8px",
|
||||||
|
border: "1px solid lightgrey",
|
||||||
|
borderRadius: "5px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<strong>{new Date(label as string).toLocaleString()}</strong>
|
||||||
|
{messwertMax && (
|
||||||
|
<div style={{ color: "grey" }}>
|
||||||
|
Messwert Maximum: {messwertMax.value.toFixed(2)} {unit}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{messwert && (
|
||||||
|
<div style={{ color: "#00AEEF", fontWeight: "bold" }}>
|
||||||
|
Messwert: {messwert.value.toFixed(2)} {unit}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{messwertDurchschnitt && (
|
||||||
|
<div style={{ color: "#00AEEF" }}>
|
||||||
|
Messwert Durchschnitt: {messwertDurchschnitt.value.toFixed(2)}{" "}
|
||||||
|
{unit}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{messwertMin && (
|
||||||
|
<div style={{ color: "grey" }}>
|
||||||
|
Messwert Minimum: {messwertMin.value.toFixed(2)} {unit}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CustomTooltip;
|
||||||
@@ -4,7 +4,11 @@ import { useSelector } from "react-redux";
|
|||||||
import KueModal from "./modals/SettingsModalWrapper";
|
import KueModal from "./modals/SettingsModalWrapper";
|
||||||
import "bootstrap-icons/font/bootstrap-icons.css"; // Import Bootstrap Icons
|
import "bootstrap-icons/font/bootstrap-icons.css"; // Import Bootstrap Icons
|
||||||
import { Kue705FOProps } from "../../../../types/Kue705FOProps";
|
import { Kue705FOProps } from "../../../../types/Kue705FOProps";
|
||||||
|
// Keep ChartSwitcher import
|
||||||
import ChartSwitcher from "./Charts/ChartSwitcher";
|
import ChartSwitcher from "./Charts/ChartSwitcher";
|
||||||
|
// Remove separate chart imports since we use ChartSwitcher
|
||||||
|
// import IsoMeasurementChart from "./Charts/IsoMeasurementChart/IsoMeasurementChart";
|
||||||
|
// import LoopMeasurementChart from "./Charts/LoopMeasurementChart/LoopMeasurementChart";
|
||||||
//-------Redux Toolkit--------
|
//-------Redux Toolkit--------
|
||||||
import { RootState } from "../../../../redux/store";
|
import { RootState } from "../../../../redux/store";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
@@ -19,13 +23,13 @@ import useModulName from "./hooks/useModulName";
|
|||||||
import type { Chart } from "chart.js";
|
import type { Chart } from "chart.js";
|
||||||
|
|
||||||
//--------handlers----------------
|
//--------handlers----------------
|
||||||
import handleButtonClick from "./kue705FO-Funktionen/handleButtonClick";
|
// Keep needed imports
|
||||||
import handleOpenModal from "./handlers/handleOpenModal";
|
import handleOpenModal from "./handlers/handleOpenModal";
|
||||||
import handleCloseModal from "./handlers/handleCloseModal";
|
import handleCloseModal from "./handlers/handleCloseModal";
|
||||||
|
// Restore chart modal handlers
|
||||||
import handleOpenChartModal from "./handlers/handleOpenChartModal";
|
import handleOpenChartModal from "./handlers/handleOpenChartModal";
|
||||||
import handleCloseChartModal from "./handlers/handleCloseChartModal";
|
import handleCloseChartModal from "./handlers/handleCloseChartModal";
|
||||||
import handleRefreshClick from "./handlers/handleRefreshClick";
|
import handleRefreshClick from "./handlers/handleRefreshClick";
|
||||||
import FallSensors from "@/components/main/fall-detection-sensors/FallSensors";
|
|
||||||
|
|
||||||
const Kue705FO: React.FC<Kue705FOProps> = ({
|
const Kue705FO: React.FC<Kue705FOProps> = ({
|
||||||
isolationswert,
|
isolationswert,
|
||||||
@@ -43,7 +47,7 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { kueName } = useSelector((state: RootState) => state.kueDataSlice);
|
const { kueName } = useSelector((state: RootState) => state.kueDataSlice);
|
||||||
|
|
||||||
const [activeButton, setActiveButton] = useState<"Schleife" | "TDR">(
|
const [activeButton, setActiveButton] = useState<"Schleife" | "TDR" | "ISO">(
|
||||||
"Schleife"
|
"Schleife"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -59,7 +63,11 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
// Keep original showChartModal
|
||||||
const [showChartModal, setShowChartModal] = useState(false);
|
const [showChartModal, setShowChartModal] = useState(false);
|
||||||
|
// Remove separate modals since we use ChartSwitcher
|
||||||
|
// const [showIsoModal, setShowIsoModal] = useState(false);
|
||||||
|
// const [showRslModal, setShowRslModal] = useState(false);
|
||||||
// Removed unused loopMeasurementCurveChartData state
|
// Removed unused loopMeasurementCurveChartData state
|
||||||
|
|
||||||
//------- Redux-Variablen abrufen--------------------------------
|
//------- Redux-Variablen abrufen--------------------------------
|
||||||
@@ -98,11 +106,40 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
|||||||
//-------------------------handlers-------------------------
|
//-------------------------handlers-------------------------
|
||||||
const openModal = () => handleOpenModal(setShowModal);
|
const openModal = () => handleOpenModal(setShowModal);
|
||||||
const closeModal = () => handleCloseModal(setShowModal);
|
const closeModal = () => handleCloseModal(setShowModal);
|
||||||
const openChartModal = () =>
|
|
||||||
handleOpenChartModal(setShowChartModal, dispatch, slotIndex, activeButton);
|
// Restore original chart modal handlers but set chart type automatically
|
||||||
|
const openIsoModal = () => {
|
||||||
|
setActiveButton("ISO");
|
||||||
|
// Set Redux state for ISO type
|
||||||
|
dispatch({
|
||||||
|
type: "kabelueberwachungChart/setSelectedSlotType",
|
||||||
|
payload: 1, // 1 = Isolationswiderstand
|
||||||
|
});
|
||||||
|
dispatch({
|
||||||
|
type: "kabelueberwachungChart/setSlotNumber",
|
||||||
|
payload: slotIndex,
|
||||||
|
});
|
||||||
|
// Open chart modal with ISO type
|
||||||
|
handleOpenChartModal(setShowChartModal, dispatch, slotIndex, "ISO");
|
||||||
|
};
|
||||||
|
|
||||||
|
const openRslModal = () => {
|
||||||
|
setActiveButton("Schleife");
|
||||||
|
setloopTitleText("Schleifenwiderstand [kOhm]");
|
||||||
|
setLoopDisplayValue(Number(schleifenwiderstand));
|
||||||
|
dispatch({
|
||||||
|
type: "kabelueberwachungChart/setSelectedSlotType",
|
||||||
|
payload: 2,
|
||||||
|
}); // RSL type
|
||||||
|
dispatch({
|
||||||
|
type: "kabelueberwachungChart/setSlotNumber",
|
||||||
|
payload: slotIndex,
|
||||||
|
});
|
||||||
|
handleOpenChartModal(setShowChartModal, dispatch, slotIndex, "Schleife");
|
||||||
|
};
|
||||||
|
|
||||||
const refreshClick = () =>
|
const refreshClick = () =>
|
||||||
handleRefreshClick(activeButton, slotIndex, setLoading);
|
handleRefreshClick(activeButton, slotIndex, setLoading);
|
||||||
// Create a ref for the chart instance to pass as the second argument
|
|
||||||
const chartInstance = useRef<Chart | null>(null);
|
const chartInstance = useRef<Chart | null>(null);
|
||||||
|
|
||||||
const closeChartModal = () =>
|
const closeChartModal = () =>
|
||||||
@@ -371,33 +408,13 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
|||||||
{/* ISO and RSL Buttons */}
|
{/* ISO and RSL Buttons */}
|
||||||
<div className="flex space-x-2">
|
<div className="flex space-x-2">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={openIsoModal}
|
||||||
setActiveButton("Schleife");
|
|
||||||
setloopTitleText("Schleifenwiderstand [kOhm]");
|
|
||||||
setLoopDisplayValue(Number(schleifenwiderstand));
|
|
||||||
handleOpenChartModal(
|
|
||||||
setShowChartModal,
|
|
||||||
dispatch,
|
|
||||||
slotIndex,
|
|
||||||
"Schleife"
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
className="bg-littwin-blue text-white text-[0.625rem] flex items-center justify-center p-2"
|
className="bg-littwin-blue text-white text-[0.625rem] flex items-center justify-center p-2"
|
||||||
>
|
>
|
||||||
ISO
|
ISO
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={openRslModal}
|
||||||
setActiveButton("Schleife");
|
|
||||||
setloopTitleText("Schleifenwiderstand [kOhm]");
|
|
||||||
setLoopDisplayValue(Number(schleifenwiderstand));
|
|
||||||
handleOpenChartModal(
|
|
||||||
setShowChartModal,
|
|
||||||
dispatch,
|
|
||||||
slotIndex,
|
|
||||||
"Schleife"
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
className="bg-littwin-blue text-white text-[0.625rem] flex items-center justify-center p-2"
|
className="bg-littwin-blue text-white text-[0.625rem] flex items-center justify-center p-2"
|
||||||
>
|
>
|
||||||
RSL
|
RSL
|
||||||
@@ -433,10 +450,7 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
|||||||
>
|
>
|
||||||
TDR
|
TDR
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button className="bg-littwin-blue text-white text-[0.625rem] flex items-center justify-center p-2">
|
||||||
onClick={openChartModal}
|
|
||||||
className="bg-littwin-blue text-white text-[0.625rem] flex items-center justify-center p-2"
|
|
||||||
>
|
|
||||||
KVz
|
KVz
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -447,7 +461,7 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
|||||||
<div className="flex flex-col space-y-2 w-full"></div>
|
<div className="flex flex-col space-y-2 w-full"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Modal für Messkurve */}
|
{/* Original Modal für Messkurve with ChartSwitcher */}
|
||||||
{showChartModal && (
|
{showChartModal && (
|
||||||
<ChartSwitcher
|
<ChartSwitcher
|
||||||
isOpen={showChartModal}
|
isOpen={showChartModal}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const handleOpenChartModal = (
|
|||||||
setShowChartModal: Dispatch<SetStateAction<boolean>>,
|
setShowChartModal: Dispatch<SetStateAction<boolean>>,
|
||||||
dispatch: ReturnType<typeof useDispatch>,
|
dispatch: ReturnType<typeof useDispatch>,
|
||||||
slotIndex: number,
|
slotIndex: number,
|
||||||
activeButton: "Schleife" | "TDR"
|
activeButton: "Schleife" | "TDR" | "ISO"
|
||||||
) => {
|
) => {
|
||||||
setShowChartModal(true);
|
setShowChartModal(true);
|
||||||
dispatch(setChartOpen(true));
|
dispatch(setChartOpen(true));
|
||||||
@@ -26,6 +26,8 @@ const handleOpenChartModal = (
|
|||||||
|
|
||||||
if (activeButton === "TDR") {
|
if (activeButton === "TDR") {
|
||||||
dispatch(setActiveMode("TDR"));
|
dispatch(setActiveMode("TDR"));
|
||||||
|
} else if (activeButton === "ISO") {
|
||||||
|
dispatch(setActiveMode("ISO"));
|
||||||
} else {
|
} else {
|
||||||
dispatch(setActiveMode("Schleife"));
|
dispatch(setActiveMode("Schleife"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { goLoop } from "@/utils/goLoop";
|
|||||||
import { goTDR } from "@/utils/goTDR";
|
import { goTDR } from "@/utils/goTDR";
|
||||||
|
|
||||||
const handleRefreshClick = (
|
const handleRefreshClick = (
|
||||||
activeButton: "Schleife" | "TDR",
|
activeButton: "Schleife" | "TDR" | "ISO",
|
||||||
slotIndex: number,
|
slotIndex: number,
|
||||||
setLoading: Dispatch<SetStateAction<boolean>>
|
setLoading: Dispatch<SetStateAction<boolean>>
|
||||||
) => {
|
) => {
|
||||||
@@ -13,6 +13,7 @@ const handleRefreshClick = (
|
|||||||
} else if (activeButton === "TDR") {
|
} else if (activeButton === "TDR") {
|
||||||
goTDR(slotIndex, setLoading);
|
goTDR(slotIndex, setLoading);
|
||||||
}
|
}
|
||||||
|
// ISO has no refresh functionality
|
||||||
};
|
};
|
||||||
|
|
||||||
export default handleRefreshClick;
|
export default handleRefreshClick;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
|
|||||||
|
|
||||||
const useLoopDisplay = (
|
const useLoopDisplay = (
|
||||||
schleifenwiderstand: number,
|
schleifenwiderstand: number,
|
||||||
activeButton: "Schleife" | "TDR"
|
activeButton: "Schleife" | "TDR" | "ISO"
|
||||||
) => {
|
) => {
|
||||||
const [loopDisplayValue, setLoopDisplayValue] =
|
const [loopDisplayValue, setLoopDisplayValue] =
|
||||||
useState<number>(schleifenwiderstand);
|
useState<number>(schleifenwiderstand);
|
||||||
@@ -12,6 +12,7 @@ const useLoopDisplay = (
|
|||||||
if (activeButton === "Schleife") {
|
if (activeButton === "Schleife") {
|
||||||
setLoopDisplayValue(schleifenwiderstand);
|
setLoopDisplayValue(schleifenwiderstand);
|
||||||
}
|
}
|
||||||
|
// For ISO and TDR, the value is set manually via setLoopDisplayValue
|
||||||
}, [schleifenwiderstand, activeButton]);
|
}, [schleifenwiderstand, activeButton]);
|
||||||
|
|
||||||
return { loopDisplayValue, setLoopDisplayValue };
|
return { loopDisplayValue, setLoopDisplayValue };
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,67 +1,33 @@
|
|||||||
[
|
[
|
||||||
{ "t": "2025-04-24 00:00:00", "i": 39.0, "a": 48.0, "g": 45.984 },
|
{ "t": "2025-07-25 00:00:00", "i": 13.5, "a": 14.0, "g": 13.5 },
|
||||||
{ "t": "2025-04-23 00:00:00", "i": 33.0, "a": 47.5, "g": 45.985 },
|
{ "t": "2025-07-24 00:00:00", "i": 11.5, "a": 14.0, "g": 13.522 },
|
||||||
{ "t": "2025-04-22 00:00:00", "i": 33.0, "a": 49.0, "g": 46.196 },
|
{ "t": "2025-07-23 00:00:00", "i": 13.0, "a": 14.0, "g": 13.5 },
|
||||||
{ "t": "2025-04-21 00:00:00", "i": 39.5, "a": 48.0, "g": 46.147 },
|
{ "t": "2025-07-22 00:00:00", "i": 13.0, "a": 14.0, "g": 13.5 },
|
||||||
{ "t": "2025-04-20 00:00:00", "i": 43.0, "a": 49.0, "g": 46.053 },
|
{ "t": "2025-07-21 00:00:00", "i": 12.0, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-19 00:00:00", "i": 45.0, "a": 47.5, "g": 46.019 },
|
{ "t": "2025-07-20 00:00:00", "i": 13.5, "a": 14.0, "g": 13.5 },
|
||||||
{ "t": "2025-04-18 00:00:00", "i": 39.0, "a": 49.5, "g": 46.097 },
|
{ "t": "2025-07-19 00:00:00", "i": 12.5, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-17 00:00:00", "i": 43.0, "a": 48.0, "g": 45.972 },
|
{ "t": "2025-07-18 00:00:00", "i": 13.0, "a": 13.5, "g": 13.498 },
|
||||||
{ "t": "2025-04-16 00:00:00", "i": 32.5, "a": 49.0, "g": 45.647 },
|
{ "t": "2025-07-17 00:00:00", "i": 13.5, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-15 00:00:00", "i": 45.0, "a": 47.0, "g": 45.71 },
|
{ "t": "2025-07-16 00:00:00", "i": 13.0, "a": 13.5, "g": 13.498 },
|
||||||
{ "t": "2025-04-14 00:00:00", "i": 43.0, "a": 49.0, "g": 45.942 },
|
{ "t": "2025-07-15 00:00:00", "i": 12.5, "a": 14.0, "g": 13.5 },
|
||||||
{ "t": "2025-04-13 00:00:00", "i": 43.0, "a": 47.5, "g": 45.969 },
|
{ "t": "2025-07-14 00:00:00", "i": 12.0, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-12 00:00:00", "i": 33.0, "a": 49.5, "g": 45.922 },
|
{ "t": "2025-07-13 00:00:00", "i": 13.0, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-11 00:00:00", "i": 39.0, "a": 48.0, "g": 45.922 },
|
{ "t": "2025-07-12 00:00:00", "i": 12.5, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-10 00:00:00", "i": 33.0, "a": 48.0, "g": 46.162 },
|
{ "t": "2025-07-11 00:00:00", "i": 12.5, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-09 00:00:00", "i": 39.0, "a": 48.0, "g": 46.091 },
|
{ "t": "2025-07-10 00:00:00", "i": 13.0, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-08 00:00:00", "i": 45.0, "a": 47.0, "g": 45.88 },
|
{ "t": "2025-07-09 00:00:00", "i": 13.5, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-07 00:00:00", "i": 43.0, "a": 47.5, "g": 45.852 },
|
{ "t": "2025-07-08 00:00:00", "i": 13.0, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-06 00:00:00", "i": 32.5, "a": 48.0, "g": 45.753 },
|
{ "t": "2025-07-07 00:00:00", "i": 13.0, "a": 14.0, "g": 13.519 },
|
||||||
{ "t": "2025-04-05 00:00:00", "i": 39.0, "a": 47.5, "g": 45.915 },
|
{ "t": "2025-07-06 00:00:00", "i": 13.0, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-04 00:00:00", "i": 43.0, "a": 47.5, "g": 46.055 },
|
{ "t": "2025-07-05 00:00:00", "i": 13.0, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-03 00:00:00", "i": 45.0, "a": 47.5, "g": 45.841 },
|
{ "t": "2025-07-04 00:00:00", "i": 12.0, "a": 13.5, "g": 13.493 },
|
||||||
{ "t": "2025-04-02 00:00:00", "i": 45.0, "a": 48.0, "g": 46.054 },
|
{ "t": "2025-07-03 00:00:00", "i": 12.5, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-04-01 00:00:00", "i": 45.0, "a": 47.5, "g": 46.168 },
|
{ "t": "2025-07-02 00:00:00", "i": 13.5, "a": 14.0, "g": 13.664 },
|
||||||
{ "t": "2025-03-31 00:00:00", "i": 33.0, "a": 48.0, "g": 46.177 },
|
{ "t": "2025-07-01 00:00:00", "i": 12.5, "a": 14.0, "g": 13.815 },
|
||||||
{ "t": "2025-03-30 00:00:00", "i": 45.0, "a": 48.0, "g": 45.998 },
|
{ "t": "2025-06-30 00:00:00", "i": 12.5, "a": 14.0, "g": 13.637 },
|
||||||
{ "t": "2025-03-29 00:00:00", "i": 45.0, "a": 47.5, "g": 45.93 },
|
{ "t": "2025-06-29 00:00:00", "i": 13.0, "a": 14.0, "g": 13.502 },
|
||||||
{ "t": "2025-03-28 00:00:00", "i": 38.5, "a": 48.0, "g": 45.945 },
|
{ "t": "2025-06-28 00:00:00", "i": 13.0, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-03-27 00:00:00", "i": 45.5, "a": 48.0, "g": 46.254 },
|
{ "t": "2025-06-27 00:00:00", "i": 12.5, "a": 13.5, "g": 13.5 },
|
||||||
{ "t": "2025-03-26 00:00:00", "i": 45.5, "a": 47.0, "g": 46.192 },
|
{ "t": "2025-06-26 00:00:00", "i": 13.5, "a": 14.0, "g": 13.5 },
|
||||||
{ "t": "2025-03-19 00:00:00", "i": 10.5, "a": 11.5, "g": 11.048 },
|
{ "t": "2025-06-25 00:00:00", "i": 13.0, "a": 14.0, "g": 13.851 }
|
||||||
{ "t": "2025-03-18 00:00:00", "i": 10.5, "a": 11.5, "g": 11.009 },
|
|
||||||
{ "t": "2025-03-17 00:00:00", "i": 10.5, "a": 11.5, "g": 11.11 },
|
|
||||||
{ "t": "2025-03-16 00:00:00", "i": 10.5, "a": 11.5, "g": 11.119 },
|
|
||||||
{ "t": "2025-03-15 00:00:00", "i": 10.5, "a": 11.5, "g": 11.012 },
|
|
||||||
{ "t": "2025-03-14 00:00:00", "i": 11.0, "a": 11.5, "g": 11.019 },
|
|
||||||
{ "t": "2025-03-13 00:00:00", "i": 11.0, "a": 11.5, "g": 11.012 },
|
|
||||||
{ "t": "2025-03-12 00:00:00", "i": 11.0, "a": 11.5, "g": 11.147 },
|
|
||||||
{ "t": "2025-03-11 00:00:00", "i": 11.0, "a": 11.5, "g": 11.079 },
|
|
||||||
{ "t": "2025-03-10 00:00:00", "i": 10.5, "a": 11.5, "g": 11.004 },
|
|
||||||
{ "t": "2025-03-09 00:00:00", "i": 11.0, "a": 11.5, "g": 11.0 },
|
|
||||||
{ "t": "2025-03-08 00:00:00", "i": 10.5, "a": 11.5, "g": 10.998 },
|
|
||||||
{ "t": "2025-03-07 00:00:00", "i": 10.5, "a": 11.5, "g": 11.141 },
|
|
||||||
{ "t": "2025-03-06 00:00:00", "i": 11.0, "a": 11.5, "g": 11.152 },
|
|
||||||
{ "t": "2025-03-05 00:00:00", "i": 10.5, "a": 11.5, "g": 11.095 },
|
|
||||||
{ "t": "2025-03-04 00:00:00", "i": 11.0, "a": 11.5, "g": 11.205 },
|
|
||||||
{ "t": "2025-03-03 00:00:00", "i": 10.5, "a": 11.5, "g": 11.096 },
|
|
||||||
{ "t": "2025-03-02 00:00:00", "i": 11.0, "a": 11.5, "g": 11.072 },
|
|
||||||
{ "t": "2025-03-01 00:00:00", "i": 11.0, "a": 11.5, "g": 11.03 },
|
|
||||||
{ "t": "2025-02-28 00:00:00", "i": 11.0, "a": 11.5, "g": 11.0 },
|
|
||||||
{ "t": "2025-02-27 00:00:00", "i": 11.0, "a": 11.0, "g": 11.0 },
|
|
||||||
{ "t": "2025-02-26 00:00:00", "i": 10.5, "a": 11.0, "g": 10.996 },
|
|
||||||
{ "t": "2025-02-25 00:00:00", "i": 7.0, "a": 200.0, "g": 24.363 },
|
|
||||||
{ "t": "2025-02-24 00:00:00", "i": 27.5, "a": 50.0, "g": 46.878 },
|
|
||||||
{ "t": "2025-02-23 00:00:00", "i": 27.5, "a": 49.5, "g": 46.693 },
|
|
||||||
{ "t": "2025-02-22 00:00:00", "i": 27.5, "a": 50.0, "g": 46.85 },
|
|
||||||
{ "t": "2025-02-21 00:00:00", "i": 28.0, "a": 50.0, "g": 47.063 },
|
|
||||||
{ "t": "2025-02-20 00:00:00", "i": 28.0, "a": 50.5, "g": 47.147 },
|
|
||||||
{ "t": "2025-02-19 00:00:00", "i": 19.0, "a": 50.5, "g": 47.355 },
|
|
||||||
{ "t": "2025-02-18 00:00:00", "i": 35.5, "a": 200.0, "g": 47.58 },
|
|
||||||
{ "t": "2025-02-17 00:00:00", "i": 35.5, "a": 200.0, "g": 47.261 },
|
|
||||||
{ "t": "2025-02-16 00:00:00", "i": 35.5, "a": 49.0, "g": 46.903 },
|
|
||||||
{ "t": "2025-02-15 00:00:00", "i": 36.0, "a": 49.0, "g": 46.896 },
|
|
||||||
{ "t": "2025-02-14 00:00:00", "i": 35.5, "a": 48.5, "g": 46.826 },
|
|
||||||
{ "t": "2025-02-13 00:00:00", "i": 200.0, "a": 200.0, "g": 200.0 }
|
|
||||||
]
|
]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,67 +1,18 @@
|
|||||||
[
|
[
|
||||||
{ "t": "2025-04-24 00:00:00", "i": 39.0, "a": 48.0, "g": 45.984 },
|
{ "t": "2025-07-25 00:00:00", "i": 25.0, "a": 47.5, "g": 45.284 },
|
||||||
{ "t": "2025-04-23 00:00:00", "i": 33.0, "a": 47.5, "g": 45.985 },
|
{ "t": "2025-07-24 00:00:00", "i": 25.0, "a": 200.0, "g": 45.605 },
|
||||||
{ "t": "2025-04-22 00:00:00", "i": 33.0, "a": 49.0, "g": 46.196 },
|
{ "t": "2025-07-23 00:00:00", "i": 23.0, "a": 47.5, "g": 45.979 },
|
||||||
{ "t": "2025-04-21 00:00:00", "i": 39.5, "a": 48.0, "g": 46.147 },
|
{ "t": "2025-07-22 00:00:00", "i": 39.0, "a": 47.0, "g": 45.469 },
|
||||||
{ "t": "2025-04-20 00:00:00", "i": 43.0, "a": 49.0, "g": 46.053 },
|
{ "t": "2025-07-21 00:00:00", "i": 33.5, "a": 47.5, "g": 45.793 },
|
||||||
{ "t": "2025-04-19 00:00:00", "i": 45.0, "a": 47.5, "g": 46.019 },
|
{ "t": "2025-07-20 00:00:00", "i": 33.5, "a": 47.5, "g": 45.947 },
|
||||||
{ "t": "2025-04-18 00:00:00", "i": 39.0, "a": 49.5, "g": 46.097 },
|
{ "t": "2025-07-19 00:00:00", "i": 39.0, "a": 47.0, "g": 45.568 },
|
||||||
{ "t": "2025-04-17 00:00:00", "i": 43.0, "a": 48.0, "g": 45.972 },
|
{ "t": "2025-07-18 00:00:00", "i": 42.5, "a": 46.5, "g": 45.339 },
|
||||||
{ "t": "2025-04-16 00:00:00", "i": 32.5, "a": 49.0, "g": 45.647 },
|
{ "t": "2025-07-17 00:00:00", "i": 33.5, "a": 47.0, "g": 45.651 },
|
||||||
{ "t": "2025-04-15 00:00:00", "i": 45.0, "a": 47.0, "g": 45.71 },
|
{ "t": "2025-07-16 00:00:00", "i": 43.0, "a": 47.0, "g": 45.817 },
|
||||||
{ "t": "2025-04-14 00:00:00", "i": 43.0, "a": 49.0, "g": 45.942 },
|
{ "t": "2025-07-15 00:00:00", "i": 39.5, "a": 47.5, "g": 45.826 },
|
||||||
{ "t": "2025-04-13 00:00:00", "i": 43.0, "a": 47.5, "g": 45.969 },
|
{ "t": "2025-07-14 00:00:00", "i": 39.0, "a": 47.0, "g": 45.297 },
|
||||||
{ "t": "2025-04-12 00:00:00", "i": 33.0, "a": 49.5, "g": 45.922 },
|
{ "t": "2025-07-13 00:00:00", "i": 32.5, "a": 46.5, "g": 45.005 },
|
||||||
{ "t": "2025-04-11 00:00:00", "i": 39.0, "a": 48.0, "g": 45.922 },
|
{ "t": "2025-07-12 00:00:00", "i": 39.0, "a": 46.0, "g": 45.026 },
|
||||||
{ "t": "2025-04-10 00:00:00", "i": 33.0, "a": 48.0, "g": 46.162 },
|
{ "t": "2025-07-11 00:00:00", "i": 42.5, "a": 46.5, "g": 45.084 },
|
||||||
{ "t": "2025-04-09 00:00:00", "i": 39.0, "a": 48.0, "g": 46.091 },
|
{ "t": "2025-07-10 00:00:00", "i": 44.5, "a": 46.0, "g": 44.983 }
|
||||||
{ "t": "2025-04-08 00:00:00", "i": 45.0, "a": 47.0, "g": 45.88 },
|
|
||||||
{ "t": "2025-04-07 00:00:00", "i": 43.0, "a": 47.5, "g": 45.852 },
|
|
||||||
{ "t": "2025-04-06 00:00:00", "i": 32.5, "a": 48.0, "g": 45.753 },
|
|
||||||
{ "t": "2025-04-05 00:00:00", "i": 39.0, "a": 47.5, "g": 45.915 },
|
|
||||||
{ "t": "2025-04-04 00:00:00", "i": 43.0, "a": 47.5, "g": 46.055 },
|
|
||||||
{ "t": "2025-04-03 00:00:00", "i": 45.0, "a": 47.5, "g": 45.841 },
|
|
||||||
{ "t": "2025-04-02 00:00:00", "i": 45.0, "a": 48.0, "g": 46.054 },
|
|
||||||
{ "t": "2025-04-01 00:00:00", "i": 45.0, "a": 47.5, "g": 46.168 },
|
|
||||||
{ "t": "2025-03-31 00:00:00", "i": 33.0, "a": 48.0, "g": 46.177 },
|
|
||||||
{ "t": "2025-03-30 00:00:00", "i": 45.0, "a": 48.0, "g": 45.998 },
|
|
||||||
{ "t": "2025-03-29 00:00:00", "i": 45.0, "a": 47.5, "g": 45.93 },
|
|
||||||
{ "t": "2025-03-28 00:00:00", "i": 38.5, "a": 48.0, "g": 45.945 },
|
|
||||||
{ "t": "2025-03-27 00:00:00", "i": 45.5, "a": 48.0, "g": 46.254 },
|
|
||||||
{ "t": "2025-03-26 00:00:00", "i": 45.5, "a": 47.0, "g": 46.192 },
|
|
||||||
{ "t": "2025-03-19 00:00:00", "i": 10.5, "a": 11.5, "g": 11.048 },
|
|
||||||
{ "t": "2025-03-18 00:00:00", "i": 10.5, "a": 11.5, "g": 11.009 },
|
|
||||||
{ "t": "2025-03-17 00:00:00", "i": 10.5, "a": 11.5, "g": 11.11 },
|
|
||||||
{ "t": "2025-03-16 00:00:00", "i": 10.5, "a": 11.5, "g": 11.119 },
|
|
||||||
{ "t": "2025-03-15 00:00:00", "i": 10.5, "a": 11.5, "g": 11.012 },
|
|
||||||
{ "t": "2025-03-14 00:00:00", "i": 11.0, "a": 11.5, "g": 11.019 },
|
|
||||||
{ "t": "2025-03-13 00:00:00", "i": 11.0, "a": 11.5, "g": 11.012 },
|
|
||||||
{ "t": "2025-03-12 00:00:00", "i": 11.0, "a": 11.5, "g": 11.147 },
|
|
||||||
{ "t": "2025-03-11 00:00:00", "i": 11.0, "a": 11.5, "g": 11.079 },
|
|
||||||
{ "t": "2025-03-10 00:00:00", "i": 10.5, "a": 11.5, "g": 11.004 },
|
|
||||||
{ "t": "2025-03-09 00:00:00", "i": 11.0, "a": 11.5, "g": 11.0 },
|
|
||||||
{ "t": "2025-03-08 00:00:00", "i": 10.5, "a": 11.5, "g": 10.998 },
|
|
||||||
{ "t": "2025-03-07 00:00:00", "i": 10.5, "a": 11.5, "g": 11.141 },
|
|
||||||
{ "t": "2025-03-06 00:00:00", "i": 11.0, "a": 11.5, "g": 11.152 },
|
|
||||||
{ "t": "2025-03-05 00:00:00", "i": 10.5, "a": 11.5, "g": 11.095 },
|
|
||||||
{ "t": "2025-03-04 00:00:00", "i": 11.0, "a": 11.5, "g": 11.205 },
|
|
||||||
{ "t": "2025-03-03 00:00:00", "i": 10.5, "a": 11.5, "g": 11.096 },
|
|
||||||
{ "t": "2025-03-02 00:00:00", "i": 11.0, "a": 11.5, "g": 11.072 },
|
|
||||||
{ "t": "2025-03-01 00:00:00", "i": 11.0, "a": 11.5, "g": 11.03 },
|
|
||||||
{ "t": "2025-02-28 00:00:00", "i": 11.0, "a": 11.5, "g": 11.0 },
|
|
||||||
{ "t": "2025-02-27 00:00:00", "i": 11.0, "a": 11.0, "g": 11.0 },
|
|
||||||
{ "t": "2025-02-26 00:00:00", "i": 10.5, "a": 11.0, "g": 10.996 },
|
|
||||||
{ "t": "2025-02-25 00:00:00", "i": 7.0, "a": 200.0, "g": 24.363 },
|
|
||||||
{ "t": "2025-02-24 00:00:00", "i": 27.5, "a": 50.0, "g": 46.878 },
|
|
||||||
{ "t": "2025-02-23 00:00:00", "i": 27.5, "a": 49.5, "g": 46.693 },
|
|
||||||
{ "t": "2025-02-22 00:00:00", "i": 27.5, "a": 50.0, "g": 46.85 },
|
|
||||||
{ "t": "2025-02-21 00:00:00", "i": 28.0, "a": 50.0, "g": 47.063 },
|
|
||||||
{ "t": "2025-02-20 00:00:00", "i": 28.0, "a": 50.5, "g": 47.147 },
|
|
||||||
{ "t": "2025-02-19 00:00:00", "i": 19.0, "a": 50.5, "g": 47.355 },
|
|
||||||
{ "t": "2025-02-18 00:00:00", "i": 35.5, "a": 200.0, "g": 47.58 },
|
|
||||||
{ "t": "2025-02-17 00:00:00", "i": 35.5, "a": 200.0, "g": 47.261 },
|
|
||||||
{ "t": "2025-02-16 00:00:00", "i": 35.5, "a": 49.0, "g": 46.903 },
|
|
||||||
{ "t": "2025-02-15 00:00:00", "i": 36.0, "a": 49.0, "g": 46.896 },
|
|
||||||
{ "t": "2025-02-14 00:00:00", "i": 35.5, "a": 48.5, "g": 46.826 },
|
|
||||||
{ "t": "2025-02-13 00:00:00", "i": 200.0, "a": 200.0, "g": 200.0 }
|
|
||||||
]
|
]
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.651",
|
"version": "1.6.652",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.651",
|
"version": "1.6.652",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "^5.1.0",
|
"@fontsource/roboto": "^5.1.0",
|
||||||
"@headlessui/react": "^2.2.4",
|
"@headlessui/react": "^2.2.4",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.651",
|
"version": "1.6.652",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
interface KueChartModeState {
|
interface KueChartModeState {
|
||||||
activeMode: "Schleife" | "TDR"; // 🔥 Zustand für den aktiven Modus
|
activeMode: "Schleife" | "TDR" | "ISO"; // 🔥 Zustand für den aktiven Modus
|
||||||
selectedSlot: number | null; // 🔥 Neu: Aktuell gewählter Slot
|
selectedSlot: number | null; // 🔥 Neu: Aktuell gewählter Slot
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,8 +15,11 @@ export const kueChartModeSlice = createSlice({
|
|||||||
name: "kueChartModeSlice",
|
name: "kueChartModeSlice",
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
setActiveMode: (state, action: PayloadAction<"Schleife" | "TDR">) => {
|
setActiveMode: (
|
||||||
state.activeMode = action.payload; // 🔥 Speichert den Modus (Schleife oder TDR)
|
state,
|
||||||
|
action: PayloadAction<"Schleife" | "TDR" | "ISO">
|
||||||
|
) => {
|
||||||
|
state.activeMode = action.payload; // 🔥 Speichert den Modus (Schleife, TDR oder ISO)
|
||||||
},
|
},
|
||||||
setSelectedSlot: (state, action: PayloadAction<number>) => {
|
setSelectedSlot: (state, action: PayloadAction<number>) => {
|
||||||
state.selectedSlot = action.payload; // 🔥 Speichert den aktiven Slot
|
state.selectedSlot = action.payload; // 🔥 Speichert den aktiven Slot
|
||||||
|
|||||||
Reference in New Issue
Block a user