diff --git a/.env.development b/.env.development index 15b2f38..7febb59 100644 --- a/.env.development +++ b/.env.development @@ -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.513 +NEXT_PUBLIC_APP_VERSION=1.6.515 NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) diff --git a/.env.production b/.env.production index 7671d73..10f6e26 100644 --- a/.env.production +++ b/.env.production @@ -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.513 +NEXT_PUBLIC_APP_VERSION=1.6.515 NEXT_PUBLIC_CPL_MODE=production \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c32858..4a0cf1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,25 @@ +## [1.6.515] – 2025-07-02 + +- feat: Firmwareupdate für alle KÜ-Module mit Fortschrittsanzeige und Abschlussmeldung + +- ProgressModal-Komponente implementiert, die während des Updates angezeigt wird +- Firmwareupdate dauert 5 Minuten (Mock-Simulation) +- Nach Abschluss erscheint automatisch ein Toast-Hinweis +- Verbesserte Benutzerführung durch blockierendes Modal während Update +- Logging in kueFirmwareUpdateLog.json integriert (Mock) + +--- +## [1.6.514] – 2025-07-02 + +- feat: Firmwareupdate für alle KÜ-Module mit Fortschrittsanzeige und Abschlussmeldung + +- ProgressModal-Komponente implementiert, die während des Updates angezeigt wird +- Firmwareupdate dauert 5 Minuten (Mock-Simulation) +- Nach Abschluss erscheint automatisch ein Toast-Hinweis +- Verbesserte Benutzerführung durch blockierendes Modal während Update +- Logging in kueFirmwareUpdateLog.json integriert (Mock) + +--- ## [1.6.513] – 2025-07-01 - feat: alle KÜs Firmware update confirm diff --git a/components/common/ConfirmModal.tsx b/components/common/ConfirmModal.tsx new file mode 100644 index 0000000..6fa56c9 --- /dev/null +++ b/components/common/ConfirmModal.tsx @@ -0,0 +1,43 @@ +// components/common/ConfirmModal.tsx +import React from "react"; + +interface ConfirmModalProps { + open: boolean; + title?: string; + message: string; + onConfirm: () => void; + onCancel: () => void; +} + +export default function ConfirmModal({ + open, + title, + message, + onConfirm, + onCancel, +}: ConfirmModalProps) { + if (!open) return null; + + return ( +
+
+ {title &&

{title}

} +

{message}

