git commit -m "feat: Enhance DetailModal with auto-loading and improved UX

- Add automatic data loading every 2 seconds when no chart data available
- Implement intelligent cursor-wait display for entire modal during loading
- Auto-reset to 'Alle Messwerte' (DIA0) and clear date fields on modal open
- Add Tailwind-based color system for chart lines (gray for min/max, littwin-blue for current/average)
- Improve chart line layering with background/foreground organization
- Add periodic UI updates to ensure responsive loading feedback
- Maintain manual 'Daten laden' button control alongside auto-loading
- Fix TypeScript dependencies and optimize useEffect performance"
This commit is contained in:
ISA
2025-08-01 14:05:58 +02:00
parent f8bfea039c
commit 3b61dcb31b
6 changed files with 77 additions and 47 deletions

View File

@@ -148,6 +148,7 @@ export const DetailModal = ({
});
const [isLoading, setIsLoading] = useState(false);
const [shouldUpdateChart, setShouldUpdateChart] = useState(false);
const [forceUpdate, setForceUpdate] = useState(0); // Für periodische UI-Updates
const reduxData = useSelector((state: RootState) => {
switch (selectedKey) {
@@ -173,46 +174,6 @@ export const DetailModal = ({
);
const dispatch = useAppDispatch();
// Reset Zeitraum auf DIA0 und Datumswerte wenn Modal geöffnet wird
useEffect(() => {
if (isOpen) {
setZeitraum("DIA0");
dispatch(setVonDatum(""));
dispatch(setBisDatum(""));
// Automatisch Daten laden nach dem Reset
setTimeout(() => {
handleFetchData();
}, 100); // Kurze Verzögerung damit setZeitraum wirksam wird
}
}, [isOpen, setZeitraum, dispatch]);
const toggleFullScreen = () => {
dispatch(setFullScreen(!isFullScreen));
setTimeout(() => {
chartRef.current?.resize();
}, 50);
};
const handleClose = () => {
dispatch(setFullScreen(false));
dispatch(setVonDatum(""));
dispatch(setBisDatum(""));
onClose();
};
useEffect(() => {
const loadZoomPlugin = async () => {
if (typeof window !== "undefined") {
const zoomPlugin = (await import("chartjs-plugin-zoom")).default;
if (!ChartJS.registry.plugins.get("zoom")) {
ChartJS.register(zoomPlugin);
}
}
};
loadZoomPlugin();
}, []);
// API-Request beim Klick auf "Daten laden" - memoized für useEffect dependency
const handleFetchData = useCallback(() => {
setIsLoading(true);
@@ -247,6 +208,67 @@ export const DetailModal = ({
}
}, [selectedKey, zeitraum, dispatch]);
// Reset Zeitraum auf DIA0 und Datumswerte wenn Modal geöffnet wird
useEffect(() => {
if (isOpen) {
setZeitraum("DIA0");
dispatch(setVonDatum(""));
dispatch(setBisDatum(""));
// Chart-Daten zurücksetzen beim Öffnen
setChartData({ datasets: [] });
}
}, [isOpen, setZeitraum, dispatch]);
// Periodische UI-Updates alle 2 Sekunden während Wartezeit
useEffect(() => {
if (isOpen && (!chartData.datasets || chartData.datasets.length === 0)) {
const interval = setInterval(() => {
setForceUpdate((prev) => prev + 1); // Force re-render für cursor-wait Update
}, 2000);
return () => clearInterval(interval);
}
}, [isOpen, chartData.datasets]);
// Automatisches "Daten laden" alle 2 Sekunden wenn keine Daten vorhanden
useEffect(() => {
if (isOpen && (!chartData.datasets || chartData.datasets.length === 0)) {
const interval = setInterval(() => {
console.log("Auto-clicking 'Daten laden' button...");
handleFetchData(); // Automatisch Daten laden
}, 2000);
return () => clearInterval(interval);
}
}, [isOpen, chartData.datasets, handleFetchData]);
const toggleFullScreen = () => {
dispatch(setFullScreen(!isFullScreen));
setTimeout(() => {
chartRef.current?.resize();
}, 50);
};
const handleClose = () => {
dispatch(setFullScreen(false));
dispatch(setVonDatum(""));
dispatch(setBisDatum(""));
onClose();
};
useEffect(() => {
const loadZoomPlugin = async () => {
if (typeof window !== "undefined") {
const zoomPlugin = (await import("chartjs-plugin-zoom")).default;
if (!ChartJS.registry.plugins.get("zoom")) {
ChartJS.register(zoomPlugin);
}
}
};
loadZoomPlugin();
}, []);
useEffect(() => {
if (chartRef.current && selectedKey) {
chartRef.current.options.plugins.title.text = `Verlauf ${selectedKey}`;
@@ -373,16 +395,19 @@ export const DetailModal = ({
if (!isOpen || !selectedKey) return null;
// Prüfen ob Chart Daten haben (für cursor-wait)
const hasChartData = chartData.datasets && chartData.datasets.length > 0;
return (
<div
className={`fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50 ${
isLoading ? "cursor-wait" : ""
!hasChartData ? "cursor-wait" : ""
}`}
>
<div
className={`bg-white p-6 rounded-xl overflow-auto shadow-2xl transition-all duration-300 ${
isFullScreen ? "w-[95vw] h-[90vh]" : "w-[50%] h-[60%]"
}`}
} ${!hasChartData ? "cursor-wait" : ""}`}
>
<div className="relative">
<h2 className="text-xl font-semibold">