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:
@@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
|
||||
NEXT_PUBLIC_EXPORT_STATIC=false
|
||||
NEXT_PUBLIC_USE_CGI=false
|
||||
# App-Versionsnummer
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.679
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.680
|
||||
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_USE_CGI=true
|
||||
# App-Versionsnummer
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.679
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.680
|
||||
NEXT_PUBLIC_CPL_MODE=production
|
||||
@@ -1,3 +1,8 @@
|
||||
## [1.6.680] – 2025-08-01
|
||||
|
||||
- fix: System ->Detailansicht -> Modal
|
||||
|
||||
---
|
||||
## [1.6.679] – 2025-08-01
|
||||
|
||||
- fix: Chart System
|
||||
|
||||
@@ -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">
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.679",
|
||||
"version": "1.6.680",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.679",
|
||||
"version": "1.6.680",
|
||||
"dependencies": {
|
||||
"@fontsource/roboto": "^5.1.0",
|
||||
"@headlessui/react": "^2.2.4",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.679",
|
||||
"version": "1.6.680",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
Reference in New Issue
Block a user