fix: Eingabedaten im KUE-Modal persistent über window.__kueCache gespeichert

- Lokale Zustände unabhängig von Redux-Intervallen gemacht
- window.__kueCache speichert pro Slot die aktuellen Eingabedaten
- Rückschreiben in Redux erfolgt nur beim Speichern
- Remounts und Polling beeinflussen keine laufenden Eingaben mehr
This commit is contained in:
Ismail Ali
2025-04-29 23:50:46 +02:00
parent 29bccd5ff2
commit 3a3340da7a
3 changed files with 78 additions and 157 deletions

View File

@@ -1,28 +1,16 @@
"use client";
"use client"; // KueEinstellung.tsx komplett angepasst mit window.__kueCache zum Schutz vor Remount-Reset
import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import type { RootState } from "../../../../../redux/store";
import { setKueData } from "../../../../../redux/slices/kueDataSlice";
import handleSave, { OriginalValues } from "../handlers/handleSave";
import handleDisplayEinschalten from "../handlers/handleDisplayEinschalten";
import firmwareUpdate from "../handlers/firmwareUpdate";
import { useAdminAuth } from "../../../settingsPageComponents/hooks/useAdminAuth";
declare global {
interface Window {
win_kueID?: string[];
win_kueLimit1?: number[];
win_kueDelay1?: number[];
win_kueLimit2Low?: number[];
win_kueLimit2High?: number[];
win_kueLoopInterval?: number[];
win_memoryInterval?: number[];
}
}
interface Props {
slot: number;
showModal: boolean;
onClose?: () => void;
onModulNameChange?: (id: string) => void;
}
@@ -41,8 +29,8 @@ const memoryIntervalOptions = [
export default function KueEinstellung({
slot,
showModal,
onClose = () => {},
onModulNameChange = () => {},
}: Props) {
const dispatch = useDispatch();
const {
@@ -50,123 +38,75 @@ export default function KueEinstellung({
kueLimit1,
kueDelay1,
kueLimit2Low,
kueLimit2High,
kueLoopInterval,
memoryInterval,
} = useSelector((state: RootState) => state.kueDataSlice);
const { isAdminLoggedIn } = useAdminAuth(true);
// Lokale States
const [localName, setLocalName] = useState(kueID[slot] || "");
const [localLimit1, setLocalLimit1] = useState<number | "">(
kueLimit1[slot] ?? ""
);
const [localDelay1, setLocalDelay1] = useState<number | "">(
kueDelay1[slot] ?? ""
);
const [localLimit2Low, setLocalLimit2Low] = useState<number | "">(
kueLimit2Low[slot] ?? ""
);
const [localLoopInterval, setLocalLoopInterval] = useState<number | "">(
kueLoopInterval[slot] ?? ""
);
const [localMemoryInterval, setLocalMemoryInterval] = useState<number | "">(
memoryInterval[slot] ?? ""
);
const formCacheKey = `slot_${slot}`;
if (typeof window !== "undefined") {
window.__kueCache = window.__kueCache || {};
}
/*
fix: Eingabefelder beim Öffnen des KUE-Modal initialisieren und gegen Redux-Updates schützen
const cached =
typeof window !== "undefined" ? window.__kueCache?.[formCacheKey] : null;
- Lokale States beim ersten Öffnen des Modals gesetzt
- Redux-Änderungen während der Bearbeitung blockiert, um Fokusverlust zu verhindern
- Benutzerfreundlichkeit bei der Bearbeitung von Kabelüberwachungen verbessert
*/
//----------------------------------------------------------------
const [initialized, setInitialized] = useState(false);
const [editMode, setEditMode] = useState(false);
useEffect(() => {
setEditMode(true);
return () => {
setEditMode(false);
const [formData, setFormData] = useState(() => {
if (cached) return cached;
return {
name: kueID[slot] || "",
limit1: kueLimit1[slot]?.toString() ?? "",
delay1: kueDelay1[slot]?.toString() ?? "",
limit2Low: kueLimit2Low[slot]?.toString() ?? "",
loopInterval: kueLoopInterval[slot]?.toString() ?? "",
memoryInterval: memoryInterval[slot]?.toString() ?? "",
};
}, []);
});
useEffect(() => {
if (!initialized && editMode) {
setLocalName(kueID[slot] || "");
setLocalLimit1(kueLimit1[slot] ?? "");
setLocalDelay1(kueDelay1[slot] ?? "");
setLocalLimit2Low(kueLimit2Low[slot] ?? "");
setLocalLoopInterval(kueLoopInterval[slot] ?? "");
setLocalMemoryInterval(memoryInterval[slot] ?? "");
setInitialized(true);
const handleChange = (key: keyof typeof formData, value: string) => {
const updated = { ...formData, [key]: value };
setFormData(updated);
if (typeof window !== "undefined") {
window.__kueCache[formCacheKey] = updated;
}
}, [initialized, slot, editMode]);
//----------------------------------------------------------------
const handleSaveWrapper = () => {
setEditMode(false); // <--- Editmode deaktivieren
onClose(); // <--- Modal direkt schließen
const originalValues: OriginalValues = {
kueID: [...(window.win_kueID ?? [])],
isolationsgrenzwerte: [...(window.win_kueLimit1 ?? [])],
verzoegerung: [...(window.win_kueDelay1 ?? [])],
untereSchleifenGrenzwerte: [...(window.win_kueLimit2Low ?? [])],
obereSchleifenGrenzwerte: [...(window.win_kueLimit2High ?? [])],
schleifenintervall: [...(window.win_kueLoopInterval ?? [])],
speicherintervall: [...(window.win_memoryInterval ?? [])],
};
handleSave({
ids: [...kueID],
isolationsgrenzwerte: [...kueLimit1],
verzoegerung: [...kueDelay1],
untereSchleifenGrenzwerte: [...kueLimit2Low],
obereSchleifenGrenzwerte: [...kueLimit2High],
schleifenintervall: [...kueLoopInterval],
speicherintervall: [...memoryInterval],
originalValues,
slot,
dispatch,
onModulNameChange,
onClose,
});
};
const updateRedux = () => {
if (!editMode) return;
const handleSaveWrapper = () => {
const updatedKueID = [...kueID];
updatedKueID[slot] = formData.name;
const updatedLimit1 = [...kueLimit1];
updatedLimit1[slot] = Number(formData.limit1);
const updatedDelay1 = [...kueDelay1];
updatedDelay1[slot] = Number(formData.delay1);
const updatedLimit2Low = [...kueLimit2Low];
updatedLimit2Low[slot] = Number(formData.limit2Low);
const updatedLoopInterval = [...kueLoopInterval];
updatedLoopInterval[slot] = Number(formData.loopInterval);
const updatedMemoryInterval = [...memoryInterval];
updatedMemoryInterval[slot] = Number(formData.memoryInterval);
dispatch(
setKueData({
kueID: [...kueID.slice(0, slot), localName, ...kueID.slice(slot + 1)],
kueLimit1: [
...kueLimit1.slice(0, slot),
Number(localLimit1),
...kueLimit1.slice(slot + 1),
],
kueDelay1: [
...kueDelay1.slice(0, slot),
Number(localDelay1),
...kueDelay1.slice(slot + 1),
],
kueLimit2Low: [
...kueLimit2Low.slice(0, slot),
Number(localLimit2Low),
...kueLimit2Low.slice(slot + 1),
],
kueLoopInterval: [
...kueLoopInterval.slice(0, slot),
Number(localLoopInterval),
...kueLoopInterval.slice(slot + 1),
],
memoryInterval: [
...memoryInterval.slice(0, slot),
Number(localMemoryInterval),
...memoryInterval.slice(slot + 1),
],
kueID: updatedKueID,
kueLimit1: updatedLimit1,
kueDelay1: updatedDelay1,
kueLimit2Low: updatedLimit2Low,
kueLoopInterval: updatedLoopInterval,
memoryInterval: updatedMemoryInterval,
})
);
if (typeof window !== "undefined") {
delete window.__kueCache[formCacheKey];
}
onClose();
};
return (
@@ -176,9 +116,8 @@ fix: Eingabefelder beim Öffnen des KUE-Modal initialisieren und gegen Redux-Upd
<input
type="text"
className="w-full border rounded p-1 text-sm"
value={localName}
onChange={(e) => setLocalName(e.target.value)}
onBlur={updateRedux}
value={formData.name}
onChange={(e) => handleChange("name", e.target.value)}
/>
</div>
@@ -198,13 +137,8 @@ fix: Eingabefelder beim Öffnen des KUE-Modal initialisieren und gegen Redux-Upd
type="number"
step="0.1"
className="w-[6rem] border rounded p-1"
value={localLimit1}
onChange={(e) =>
setLocalLimit1(
e.target.value ? parseFloat(e.target.value) : ""
)
}
onBlur={updateRedux}
value={formData.limit1}
onChange={(e) => handleChange("limit1", e.target.value)}
/>
</td>
<td className="border p-2 text-center">
@@ -212,13 +146,8 @@ fix: Eingabefelder beim Öffnen des KUE-Modal initialisieren und gegen Redux-Upd
type="number"
step="0.1"
className="w-[6rem] border rounded p-1"
value={localDelay1}
onChange={(e) =>
setLocalDelay1(
e.target.value ? parseFloat(e.target.value) : ""
)
}
onBlur={updateRedux}
value={formData.delay1}
onChange={(e) => handleChange("delay1", e.target.value)}
/>
</td>
</tr>
@@ -242,13 +171,8 @@ fix: Eingabefelder beim Öffnen des KUE-Modal initialisieren und gegen Redux-Upd
type="number"
step="0.1"
className="w-[6rem] border rounded p-1"
value={localLimit2Low}
onChange={(e) =>
setLocalLimit2Low(
e.target.value ? parseFloat(e.target.value) : ""
)
}
onBlur={updateRedux}
value={formData.limit2Low}
onChange={(e) => handleChange("limit2Low", e.target.value)}
/>
</td>
<td className="border p-2 text-center">
@@ -256,13 +180,8 @@ fix: Eingabefelder beim Öffnen des KUE-Modal initialisieren und gegen Redux-Upd
type="number"
step="0.1"
className="w-[6rem] border rounded p-1"
value={localLoopInterval}
onChange={(e) =>
setLocalLoopInterval(
e.target.value ? parseFloat(e.target.value) : ""
)
}
onBlur={updateRedux}
value={formData.loopInterval}
onChange={(e) => handleChange("loopInterval", e.target.value)}
/>
</td>
</tr>
@@ -273,11 +192,8 @@ fix: Eingabefelder beim Öffnen des KUE-Modal initialisieren und gegen Redux-Upd
<label className="font-bold block mb-1">Speicherintervall</label>
<select
className="w-full border rounded p-1 text-sm"
value={localMemoryInterval}
onChange={(e) =>
setLocalMemoryInterval(parseInt(e.target.value, 10))
}
onBlur={updateRedux}
value={formData.memoryInterval}
onChange={(e) => handleChange("memoryInterval", e.target.value)}
>
{memoryIntervalOptions.map((opt) => (
<option key={opt.value} value={opt.value}>

View File

@@ -27,6 +27,11 @@ export default function KueModal({ showModal, onClose, slot }: KueModalProps) {
(window as any).__lastKueTab = activeTab;
}
}, [activeTab]);
useEffect(() => {
if (typeof window !== "undefined") {
window.kabelModalOpen = showModal;
}
}, [showModal]);
return (
<ReactModal
@@ -94,15 +99,15 @@ export default function KueModal({ showModal, onClose, slot }: KueModalProps) {
</div>
<div className="p-4 bg-white rounded-b-md max-h-[75vh] overflow-y-auto">
{activeTab === "kue" && (
<div style={{ display: activeTab === "kue" ? "block" : "none" }}>
<KueEinstellung
slot={slot}
onModulNameChange={(id) => {
console.log("Modulname geändert:", id);
}}
showModal={showModal} // ← hier übergeben
onModulNameChange={(id) => console.log("Modulname geändert:", id)}
onClose={onClose}
/>
)}
</div>
{activeTab === "tdr" && <TdrEinstellung slot={slot} />}
{activeTab === "knoten" && <Knotenpunkte slot={slot} />}
</div>

View File

@@ -6,5 +6,5 @@
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
*/
const webVersion = "1.6.315";
const webVersion = "1.6.316";
export default webVersion;