Files
CPLv4.0/components/main/kabelueberwachung/kue705FO/Charts/LoopMeasurementChart/LoopChartView.tsx
2025-09-09 10:35:34 +02:00

182 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"; // LoopChartView.tsx
import React, { useEffect, useRef } from "react";
import { Listbox } from "@headlessui/react";
import ReactModal from "react-modal";
import LoopMeasurementChart from "./LoopMeasurementChart";
import Report from "../IsoMeasurementChart/Report";
import LoopChartActionBar from "./LoopChartActionBar";
import { useSelector, useDispatch } from "react-redux";
import { AppDispatch, RootState } from "@/redux/store";
import {
setChartOpen,
setFullScreen,
setSlotNumber,
setVonDatum,
setBisDatum,
setSelectedMode,
setSelectedSlotType,
} from "@/redux/slices/kabelueberwachungChartSlice";
import { setChartTitle as setLoopChartTitle } from "@/redux/slices/loopChartTypeSlice";
import { resetBrushRange } from "@/redux/slices/brushSlice";
import { resetDateRange } from "@/redux/slices/dateRangePickerSlice";
interface LoopChartViewProps {
isOpen: boolean;
onClose: () => void;
slotIndex: number;
}
function LoopChartView({ isOpen, onClose, slotIndex }: LoopChartViewProps) {
const dispatch = useDispatch<AppDispatch>();
const chartTitle = useSelector(
(state: RootState) => state.loopChartType.chartTitle
);
const isFullScreen = useSelector(
(state: RootState) => state.kabelueberwachungChartSlice.isFullScreen
);
// slotNumber nicht direkt benötigt wird intern über Redux genutzt
// **Modal schließen + Redux-Status zurücksetzen**
const handleClose = () => {
const today = new Date();
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(today.getDate() - 30);
const toISO = (date: Date) => date.toLocaleDateString("sv-SE");
dispatch(setVonDatum(toISO(thirtyDaysAgo)));
dispatch(setBisDatum(toISO(today)));
dispatch(resetDateRange());
dispatch(setSelectedMode("DIA0"));
dispatch(setSelectedSlotType("schleifenwiderstand"));
dispatch(setChartOpen(false));
dispatch(setFullScreen(false));
dispatch(resetBrushRange());
onClose();
};
const toggleFullScreen = () => dispatch(setFullScreen(!isFullScreen));
const actionBarRef = useRef<{ handleFetchData: () => void }>(null);
useEffect(() => {
if (isOpen) {
const today = new Date();
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(today.getDate() - 30);
const toISO = (date: Date) => date.toLocaleDateString("sv-SE");
dispatch(setSlotNumber(slotIndex));
dispatch(setVonDatum(toISO(thirtyDaysAgo)));
dispatch(setBisDatum(toISO(today)));
dispatch(setSelectedSlotType("schleifenwiderstand"));
dispatch(setSelectedMode("DIA0"));
const t = setTimeout(() => actionBarRef.current?.handleFetchData(), 120);
return () => clearTimeout(t);
}
}, [isOpen, slotIndex, dispatch]);
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="Schleifenwiderstand"
>
<header className="modal-header relative pr-56">
<h3 className="text-sm font-semibold tracking-wide">
Schleifenwiderstand
</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>
<div className="absolute top-2 right-28">
<Listbox
value={chartTitle}
onChange={(value: "Messkurve" | "Meldungen") =>
dispatch(setLoopChartTitle(value))
}
>
<div className="relative w-40">
<Listbox.Button className="dropdown-surface w-full flex items-center justify-between h-8">
<span className="dropdown-text-fix">{chartTitle}</span>
<i className="bi bi-chevron-down text-sm opacity-70" />
</Listbox.Button>
<Listbox.Options className="dropdown-options absolute z-50 mt-1 w-full max-h-60 overflow-auto text-sm">
{(["Messkurve", "Meldungen"] as const).map((option) => (
<Listbox.Option
key={option}
value={option}
className={({ selected, active }) =>
`px-3 py-1.5 cursor-pointer rounded-sm m-0.5 ${
selected
? "dropdown-option-active"
: active
? "dropdown-option-hover"
: ""
}`
}
>
{option}
</Listbox.Option>
))}
</Listbox.Options>
</div>
</Listbox>
</div>
</header>
<div className="flex flex-col flex-1 p-3 gap-3">
<LoopChartActionBar ref={actionBarRef} />
<div className="flex-1 relative">
{chartTitle === "Messkurve" ? (
<LoopMeasurementChart />
) : (
<Report moduleType="RSL" autoLoad={chartTitle === "Meldungen"} />
)}
</div>
</div>
</ReactModal>
);
}
export default LoopChartView;