Kableüberwachung Modal und digitale Eingänge Modal

This commit is contained in:
ISA
2025-05-06 14:31:08 +02:00
parent 9c44fa0a49
commit 36f791237c
9 changed files with 81 additions and 79 deletions

View File

@@ -33,6 +33,15 @@ export default function AnalogeEingaengeTable({
return (
<div className="w-full">
<h2 className="text-sm laptop:text-xs font-bold mb-3 flex items-center">
<img
src="/images/analogeEingaengeIcon.svg"
alt="Analoge Eingänge"
className="w-6 h-6 mr-2 text-littwin-blue"
/>
Messwerteingänge
</h2>
<div className="bg-white shadow-lg rounded-lg p-4 border border-gray-200">
<div className="overflow-x-auto">
<table className="w-full border-collapse border border-gray-300 text-sm md:text-base">

View File

@@ -64,7 +64,7 @@ export default function DigitalInputs({ openInputModal, inputRange }: Props) {
</span>
<div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 w-max bg-gray-400 text-xs laptop:text-[10px] text-white rounded opacity-0 group-hover:opacity-100 transition p-1 z-10 xl:text-sm ">
Eingang Aus
Eingang Ein
</div>
</div>
) : (
@@ -73,7 +73,7 @@ export default function DigitalInputs({ openInputModal, inputRange }: Props) {
</span>
<div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 w-max bg-gray-400 text-xs laptop:text-[10px] text-white rounded opacity-0 group-hover:opacity-100 transition p-1 z-10">
Eingang Ein
Eingang Aus
</div>
</div>
)}

View File

@@ -23,6 +23,7 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
const [filterzeit, setFilterzeit] = useState(0);
const [gewichtung, setGewichtung] = useState(0);
const [zaehlerAktiv, setZaehlerAktiv] = useState(false);
const [eingangOffline, setEingangOffline] = useState(false);
useEffect(() => {
if (reduxInput && isInitialLoad) {
@@ -31,6 +32,7 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
setFilterzeit(reduxInput.filterzeit);
setGewichtung(reduxInput.gewichtung);
setZaehlerAktiv(reduxInput.zaehlerAktiv);
setEingangOffline(reduxInput.eingangOffline);
setIsInitialLoad(false);
}
}, [reduxInput, isInitialLoad]);
@@ -76,6 +78,10 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
await sendCgiUpdate(`DEZ${id}=${zaehlerAktiv ? 1 : 0}`);
hasChange = true;
}
if (eingangOffline !== reduxInput.eingangOffline) {
await sendCgiUpdate(`DEO${id}=${eingangOffline ? 1 : 0}`);
hasChange = true;
}
if (!hasChange) {
alert("⚠️ Keine Änderungen erkannt.");
return;
@@ -141,30 +147,13 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
return (
<div className="fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 flex justify-center items-center z-50">
<div className="bg-white rounded-lg shadow-lg p-6 w-1/2 max-w-lg">
<h2 className="text-xl font-semibold text-blue-500 mb-4 border-b pb-2">
Parameter für Eingang {selectedInput.id}
<h2 className="text-base font-bold mb-4 border-b pb-2">
Einstellungen Eingang {selectedInput.id}
</h2>
<div className="grid grid-cols-2 gap-x-4 gap-y-3">
<div>
<strong>Zustand:</strong>
</div>
<div className="flex items-center gap-3 text-xl font-semibold col-span-1">
{reduxInput.status ? (
<>
<span className="text-red-500 text-2xl"></span>
<span className="text-red-600">Aus</span>
</>
) : (
<>
<span className="text-green-500 text-2xl"></span>
<span className="text-green-600">Ein</span>
</>
)}
</div>
<div>
<strong>Name:</strong>
<span className="font-normal">Bezeichnung:</span>
</div>
<div>
<input
@@ -177,17 +166,16 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
</div>
<div>
<strong>Invertierung:</strong>
<span className="font-normal">Invertierung:</span>
</div>
<div className="flex items-center gap-2">
<span>{invertiert ? "Ein" : "Aus"}</span>
<button
type="button"
role="switch"
aria-checked={invertiert}
onClick={() => setInvertiert(!invertiert)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 ${
invertiert ? "bg-green-500" : "bg-gray-300"
invertiert ? "bg-littwin-blue" : "bg-gray-300"
}`}
>
<span
@@ -196,17 +184,11 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
}`}
/>
</button>
<span>{invertiert ? "Ein" : "Aus"}</span>
</div>
{/* Zählerstand ausblenden */}
{/*
<div>
<strong>Zählerstand:</strong>
</div>
<div>{reduxInput.counter}</div>
*/}
<div>
<strong>Filterzeit:</strong>
<span className="font-normal">Filterzeit:</span>
</div>
<div className="relative">
<input
@@ -220,16 +202,17 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
setFilterzeit(val);
}
}}
className="border border-gray-300 rounded px-2 py-1 pr-10 w-full"
className="border border-gray-300 rounded px-2 py-1 pr-10 w-full text-right"
title="Maximal 2000 ms erlaubt"
/>
<span className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm">
ms
</span>
</div>
<div>
<strong>Gewichtung:</strong>
<span className="font-normal">Gewichtung:</span>
</div>
<div>
<input
@@ -243,57 +226,45 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
setGewichtung(val);
}
}}
className="border border-gray-300 rounded px-2 py-1 w-full"
className="border border-gray-300 rounded px-2 py-1 w-full text-right"
title="Maximal 1000 erlaubt"
/>
</div>
{/* Zähler aktiv ausblenden */}
{/*
<div>
<strong>Zähler aktiv:</strong>
<div className="relative group inline-block">
<span className="font-normal">Out of Service:</span>
</div>
<div className="flex items-center gap-2">
<span>{zaehlerAktiv ? "Ja" : "Nein"}</span>
<button
type="button"
role="switch"
aria-checked={zaehlerAktiv}
onClick={() => setZaehlerAktiv(!zaehlerAktiv)}
aria-checked={eingangOffline}
onClick={() => setEingangOffline(!eingangOffline)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 ${
zaehlerAktiv ? "bg-green-500" : "bg-gray-300"
eingangOffline ? "bg-littwin-blue" : "bg-gray-300"
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform duration-200 ${
zaehlerAktiv ? "translate-x-6" : "translate-x-1"
eingangOffline ? "translate-x-6" : "translate-x-1"
}`}
/>
</button>
<span>{eingangOffline ? "Ein" : "Aus"}</span>
</div>
*/}
<div className="relative group inline-block">
<strong>OOS:</strong>
<span className="absolute top-full left-1/2 -translate-x-1/2 mt-1 px-2 py-1 text-xs text-white bg-gray-700 rounded opacity-0 group-hover:opacity-100 transition-opacity">
Out of Service
</span>
</div>
<div>{reduxInput.eingangOffline ? "aus" : "ein"}</div>
</div>
<div className="mt-6 flex justify-end gap-2">
<button
onClick={handleClose}
className="px-4 py-2 bg-gray-300 hover:bg-gray-400 text-black rounded-lg transition"
className="bg-littwin-blue text-white px-4 py-2 rounded flex items-center"
>
Schließen
</button>
<button
onClick={handleSpeichern}
className="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition"
className="bg-littwin-blue text-white px-4 py-2 rounded flex items-center"
>
Speichern
</button>

