176 lines
5.8 KiB
TypeScript
176 lines
5.8 KiB
TypeScript
"use client"; // KVZChartView.tsx
|
||
|
||
import React, { useEffect } from "react";
|
||
import DateRangePicker from "@/components/common/DateRangePicker";
|
||
import { getMessagesThunk } from "@/redux/thunks/getMessagesThunk";
|
||
import { setLoading } from "@/redux/slices/kabelueberwachungChartSlice";
|
||
import ReactModal from "react-modal";
|
||
import { useDispatch, useSelector } from "react-redux";
|
||
import { AppDispatch, RootState } from "@/redux/store";
|
||
import {
|
||
setChartOpen,
|
||
setFullScreen,
|
||
setSlotNumber,
|
||
setVonDatum,
|
||
setBisDatum,
|
||
setSelectedMode,
|
||
setSelectedSlotType,
|
||
} from "@/redux/slices/kabelueberwachungChartSlice";
|
||
import { resetBrushRange } from "@/redux/slices/brushSlice";
|
||
import FallSensors from "../../../../fall-detection-sensors/FallSensors";
|
||
import Report from "../IsoMeasurementChart/Report";
|
||
|
||
interface KVZChartViewProps {
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
slotIndex: number;
|
||
}
|
||
|
||
// Modal zur Anzeige der KVz Zustände (Sturzsensoren / Fall Detection LEDs)
|
||
// Stil und Verhalten analog zu ISO / RSL / TDR Modals
|
||
const KVZChartView: React.FC<KVZChartViewProps> = ({
|
||
isOpen,
|
||
onClose,
|
||
slotIndex,
|
||
}) => {
|
||
const dispatch = useDispatch<AppDispatch>();
|
||
const { isFullScreen, slotNumber, vonDatum, bisDatum } = useSelector(
|
||
(state: RootState) => state.kabelueberwachungChartSlice
|
||
);
|
||
const { vonDatum: pickerVonDatum, bisDatum: pickerBisDatum } = useSelector(
|
||
(state: RootState) => state.dateRangePicker
|
||
);
|
||
|
||
// Beim Öffnen: Slot + Standard-Datumsbereich setzen (30 Tage) – analog zu anderen Modals
|
||
useEffect(() => {
|
||
if (!isOpen) return;
|
||
dispatch(setSlotNumber(slotIndex));
|
||
const today = new Date();
|
||
const thirtyDaysAgo = new Date();
|
||
thirtyDaysAgo.setDate(today.getDate() - 30);
|
||
const toISO = (d: Date) => d.toLocaleDateString("sv-SE");
|
||
dispatch(setVonDatum(toISO(thirtyDaysAgo)));
|
||
dispatch(setBisDatum(toISO(today)));
|
||
}, [isOpen, slotIndex, dispatch]);
|
||
|
||
const handleClose = () => {
|
||
// Reset auf Default (wie andere Modals es tun)
|
||
const today = new Date();
|
||
const thirtyDaysAgo = new Date();
|
||
thirtyDaysAgo.setDate(today.getDate() - 30);
|
||
const toISO = (d: Date) => d.toLocaleDateString("sv-SE");
|
||
dispatch(setVonDatum(toISO(thirtyDaysAgo)));
|
||
dispatch(setBisDatum(toISO(today)));
|
||
dispatch(setSelectedMode("DIA1"));
|
||
dispatch(setSelectedSlotType("isolationswiderstand"));
|
||
dispatch(setChartOpen(false));
|
||
dispatch(setFullScreen(false));
|
||
dispatch(resetBrushRange());
|
||
onClose();
|
||
};
|
||
|
||
const toggleFullScreen = () => dispatch(setFullScreen(!isFullScreen));
|
||
|
||
const handleFetchMessages = async () => {
|
||
const fromDate = pickerVonDatum ?? vonDatum;
|
||
const toDate = pickerBisDatum ?? bisDatum;
|
||
try {
|
||
dispatch(setLoading(true));
|
||
await dispatch(getMessagesThunk({ fromDate, toDate })).unwrap();
|
||
} catch (e) {
|
||
console.error("Fehler beim Laden der KVZ Meldungen", e);
|
||
} finally {
|
||
dispatch(setLoading(false));
|
||
}
|
||
};
|
||
return (
|
||
<ReactModal
|
||
isOpen={isOpen}
|
||
onRequestClose={handleClose}
|
||
ariaHideApp={false}
|
||
style={{
|
||
overlay: {
|
||
backgroundColor: "rgba(0,0,0,0.55)",
|
||
backdropFilter: "blur(2px)",
|
||
},
|
||
content: {
|
||
inset: "50% auto auto 50%",
|
||
transform: "translate(-50%, -50%)",
|
||
width: isFullScreen ? "90vw" : "72rem",
|
||
height: isFullScreen ? "90vh" : "38rem",
|
||
padding: 0,
|
||
border: "1px solid var(--color-border)",
|
||
background: "var(--color-surface)",
|
||
borderRadius: "14px",
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
overflow: "hidden",
|
||
},
|
||
}}
|
||
contentLabel="KVZ Zustände & Meldungen"
|
||
>
|
||
<header className="modal-header relative pr-32">
|
||
<h3 className="text-sm font-semibold tracking-wide">
|
||
KVZ Zustände & Meldungen
|
||
</h3>
|
||
<div className="absolute top-2 right-2 flex gap-2">
|
||
<button
|
||
onClick={toggleFullScreen}
|
||
className="icon-btn"
|
||
aria-label={isFullScreen ? "Vollbild verlassen" : "Vollbild"}
|
||
type="button"
|
||
>
|
||
<i
|
||
className={
|
||
isFullScreen
|
||
? "bi bi-fullscreen-exit"
|
||
: "bi bi-arrows-fullscreen"
|
||
}
|
||
/>
|
||
</button>
|
||
<button
|
||
onClick={handleClose}
|
||
className="icon-btn"
|
||
aria-label="Schließen"
|
||
type="button"
|
||
>
|
||
<i className="bi bi-x-lg" />
|
||
</button>
|
||
</div>
|
||
</header>
|
||
<div className="flex flex-col flex-1 p-3 gap-3">
|
||
{/* Toolbar */}
|
||
<div className="w-full flex flex-wrap items-center gap-4">
|
||
<div className="flex items-center gap-2">
|
||
<span className="text-xs font-semibold opacity-80 select-none text-fg-secondary">
|
||
KÜ {slotNumber !== null ? slotNumber + 1 : "-"}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center gap-3 flex-1 min-w-[20rem]">
|
||
<div className="relative z-[1500]">
|
||
<DateRangePicker />
|
||
</div>
|
||
<button
|
||
type="button"
|
||
onClick={handleFetchMessages}
|
||
className="btn-primary h-8 font-medium px-4"
|
||
>
|
||
Anzeigen
|
||
</button>
|
||
</div>
|
||
<div className="flex items-center justify-end w-48">
|
||
<FallSensors slotIndex={slotIndex} />
|
||
</div>
|
||
</div>
|
||
<div className="flex-1 relative border border-base rounded bg-[var(--color-surface-alt)] text-fg overflow-hidden p-2">
|
||
<div className="w-full h-full rounded bg-[var(--color-surface)] overflow-hidden">
|
||
<Report moduleType="KVZ" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</ReactModal>
|
||
);
|
||
};
|
||
|
||
export default KVZChartView;
|