ISO, RSL, TDR, und KVZ Modal nach Wünsch angepasst für KÜs

This commit is contained in:
ISA
2025-08-11 14:24:03 +02:00
parent 06aa3c8f3e
commit bc20f3869d
11 changed files with 287 additions and 21 deletions

View File

@@ -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.686 NEXT_PUBLIC_APP_VERSION=1.6.687
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)

View File

@@ -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.686 NEXT_PUBLIC_APP_VERSION=1.6.687
NEXT_PUBLIC_CPL_MODE=production NEXT_PUBLIC_CPL_MODE=production

View File

@@ -1,3 +1,8 @@
## [1.6.687] 2025-08-11
- ISO & RSL dropdowns moved to headers like TDR; removed old dropdowns from action bars, cleaned imports, fixed TypeScript issues
---
## [1.6.686] 2025-08-11 ## [1.6.686] 2025-08-11
- LoopChartActionBar verhält sich jetzt wie im ISO-Modal: Bei Auswahl „Meldungen“ - LoopChartActionBar verhält sich jetzt wie im ISO-Modal: Bei Auswahl „Meldungen“

View File

@@ -234,7 +234,11 @@ const IsoChartView: React.FC<IsoChartViewProps> = ({
</div> </div>
<IsoChartActionBar /> <IsoChartActionBar />
<div style={{ flex: 1, height: "90%" }}> <div style={{ flex: 1, height: "90%" }}>
{chartTitle === "Messkurve" ? <IsoMeasurementChart /> : <Report />} {chartTitle === "Messkurve" ? (
<IsoMeasurementChart />
) : (
<Report moduleType="ISO" />
)}
</div> </div>
</div> </div>
</ReactModal> </ReactModal>

View File

@@ -1,6 +1,6 @@
"use client"; // Report.tsx "use client"; // Report.tsx
import React, { useState, useEffect, useCallback } from "react"; import React, { useState, useEffect, useCallback, useMemo } from "react";
import { useSelector, useDispatch } from "react-redux"; import { useSelector, useDispatch } from "react-redux";
import { RootState, AppDispatch } from "@/redux/store"; import { RootState, AppDispatch } from "@/redux/store";
import { getMessagesThunk } from "@/redux/thunks/getMessagesThunk"; import { getMessagesThunk } from "@/redux/thunks/getMessagesThunk";
@@ -15,7 +15,13 @@ type Meldung = {
v: string; // value/status text v: string; // value/status text
}; };
const Report: React.FC = () => { type ModuleType = "ISO" | "TDR" | "RSL" | "KVZ";
interface ReportProps {
moduleType: ModuleType;
}
const Report: React.FC<ReportProps> = ({ moduleType }) => {
const dispatch = useDispatch<AppDispatch>(); const dispatch = useDispatch<AppDispatch>();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
@@ -109,6 +115,24 @@ const Report: React.FC = () => {
[] []
); );
// Modul-spezifische Schlüsselwörter (alle lowercase, ö => oe normalisiert)
const moduleKeywordMap = useMemo<Record<ModuleType, string[]>>(
() => ({
ISO: ["modul online", "aderbruch", "erdschluss", "isofehler"],
TDR: ["modul online", "tdr aktiv", "tdr entfernung"],
RSL: ["modul online", "aderbruch", "schleifenfehler"],
KVZ: ["modul online", "aderbruch", "kvz störung", "kvz stoerung"],
}),
[]
);
const normalize = (text: string) =>
text
.toLowerCase()
.replace(/ö/g, "oe")
.replace(/ä/g, "ae")
.replace(/ü/g, "ue");
// Daten laden // Daten laden
const loadMessages = useCallback(async () => { const loadMessages = useCallback(async () => {
if (slotNumber === null) return; if (slotNumber === null) return;
@@ -135,12 +159,24 @@ const Report: React.FC = () => {
// Filter anwenden wenn sich Nachrichten oder Slot ändern // Filter anwenden wenn sich Nachrichten oder Slot ändern
useEffect(() => { useEffect(() => {
if (slotNumber !== null && messages.length > 0) { if (slotNumber !== null && messages.length > 0) {
const filtered = filterMessagesForSlot(messages, slotNumber); const slotFiltered = filterMessagesForSlot(messages, slotNumber);
setFilteredMessages(filtered); // Modul-Filter anwenden
const keywords = moduleKeywordMap[moduleType].map(normalize);
const moduleFiltered = slotFiltered.filter((m) => {
const msgNorm = normalize(m.m);
return keywords.some((kw) => msgNorm.includes(kw));
});
setFilteredMessages(moduleFiltered);
} else { } else {
setFilteredMessages([]); setFilteredMessages([]);
} }
}, [messages, slotNumber, filterMessagesForSlot]); }, [
messages,
slotNumber,
filterMessagesForSlot,
moduleType,
moduleKeywordMap,
]);
// Automatisches Laden beim Mount und bei Änderungen // Automatisches Laden beim Mount und bei Änderungen
useEffect(() => { useEffect(() => {
@@ -169,8 +205,8 @@ const Report: React.FC = () => {
{filteredMessages.length === 0 ? ( {filteredMessages.length === 0 ? (
<div className="text-center text-gray-500 "> <div className="text-center text-gray-500 ">
Keine Meldungen für CableLine Keine Meldungen für CableLine
{slotNumber !== null ? slotNumber + 1 : "-"} im gewählten Zeitraum {slotNumber !== null ? slotNumber + 1 : "-"} (Filter: {moduleType}) im
gefunden. gewählten Zeitraum gefunden.
</div> </div>
) : ( ) : (
<div className="flex-1 overflow-auto "> <div className="flex-1 overflow-auto ">
@@ -213,9 +249,9 @@ const Report: React.FC = () => {
</div> </div>
)} )}
<div className="mt-4 text-sm text-gray-500 text-center mt-4"> {/* <div className="mt-4 text-sm text-gray-500 text-center mt-4">
{filteredMessages.length} Meldung(en) gefunden {filteredMessages.length} Meldung(en) (Filter: {moduleType}) gefunden
</div> </div> */}
</div> </div>
); );
}; };

View File

@@ -34,6 +34,9 @@ const KVZChartView: React.FC<KVZChartViewProps> = ({
const isFullScreen = useSelector( const isFullScreen = useSelector(
(state: RootState) => state.kabelueberwachungChartSlice.isFullScreen (state: RootState) => state.kabelueberwachungChartSlice.isFullScreen
); );
const slotNumber = useSelector(
(state: RootState) => state.kabelueberwachungChartSlice.slotNumber
);
// Beim Öffnen Slot setzen (damit konsistent zu anderen Modals) // Beim Öffnen Slot setzen (damit konsistent zu anderen Modals)
useEffect(() => { useEffect(() => {
@@ -129,14 +132,20 @@ const KVZChartView: React.FC<KVZChartViewProps> = ({
<h3 className="text-lg font-semibold mb-1">KVz Zustände & Meldungen</h3> <h3 className="text-lg font-semibold mb-1">KVz Zustände & Meldungen</h3>
{/* LED Bereich */} {/* LED Bereich */}
<div className="w-full flex justify-start mb-4"> <div className="w-full flex justify-between mb-4">
<div className="flex items-center">
<label className="text-sm font-semibold">
{slotNumber !== null ? slotNumber + 1 : "-"}
</label>
</div>
<div style={{ width: "12rem" }}> <div style={{ width: "12rem" }}>
<FallSensors slotIndex={slotIndex} /> <FallSensors slotIndex={slotIndex} />
</div> </div>
<div></div>
</div> </div>
{/* Meldungen Bereich */} {/* Meldungen Bereich */}
<div className="flex-1 border rounded bg-white overflow-hidden"> <div className="flex-1 border rounded bg-white overflow-hidden">
<Report /> <Report moduleType="KVZ" />
</div> </div>
</div> </div>
</ReactModal> </ReactModal>

View File

@@ -235,7 +235,11 @@ const LoopChartView: React.FC<LoopChartViewProps> = ({
</div> </div>
<LoopChartActionBar /> <LoopChartActionBar />
<div style={{ flex: 1, height: "90%" }}> <div style={{ flex: 1, height: "90%" }}>
{chartTitle === "Messkurve" ? <LoopMeasurementChart /> : <Report />} {chartTitle === "Messkurve" ? (
<LoopMeasurementChart />
) : (
<Report moduleType="RSL" />
)}
</div> </div>
</div> </div>
</ReactModal> </ReactModal>

View File

@@ -225,7 +225,7 @@ const TDRChartView: React.FC<TDRChartViewProps> = ({
{chartTitle === "Messkurve" ? ( {chartTitle === "Messkurve" ? (
<TDRChart isFullScreen={isFullScreen} /> <TDRChart isFullScreen={isFullScreen} />
) : ( ) : (
<Report /> <Report moduleType="TDR" />
)} )}
</div> </div>
</div> </div>

View File

@@ -3998,5 +3998,213 @@
"m": "Isofehler gehend", "m": "Isofehler gehend",
"i": "CableLine13", "i": "CableLine13",
"v": "0" "v": "0"
},
{
"t": "2025-08-11 12:05:00",
"s": 100,
"c": "#00d200",
"m": "Modul online",
"i": "CableLine1",
"v": "online"
},
{
"t": "2025-08-11 12:06:00",
"s": 400,
"c": "#ff9900",
"m": "Aderbruch kommend",
"i": "CableLine1",
"v": "1"
},
{
"t": "2025-08-11 12:06:30",
"s": 0,
"c": "#00d200",
"m": "Aderbruch gehend",
"i": "CableLine1",
"v": "0"
},
{
"t": "2025-08-11 12:07:00",
"s": 500,
"c": "#ff0000",
"m": "Erdschluss kommend",
"i": "CableLine1",
"v": "1"
},
{
"t": "2025-08-11 12:07:20",
"s": 0,
"c": "#00d200",
"m": "Erdschluss gehend",
"i": "CableLine1",
"v": "0"
},
{
"t": "2025-08-11 12:07:40",
"s": 500,
"c": "#ff0000",
"m": "Isofehler kommend",
"i": "CableLine1",
"v": "1"
},
{
"t": "2025-08-11 12:08:10",
"s": 0,
"c": "#00d200",
"m": "Isofehler gehend",
"i": "CableLine1",
"v": "0"
},
{
"t": "2025-08-11 12:08:40",
"s": 300,
"c": "#ffaa00",
"m": "Schleifenfehler kommend",
"i": "CableLine1",
"v": "1"
},
{
"t": "2025-08-11 12:09:00",
"s": 0,
"c": "#00d200",
"m": "Schleifenfehler gehend",
"i": "CableLine1",
"v": "0"
},
{
"t": "2025-08-11 12:09:20",
"s": 500,
"c": "#ff0000",
"m": "TDR aktiv",
"i": "CableLine1",
"v": "start"
},
{
"t": "2025-08-11 12:09:50",
"s": 200,
"c": "#0077ff",
"m": "TDR Entfernung 123m",
"i": "CableLine1",
"v": "123"
},
{
"t": "2025-08-11 12:10:10",
"s": 400,
"c": "#ff9900",
"m": "KVz Störung kommend",
"i": "CableLine1",
"v": "1"
},
{
"t": "2025-08-11 12:10:40",
"s": 0,
"c": "#00d200",
"m": "KVz Störung gehend",
"i": "CableLine1",
"v": "0"
},
{
"t": "2025-08-11 12:11:10",
"s": 100,
"c": "#00d200",
"m": "Modul online",
"i": "CableLine11",
"v": "online"
},
{
"t": "2025-08-11 12:11:40",
"s": 400,
"c": "#ff9900",
"m": "Aderbruch kommend",
"i": "CableLine11",
"v": "1"
},
{
"t": "2025-08-11 12:12:10",
"s": 0,
"c": "#00d200",
"m": "Aderbruch gehend",
"i": "CableLine11",
"v": "0"
},
{
"t": "2025-08-11 12:12:40",
"s": 500,
"c": "#ff0000",
"m": "Erdschluss kommend",
"i": "CableLine11",
"v": "1"
},
{
"t": "2025-08-11 12:13:10",
"s": 0,
"c": "#00d200",
"m": "Erdschluss gehend",
"i": "CableLine11",
"v": "0"
},
{
"t": "2025-08-11 12:13:40",
"s": 500,
"c": "#ff0000",
"m": "Isofehler kommend",
"i": "CableLine11",
"v": "1"
},
{
"t": "2025-08-11 12:14:10",
"s": 0,
"c": "#00d200",
"m": "Isofehler gehend",
"i": "CableLine11",
"v": "0"
},
{
"t": "2025-08-11 12:14:40",
"s": 300,
"c": "#ffaa00",
"m": "Schleifenfehler kommend",
"i": "CableLine11",
"v": "1"
},
{
"t": "2025-08-11 12:15:10",
"s": 0,
"c": "#00d200",
"m": "Schleifenfehler gehend",
"i": "CableLine11",
"v": "0"
},
{
"t": "2025-08-11 12:15:40",
"s": 500,
"c": "#ff0000",
"m": "TDR aktiv",
"i": "CableLine11",
"v": "start"
},
{
"t": "2025-08-11 12:16:10",
"s": 200,
"c": "#0077ff",
"m": "TDR Entfernung 87m",
"i": "CableLine11",
"v": "87"
},
{
"t": "2025-08-11 12:16:40",
"s": 400,
"c": "#ff9900",
"m": "KVz Störung kommend",
"i": "CableLine11",
"v": "1"
},
{
"t": "2025-08-11 12:17:10",
"s": 0,
"c": "#00d200",
"m": "KVz Störung gehend",
"i": "CableLine11",
"v": "0"
} }
] ]

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.686", "version": "1.6.687",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.686", "version": "1.6.687",
"dependencies": { "dependencies": {
"@fontsource/roboto": "^5.1.0", "@fontsource/roboto": "^5.1.0",
"@headlessui/react": "^2.2.4", "@headlessui/react": "^2.2.4",

View File

@@ -1,6 +1,6 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.686", "version": "1.6.687",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",