View File

@@ -164,26 +164,30 @@ export default function KueEinstellung({
<h3 className="font-bold mb-2">Isolationsmessung</h3>
<div className="mb-4 grid grid-cols-3 items-center gap-2 w-full">
<label className="w-48 ">Grenzwert:</label>
<div>
<div className="relative w-36">
<input
type="number"
className="w-24 border rounded p-1 mr-2 text-right"
className="border rounded px-2 py-1 pr-20 w-full text-right"
value={formData.limit1}
onChange={(e) => handleChange("limit1", e.target.value)}
/>
<span>MOhm</span>
<span className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm">
MOhm
</span>
</div>
</div>
<div className="mb-4 grid grid-cols-3 items-center gap-2 w-full">
<label className="w-48 ">Verzögerung:</label>
<div>
<div className="relative w-36">
<input
type="number"
className="w-24 border rounded p-1 mr-2 text-right"
className="border rounded px-2 py-1 pr-20 w-full text-right"
value={formData.delay1}
onChange={(e) => handleChange("delay1", e.target.value)}
/>
<span>Sekunden</span>
<span className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm">
Sekunden
</span>
</div>
</div>
</div>
@@ -192,26 +196,30 @@ export default function KueEinstellung({
<h3 className="font-bold mb-2">Schleifenmessung</h3>
<div className="mb-4 grid grid-cols-3 items-center gap-2 w-full">
<label className="w-48 ">Grenzwert:</label>
<div>
<div className="relative w-36">
<input
type="number"
className="w-24 border rounded p-1 mr-2 text-right"
className="border rounded px-2 py-1 pr-20 w-full text-right"
value={formData.limit2Low}
onChange={(e) => handleChange("limit2Low", e.target.value)}
/>
<span>kOhm</span>
<span className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm">
kOhm
</span>
</div>
</div>
<div className="mb-4 grid grid-cols-3 items-center gap-2 w-full">
<label className="w-48 ">Schleifenmessintervall:</label>
<div>
<div className="relative w-36">
<input
type="number"
className="w-24 border rounded p-1 mr-2 text-right"
className="border rounded px-2 py-1 pr-20 w-full text-right"
value={formData.loopInterval}
onChange={(e) => handleChange("loopInterval", e.target.value)}
/>
<span>Stunden</span>
<span className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm">
Stunden
</span>
</div>
</div>
</div>

View File

@@ -189,10 +189,10 @@ export default function TdrEinstellung({ slot, onClose }: Props) {
<div className="mt-6 mb-4">
<div className="mb-4 grid grid-cols-3 items-center gap-2 w-full">
<label className="">TDR Dämpfung:</label>
<div className="flex items-center gap-2">
<div className="relative w-36">
<input
type="number"
className="w-24 border rounded p-1 mr-2 text-right"
className="border rounded px-2 py-1 pr-20 w-full text-right"
value={tdrData.daempfung}
onChange={(e) => {
const updated = { ...tdrData, daempfung: e.target.value };
@@ -200,15 +200,17 @@ export default function TdrEinstellung({ slot, onClose }: Props) {
updateCache(updated);
}}
/>
<span>dB</span>
<span className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm">
dB
</span>
</div>
</div>
<div className="mb-4 grid grid-cols-3 items-center gap-2 w-full">
<label className="">Geschwindigkeit:</label>
<div className="flex items-center gap-2">
<div className="relative w-36">
<input
type="number"
className="w-24 border rounded p-1 mr-2 text-right"
className="border rounded px-2 py-1 pr-20 w-full text-right"
value={tdrData.geschwindigkeit}
onChange={(e) => {
const updated = { ...tdrData, geschwindigkeit: e.target.value };
@@ -216,7 +218,9 @@ export default function TdrEinstellung({ slot, onClose }: Props) {
updateCache(updated);
}}
/>
<span>m/µs</span>
<span className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm">
m/µs
</span>
</div>
</div>

View File

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

View File

@@ -43,7 +43,7 @@ const EinAusgaenge: React.FC = () => {
return (
<div className="flex flex-col gap-3 p-4 h-[calc(100vh-13vh-8vh)] laptop:h-[calc(100vh-10vh-5vh)] xl:h-[calc(100vh-10vh-6vh)] laptop:gap-0">
<h1 className="text-base font-semibold mb-2">Ein- und Ausgänge</h1>
<h1 className="text-base font-semibold mb-2">Schaltausgänge</h1>
<div className="grid grid-cols-1 xl:grid-cols-3 gap-4 items-start ">
<DigitalOutputs openOutputModal={openOutputModal} />

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="#FFFFFF" stroke="#00B0F0" stroke-width="1.06497" stroke-linecap="round" stroke-linejoin="round">
<!-- Rahmen -->
<rect x="1" y="1" width="30" height="30" rx="4" ry="4" fill="none" stroke="#00B0F0" stroke-width="1.5" />
<!-- Wellenlinie -->
<path d="M4 16h3l3 8 4-16 3 8h11" />
</svg>

After

Width:  |  Height:  |  Size: 382 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF" stroke="#00B0F0" stroke-width="1.06497" stroke-linecap="round" stroke-linejoin="round">
<path d="M2 12h3l3 8 4-16 3 8h7" />
</svg>

After

Width:  |  Height:  |  Size: 231 B