+
+ + +
+
+
+ ); +} diff --git a/components/main/kabelueberwachung/kue705FO/handlers/firmwareUpdate.ts b/components/main/kabelueberwachung/kue705FO/handlers/firmwareUpdate.ts index b922304..2aee2e8 100644 --- a/components/main/kabelueberwachung/kue705FO/handlers/firmwareUpdate.ts +++ b/components/main/kabelueberwachung/kue705FO/handlers/firmwareUpdate.ts @@ -1,24 +1,32 @@ -// /komponents/main/kabelueberwachung/kue705FO/handlers/firmwareUpdate.ts -const firmwareUpdate = (slot: number) => { +// @/components/main/kabelueberwachung/kue705FO/handlers/firmwareUpdate.ts +export default async function firmwareUpdate( + slot: number +): Promise<{ message: string }> { const isDev = typeof window !== "undefined" && window.location.hostname === "localhost"; const url = isDev ? `${window.location.origin}/api/cpl/kueSingleModuleUpdateMock?slot=${ slot + 1 }` - : `${window.location.origin}/CPL?/kabelueberwachung.html&KSU${slot}=1`; + : `${window.location.origin}/CPL?Service/ae.ACP&KSU${slot}=1`; - fetch(url, { method: "GET" }) - .then((response) => response.json()) - .then((data) => { - alert( - data.message || `Update an Slot ${slot + 1} erfolgreich gestartet!` - ); - }) - .catch((error) => { - console.error("Fehler:", error); - alert("Fehler beim Update!"); - }); -}; + try { + const response = await fetch(url, { method: "GET" }); -export default firmwareUpdate; + if (!response.ok) { + throw new Error(`Fehler: Status ${response.status}`); + } + + const data = await response.json(); + + //alert(data.message || `Update an Slot ${slot + 1} erfolgreich gestartet!`); + const message = + data.message || `Update an Slot ${slot + 1} erfolgreich gestartet!`; + console.log(message); + return { message }; + } catch (error) { + console.error("Fehler:", error); + //alert("Fehler beim Update!"); + return { message: "Fehler beim Update!" }; + } +} diff --git a/components/main/kabelueberwachung/kue705FO/modals/KueEinstellung.tsx b/components/main/kabelueberwachung/kue705FO/modals/KueEinstellung.tsx index b5a03f2..9614604 100644 --- a/components/main/kabelueberwachung/kue705FO/modals/KueEinstellung.tsx +++ b/components/main/kabelueberwachung/kue705FO/modals/KueEinstellung.tsx @@ -1,16 +1,20 @@ "use client"; - -import { useState } from "react"; +// components/main/kabelueberwachung/kue705FO/modals/KueEinstellung.tsx +import { useState, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import type { RootState } from "../../../../../redux/store"; import handleSave from "../handlers/handleSave"; import handleDisplayEinschalten from "../handlers/handleDisplayEinschalten"; import firmwareUpdate from "../handlers/firmwareUpdate"; import { useAdminAuth } from "../../../settingsPageComponents/hooks/useAdminAuth"; +import ProgressModal from "@/components/main/settingsPageComponents/modals/ProgressModal"; +import { toast } from "react-toastify"; +import ConfirmModal from "@/components/common/ConfirmModal"; interface Props { slot: number; showModal: boolean; + isAdminLoggedIn: boolean; // NEU onClose?: () => void; onModulNameChange?: (id: string) => void; } @@ -29,7 +33,8 @@ const memoryIntervalOptions = [ export default function KueEinstellung({ slot, - + showModal, + isAdminLoggedIn, onClose = () => {}, onModulNameChange, }: Props) { @@ -43,18 +48,15 @@ export default function KueEinstellung({ kueLoopInterval, memoryInterval, } = useSelector((state: RootState) => state.kueDataSlice); + const [showConfirmModal, setShowConfirmModal] = useState(false); - const { isAdminLoggedIn } = useAdminAuth(true); - - const formCacheKey = `slot_${slot}`; - if (typeof window !== "undefined") { - window.__kueCache = window.__kueCache || {}; - } - const cached = - typeof window !== "undefined" ? window.__kueCache?.[formCacheKey] : null; - + const [isUpdating, setIsUpdating] = useState(false); + const [progress, setProgress] = useState(0); const [formData, setFormData] = useState(() => { - if (cached) return cached; + if (typeof window !== "undefined") { + const cache = window.__kueCache?.[`slot_${slot}`]; + if (cache) return cache; + } return { kueID: kueID[slot] || "", kueName: kueName[slot] || "", @@ -70,17 +72,12 @@ export default function KueEinstellung({ const updated = { ...formData, [key]: value }; setFormData(updated); if (typeof window !== "undefined") { - window.__kueCache![formCacheKey] = updated; + window.__kueCache = window.__kueCache || {}; + window.__kueCache[`slot_${slot}`] = updated; } }; const handleSaveWrapper = async () => { - const updatedKueID = [...kueID]; - //updatedKueID[slot] = formData.kueID; - /* if (Object.isFrozen(kueID)) { - console.warn("kueID ist readonly!"); - } - */ const updatedKueName = [...kueName]; updatedKueName[slot] = formData.kueName; @@ -100,7 +97,7 @@ export default function KueEinstellung({ updatedMemoryInterval[slot] = Number(formData.memoryInterval); const newData = { - kueID: updatedKueID[slot], + kueID: kueID[slot], kueName: updatedKueName[slot], limit1: updatedLimit1[slot].toString(), delay1: updatedDelay1[slot].toString(), @@ -108,13 +105,11 @@ export default function KueEinstellung({ loopInterval: updatedLoopInterval[slot].toString(), memoryInterval: updatedMemoryInterval[slot].toString(), }; - setFormData(newData); if (typeof window !== "undefined") { window.__kueCache![`slot_${slot}`] = newData; } - // 🔧 handleSave aufrufen mit allen Daten await handleSave({ slot, ids: kueID, @@ -122,7 +117,7 @@ export default function KueEinstellung({ isolationsgrenzwerte: updatedLimit1, verzoegerung: updatedDelay1, untereSchleifenGrenzwerte: updatedLimit2Low, - obereSchleifenGrenzwerte: updatedLimit2Low, // ggf. anpassen, falls du später High-Werte brauchst + obereSchleifenGrenzwerte: updatedLimit2Low, schleifenintervall: updatedLoopInterval, speicherintervall: updatedMemoryInterval, originalValues: { @@ -245,20 +240,62 @@ export default function KueEinstellung({
{isAdminLoggedIn && ( - + + )} + {showConfirmModal && ( + setShowConfirmModal(false)} + onConfirm={async () => { + setShowConfirmModal(false); + toast.info("Firmware-Update gestartet. Bitte warten..."); + setIsUpdating(true); + setProgress(0); + + const totalDuration = 5000; + const intervalMs = 50; + const steps = totalDuration / intervalMs; + let currentStep = 0; + + const interval = setInterval(() => { + currentStep++; + const newProgress = Math.min((currentStep / steps) * 100, 100); + setProgress(newProgress); + + if (currentStep >= steps) { + clearInterval(interval); + setProgress(100); + setTimeout(() => { + toast.success( + "✅ Firmwareupdate erfolgreich abgeschlossen." + ); + setIsUpdating(false); + }, 300); + } + }, intervalMs); + + try { + await firmwareUpdate(slot); + } catch (err) { + console.error("Firmware-Update-Fehler:", err); + clearInterval(interval); + toast.error("❌ Fehler beim Firmwareupdate"); + setIsUpdating(false); } }} - className="bg-littwin-blue text-white px-4 py-2 rounded flex items-center" - > - Firmware Update - + /> + )} + {isUpdating && ( + )}