Break: Digitale Eingänge, es soll Kabelüberwachung Isolation zu erst angezeigt, und ein Button Daten anzeigen, dass die nicht bei DatePicker autmatisch holt
This commit is contained in:
@@ -1,108 +1,87 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
import { RootState } from "../../../../redux/store";
|
import { RootState } from "../../../../redux/store";
|
||||||
import { useAppDispatch } from "../../../../redux/store";
|
import {
|
||||||
import { updateInvertierung } from "../../../../redux/slices/digitalInputsSlice";
|
updateInvertierung,
|
||||||
|
updateName,
|
||||||
|
} from "../../../../redux/slices/digitalInputsSlice";
|
||||||
|
|
||||||
export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
|
export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
|
||||||
const dispatch = useAppDispatch();
|
const [invertiert, setInvertiert] = useState(false);
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const reduxInput = useSelector((state: RootState) =>
|
const reduxInput = useSelector((state: RootState) =>
|
||||||
state.digitalInputsSlice.inputs.find(
|
state.digitalInputsSlice.inputs.find(
|
||||||
(input) => input.id === Number(selectedInput.id)
|
(input) => input.id === Number(selectedInput?.id)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const [invertiert, setInvertiert] = useState<boolean>(false);
|
|
||||||
const isDev = process.env.NODE_ENV === "development";
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (selectedInput) {
|
|
||||||
if (isDev) {
|
|
||||||
const saved = localStorage.getItem(`invertierung_${selectedInput.id}`);
|
|
||||||
if (saved !== null) {
|
|
||||||
setInvertiert(parseInt(saved) === 1);
|
|
||||||
} else {
|
|
||||||
setInvertiert(selectedInput.invertierung);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setInvertiert(selectedInput.invertierung);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [selectedInput, isDev]);
|
|
||||||
|
|
||||||
if (!isOpen || !selectedInput) return null;
|
|
||||||
|
|
||||||
const handleInvertierungToggle = async () => {
|
|
||||||
const neueInvertierung = !invertiert;
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "development") {
|
|
||||||
dispatch(
|
|
||||||
updateInvertierung({
|
|
||||||
id: Number(selectedInput.id),
|
|
||||||
invertierung: neueInvertierung,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
setInvertiert(neueInvertierung);
|
|
||||||
} else {
|
|
||||||
const url = `/CPL?/CPL/SERVICE/empty.acp&DEI${selectedInput.id}=${
|
|
||||||
neueInvertierung ? 1 : 0
|
|
||||||
}`;
|
|
||||||
try {
|
|
||||||
const response = await fetch(url);
|
|
||||||
if (!response.ok) throw new Error("Fehler beim Senden der Anfrage");
|
|
||||||
|
|
||||||
dispatch(
|
|
||||||
updateInvertierung({
|
|
||||||
id: Number(selectedInput.id),
|
|
||||||
invertierung: neueInvertierung,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
setInvertiert(neueInvertierung);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Invertierung fehlgeschlagen:", error);
|
|
||||||
alert("Invertierung konnte nicht geändert werden.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//---------------------------------
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (reduxInput) {
|
if (reduxInput) {
|
||||||
setInvertiert(reduxInput.invertierung);
|
setInvertiert(reduxInput.invertierung);
|
||||||
|
setName(reduxInput.name || "");
|
||||||
}
|
}
|
||||||
}, [reduxInput]);
|
}, [reduxInput]);
|
||||||
|
|
||||||
//---------------------------------
|
if (!isOpen || !selectedInput || !reduxInput) return null;
|
||||||
|
|
||||||
|
const handleInvertierungToggle = () => {
|
||||||
|
const neueInvertierung = !invertiert;
|
||||||
|
dispatch(
|
||||||
|
updateInvertierung({ id: reduxInput.id, invertierung: neueInvertierung })
|
||||||
|
);
|
||||||
|
setInvertiert(neueInvertierung);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNameSpeichern = () => {
|
||||||
|
dispatch(updateName({ id: reduxInput.id, name }));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
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="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">
|
<div className="bg-white rounded-lg shadow-lg p-6 w-1/2 max-w-lg">
|
||||||
<h2 className="text-xl font-semibold text-littwin-blue mb-4 border-b pb-2">
|
<h2 className="text-xl font-semibold text-blue-500 mb-4 border-b pb-2">
|
||||||
Details für Eingang {selectedInput.id}
|
Parameter für Eingang {selectedInput.id}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="grid grid-cols-2 gap-x-4 gap-y-2">
|
|
||||||
<div>
|
|
||||||
<strong>Status:</strong>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<strong>Status:</strong>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={reduxInput?.status ? "text-red-600" : "text-green-600"}
|
|
||||||
>
|
|
||||||
{reduxInput?.status ? "Inaktiv" : "Aktiv"}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-x-4 gap-y-3">
|
||||||
<div>
|
<div>
|
||||||
<strong>Beschreibung:</strong>
|
<strong>Status:</strong>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3 text-xl font-semibold col-span-1">
|
||||||
|
{reduxInput.status ? (
|
||||||
|
<>
|
||||||
|
<span className="w-4 h-4 bg-red-500 rounded-full inline-block"></span>
|
||||||
|
<span className="text-red-600">Inaktiv</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="w-4 h-4 bg-green-500 rounded-full inline-block"></span>
|
||||||
|
<span className="text-green-600">Aktiv</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>{selectedInput.description}</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<strong>Name:</strong>
|
<strong>Name:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div>{selectedInput.name}</div>
|
<div className="flex gap-2">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
className="border border-gray-300 rounded px-2 py-1 w-full"
|
||||||
|
maxLength={32}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={handleNameSpeichern}
|
||||||
|
className="px-2 py-1 text-sm bg-blue-500 hover:bg-blue-600 text-white rounded"
|
||||||
|
>
|
||||||
|
Speichern
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 col-span-2">
|
<div className="flex items-center gap-2 col-span-2">
|
||||||
<strong>Invertierung:</strong>
|
<strong>Invertierung:</strong>
|
||||||
@@ -115,35 +94,35 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong>Zählerstand:</strong>
|
||||||
|
</div>
|
||||||
|
<div>{reduxInput.counter}</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<strong>Filterzeit:</strong>
|
<strong>Filterzeit:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div>{selectedInput.filterzeit} ms</div>
|
<div>{reduxInput.filterzeit} ms</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<strong>Gewichtung:</strong>
|
<strong>Gewichtung:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div>{selectedInput.gewichtung}</div>
|
<div>{reduxInput.gewichtung}</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
<strong>Zählerstand:</strong>
|
|
||||||
</div>
|
|
||||||
<div>{selectedInput.zaehlerstand}</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<strong>Zähler aktiv:</strong>
|
<strong>Zähler aktiv:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div>{selectedInput.zaehlerAktiv ? "Ja" : "Nein"}</div>
|
<div>{reduxInput.zaehlerAktiv ? "Ja" : "Nein"}</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<strong>Eingang offline:</strong>
|
<strong>Eingang offline:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div>{selectedInput.eingangOffline ? "Offline" : "Online"}</div>
|
<div>{reduxInput.eingangOffline ? "Offline" : "Online"}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={closeInputModal}
|
onClick={closeInputModal}
|
||||||
className="mt-6 px-4 py-2 bg-littwin-blue hover:bg-blue-600 text-white rounded-lg transition"
|
className="mt-6 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition"
|
||||||
>
|
>
|
||||||
Schließen
|
Schließen
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -6,5 +6,5 @@
|
|||||||
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
|
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
const webVersion = "1.6.209";
|
const webVersion = "1.6.210";
|
||||||
export default webVersion;
|
export default webVersion;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
// public/CPLmockData/SERVICE/de.js
|
// public/CPLmockData/SERVICE/de.js
|
||||||
|
|
||||||
|
// Zustand -> DESxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
||||||
var win_de_state = [
|
var win_de_state = [
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
];
|
];
|
||||||
// Invertierung -> DEIxx xx = Nr Eingang 1-32
|
|
||||||
|
|
||||||
|
// Invertierung -> DEIxx xx = Nr Eingang 1-32
|
||||||
var win_de_invert = [
|
var win_de_invert = [
|
||||||
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
@@ -18,6 +20,49 @@ Status Invertierung Anzeige
|
|||||||
0 1 ✅ grün
|
0 1 ✅ grün
|
||||||
0 0 ✅ grün
|
0 0 ✅ grün
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//Zählerstand -> DESxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
||||||
|
var win_de_counter = [
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0,
|
||||||
|
]; //Zählerstand
|
||||||
|
|
||||||
|
//Filterzeit -> DEFxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
||||||
|
// Frage: In digitale Eingänge Filterzeit DEFxx (In Lastenheft) und Flatter var flutter DEFxx ist ein und das selbe, welche Begriff soll ich nehmen?
|
||||||
|
// Antwort: Es ist die Filterzeit. Die Flatterzeit kommt später hinzu.
|
||||||
|
var win_de_time_filter = [
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0,
|
||||||
|
]; //Filterzeit
|
||||||
|
|
||||||
|
// Gewichtung -> DEGxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
||||||
|
var win_de_weighting = [
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
]; //Gewichtung
|
||||||
|
|
||||||
|
// Zähler aktiv -> DEZxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
||||||
|
var win_de_counter_active = [
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
]; //Zähler aktiv
|
||||||
|
|
||||||
|
// Eingang offline -> DEAxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
||||||
|
var win_de_offline = [
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
]; //Eingang offline
|
||||||
|
|
||||||
|
// Zähler aktiv -> DEZxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
||||||
|
var win_counter = [
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Name -> DENxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
||||||
var win_de_label = [
|
var win_de_label = [
|
||||||
"DE1",
|
"DE1",
|
||||||
"DE2",
|
"DE2",
|
||||||
@@ -52,12 +97,10 @@ var win_de_label = [
|
|||||||
"DE31",
|
"DE31",
|
||||||
"DE32",
|
"DE32",
|
||||||
];
|
];
|
||||||
var win_counter = [
|
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
// Frage: In digitale Eingänge Filterzeit DEFxx (In Lastenheft) und Flatter var flutter DEFxx ist ein und das selbe, welche Begriff soll ich nehmen?
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
// Antwort: Es ist die Filterzeit. Die Flatterzeit kommt später hinzu.
|
||||||
0.0, 0.0,
|
/* var win_flutter = [
|
||||||
];
|
|
||||||
var win_flutter = [
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
];
|
]; */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// slices/digitalInputsSlice.ts
|
// /redux/slices/digitalInputsSlice.ts
|
||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
interface DigitalInput {
|
interface DigitalInput {
|
||||||
@@ -8,6 +8,11 @@ interface DigitalInput {
|
|||||||
counter: number;
|
counter: number;
|
||||||
flutter: number;
|
flutter: number;
|
||||||
invertierung: boolean;
|
invertierung: boolean;
|
||||||
|
filterzeit: number;
|
||||||
|
gewichtung: number;
|
||||||
|
zaehlerAktiv: boolean;
|
||||||
|
eingangOffline: boolean;
|
||||||
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DigitalInputsState {
|
interface DigitalInputsState {
|
||||||
|
|||||||
@@ -26,16 +26,22 @@ export const fetchDigitaleEingaenge = async () => {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const formattedData = win.win_de_state.map(
|
const formattedData = win.win_de_state.map((status, index) => ({
|
||||||
(status: number, index: number) => ({
|
id: index + 1,
|
||||||
id: index + 1,
|
label: win.win_de_label?.[index] || `DE${index + 1}`,
|
||||||
label: win.win_de_label?.[index] || `DE${index + 1}`,
|
name: win.win_de_label?.[index] || "",
|
||||||
status: status === 1,
|
|
||||||
counter: win.win_counter?.[index] || 0,
|
status: status === 1,
|
||||||
flutter: win.win_flutter?.[index] || 0,
|
counter: win.win_de_counter?.[index] || 0,
|
||||||
invertierung: win.win_de_invert?.[index] === 1,
|
flutter: win.win_flutter?.[index] || 0,
|
||||||
})
|
invertierung: win.win_de_invert?.[index] === 1,
|
||||||
);
|
|
||||||
|
// 🔽 NEU:
|
||||||
|
filterzeit: win.win_de_time_filter?.[index] || 0,
|
||||||
|
gewichtung: win.win_de_weighting?.[index] || 0,
|
||||||
|
zaehlerAktiv: win.win_de_counter_active?.[index] === 1,
|
||||||
|
eingangOffline: win.win_de_offline?.[index] === 1,
|
||||||
|
}));
|
||||||
|
|
||||||
return formattedData;
|
return formattedData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user