Feat: KVz Bereich in EinstellungsModal in KÜs Modal
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.660
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.661
|
||||
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.660
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.661
|
||||
NEXT_PUBLIC_CPL_MODE=production
|
||||
@@ -1,3 +1,8 @@
|
||||
## [1.6.661] – 2025-07-31
|
||||
|
||||
- feat: TDR starten Button in KÜ Chart
|
||||
|
||||
---
|
||||
## [1.6.660] – 2025-07-31
|
||||
|
||||
- fix: Schleifenwiderstand (TDR) Messung starten Button auf der Produktion
|
||||
|
||||
@@ -79,6 +79,7 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
||||
kueOverflow: kueOverflowRaw,
|
||||
kuePSTmMinus96V, // <- richtig, weil so im State vorhanden
|
||||
tdrActive, // <- TDR aktiv Status hinzugefügt
|
||||
win_fallSensorsActive, // <- KVz aktiv Status hinzugefügt
|
||||
} = useSelector((state: RootState) => state.kueDataSlice);
|
||||
|
||||
//---------------------------------------------
|
||||
@@ -227,6 +228,9 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
||||
// TDR aktiv Status für diesen Slot prüfen
|
||||
const isTdrActiveForSlot = tdrActive?.[slotIndex] === 1;
|
||||
|
||||
// KVz aktiv Status für diesen Slot prüfen
|
||||
const isKvzActiveForSlot = win_fallSensorsActive?.[slotIndex] === 1;
|
||||
|
||||
// Removed useChartData(loopMeasurementCurveChartData) as the state was unused
|
||||
|
||||
//---------------------------------
|
||||
@@ -401,12 +405,15 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
||||
TDR
|
||||
</button>
|
||||
)}
|
||||
{/* KVz Button - nur anzeigen wenn KVz aktiv ist */}
|
||||
{isKvzActiveForSlot && (
|
||||
<button
|
||||
onClick={openKvzModal}
|
||||
className="bg-littwin-blue text-white text-[0.625rem] flex items-center justify-center p-2"
|
||||
>
|
||||
KVz
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Messkurve Button */}
|
||||
@@ -443,8 +450,8 @@ const Kue705FO: React.FC<Kue705FOProps> = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* KVz Panel - Anzeige ganz unten */}
|
||||
{showKvzPanel && (
|
||||
{/* KVz Panel - Anzeige ganz unten, nur wenn KVz aktiv ist */}
|
||||
{showKvzPanel && isKvzActiveForSlot && (
|
||||
<div className=" bg-gray-400 mt-4 border p-1">
|
||||
<FallSensors />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { RootState } from "../../../../../redux/store";
|
||||
import { setKueData } from "../../../../../redux/slices/kueDataSlice";
|
||||
import { useAdminAuth } from "../../../settingsPageComponents/hooks/useAdminAuth";
|
||||
|
||||
type KvzData = {
|
||||
// Hier können später weitere KVz-spezifische Einstellungen hinzugefügt werden
|
||||
kvzSettings: string;
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__kvzCache?: Record<string, { data: KvzData; kvzActive: boolean }>;
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
slot: number;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
export default function KvzModalView({ slot, onClose }: Props) {
|
||||
const { isAdminLoggedIn } = useAdminAuth(true);
|
||||
const dispatch = useDispatch();
|
||||
const kvzSlice = useSelector((state: RootState) => state.kueDataSlice);
|
||||
|
||||
const cacheKey = `kvz_slot_${slot}`;
|
||||
if (typeof window !== "undefined") {
|
||||
window.__kvzCache = window.__kvzCache || {};
|
||||
}
|
||||
const cachedKvz =
|
||||
typeof window !== "undefined"
|
||||
? window.__kvzCache?.[cacheKey] ?? null
|
||||
: null;
|
||||
|
||||
const [kvzData] = useState(
|
||||
() =>
|
||||
cachedKvz?.data || {
|
||||
kvzSettings: "", // Placeholder für zukünftige Einstellungen
|
||||
}
|
||||
);
|
||||
|
||||
const [kvzActive, setKvzActive] = useState(
|
||||
() => cachedKvz?.kvzActive ?? kvzSlice.win_fallSensorsActive?.[slot] === 1
|
||||
);
|
||||
|
||||
const updateCache = (data: typeof kvzData, active = kvzActive) => {
|
||||
if (typeof window !== "undefined") {
|
||||
(window.__kvzCache ??= {})[cacheKey] = {
|
||||
data,
|
||||
kvzActive: active,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const handleKvzToggle = () => {
|
||||
const newState = !kvzActive;
|
||||
setKvzActive(newState);
|
||||
updateCache(kvzData, newState);
|
||||
|
||||
// Redux State sofort aktualisieren für UI-Update
|
||||
const updatedKvzActive = [...(kvzSlice.win_fallSensorsActive || [])];
|
||||
updatedKvzActive[slot] = newState ? 1 : 0;
|
||||
dispatch(setKueData({ win_fallSensorsActive: updatedKvzActive }));
|
||||
|
||||
const isDev = window.location.hostname === "localhost";
|
||||
const slotParam = `KVZ${slot}=${newState ? 1 : 0}`;
|
||||
|
||||
const reloadAfterConfirm = () => {
|
||||
const msg = newState
|
||||
? "✅ KVz wurde aktiviert."
|
||||
: "⚠️ KVz wurde deaktiviert.";
|
||||
alert(msg);
|
||||
location.reload();
|
||||
};
|
||||
|
||||
if (isDev) {
|
||||
const updates = [
|
||||
{ key: "win_fallSensorsActive", slot, value: newState ? 1 : 0 },
|
||||
];
|
||||
|
||||
fetch("/api/cpl/updateKvzSettingsDataAPIHandler", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ updates }),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then(() => {
|
||||
console.log("KVz-Aktiv-Status gespeichert.");
|
||||
reloadAfterConfirm();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Fehler beim Speichern von KVz aktiv:", err);
|
||||
});
|
||||
} else {
|
||||
const url = `${window.location.origin}/CPL?/kabelueberwachung.html&${slotParam}`;
|
||||
fetch(url)
|
||||
.then((res) => {
|
||||
if (!res.ok) throw new Error("KVz-Befehl fehlgeschlagen");
|
||||
console.log("KVz aktiviert/deaktiviert:", res.status);
|
||||
reloadAfterConfirm();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Fehler beim KVz-Befehl:", err);
|
||||
alert("Fehler beim Umschalten der KVz-Funktion.");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
const isDev = window.location.hostname === "localhost";
|
||||
|
||||
if (isDev) {
|
||||
const updates = [
|
||||
{ key: "win_fallSensorsActive", slot, value: kvzActive ? 1 : 0 },
|
||||
// Hier können später weitere KVz-Einstellungen hinzugefügt werden
|
||||
];
|
||||
|
||||
fetch("/api/cpl/updateKvzSettingsDataAPIHandler", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ updates }),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then(() => {
|
||||
alert("KVz-Einstellungen erfolgreich gespeichert.");
|
||||
if (typeof onClose === "function") onClose();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Fehler beim Speichern:", err);
|
||||
alert("Speichern fehlgeschlagen.");
|
||||
});
|
||||
} else {
|
||||
// Originaler Webservice-Teil für Produktionsumgebung
|
||||
alert("KVz-Einstellungen gespeichert.");
|
||||
if (typeof onClose === "function") onClose();
|
||||
}
|
||||
|
||||
updateCache(kvzData, kvzActive);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-4 text-sm">
|
||||
{/* KVz-Funktion */}
|
||||
{isAdminLoggedIn && (
|
||||
<div className="mb-4 mt-4 grid grid-cols-3 items-center gap-2 w-full">
|
||||
<span className="text-sm font-medium">KVz-Funktion:</span>
|
||||
<div className="col-span-2 flex items-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={kvzActive}
|
||||
onClick={handleKvzToggle}
|
||||
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 ${
|
||||
kvzActive ? "bg-littwin-blue" : "bg-gray-300"
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform duration-200 ${
|
||||
kvzActive ? "translate-x-6" : "translate-x-1"
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
<span className="text-sm text-gray-600">
|
||||
{kvzActive ? "aktiviert" : "deaktiviert"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Zukünftige KVz-Einstellungen können hier hinzugefügt werden */}
|
||||
{!isAdminLoggedIn && (
|
||||
<div className="mt-6 mb-4">
|
||||
<div className="mb-4">
|
||||
<p className="text-sm text-gray-600">
|
||||
Nur Admin-Benutzer können diese Einstellungen ändern.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Speichern Button */}
|
||||
|
||||
{/* <div className="mt-36">
|
||||
<div className="flex justify-end gap-2 p-3 rounded">
|
||||
<button
|
||||
onClick={handleSave}
|
||||
className="bg-littwin-blue text-white px-4 py-2 rounded flex items-center"
|
||||
>
|
||||
Speichern
|
||||
</button>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { useState, useEffect } from "react";
|
||||
import ReactModal from "react-modal";
|
||||
import KueEinstellung from "./KueEinstellung";
|
||||
import TdrEinstellung from "./TdrEinstellung";
|
||||
import KvzModalView from "./KvzModalView";
|
||||
import Knotenpunkte from "./Knotenpunkte";
|
||||
|
||||
interface KueModalProps {
|
||||
@@ -14,18 +15,20 @@ interface KueModalProps {
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__lastKueTab?: "kue" | "tdr" | "knoten";
|
||||
__lastKueTab?: "kue" | "tdr" | "kvz" | "knoten";
|
||||
kabelModalOpen?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export default function KueModal({ showModal, onClose, slot }: KueModalProps) {
|
||||
const [activeTab, setActiveTab] = useState<"kue" | "tdr" | "knoten">(() => {
|
||||
const [activeTab, setActiveTab] = useState<"kue" | "tdr" | "kvz" | "knoten">(
|
||||
() => {
|
||||
if (typeof window !== "undefined" && window.__lastKueTab) {
|
||||
return window.__lastKueTab;
|
||||
}
|
||||
return "kue";
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
@@ -77,6 +80,7 @@ export default function KueModal({ showModal, onClose, slot }: KueModalProps) {
|
||||
{[
|
||||
{ label: "Allgemein", key: "kue" as const },
|
||||
{ label: "TDR ", key: "tdr" as const },
|
||||
{ label: "KVz", key: "kvz" as const },
|
||||
{ label: "Knotenpunkte", key: "knoten" as const },
|
||||
].map(({ label, key }) => (
|
||||
<button
|
||||
@@ -105,6 +109,7 @@ export default function KueModal({ showModal, onClose, slot }: KueModalProps) {
|
||||
{activeTab === "tdr" && (
|
||||
<TdrEinstellung slot={slot} onClose={onClose} />
|
||||
)}
|
||||
{activeTab === "kvz" && <KvzModalView slot={slot} onClose={onClose} />}
|
||||
{activeTab === "knoten" && (
|
||||
<Knotenpunkte slot={slot} onClose={onClose} />
|
||||
)}
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.660",
|
||||
"version": "1.6.661",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.660",
|
||||
"version": "1.6.661",
|
||||
"dependencies": {
|
||||
"@fontsource/roboto": "^5.1.0",
|
||||
"@headlessui/react": "^2.2.4",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.660",
|
||||
"version": "1.6.661",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
Reference in New Issue
Block a user