diff --git a/.env.development b/.env.development index a6f058e..8162e2e 100644 --- a/.env.development +++ b/.env.development @@ -6,5 +6,16 @@ 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.445 -NEXT_PUBLIC_CPL_MODE=jsSimulatedProd # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) \ No newline at end of file +NEXT_PUBLIC_APP_VERSION=1.6.446 +NEXT_PUBLIC_CPL_MODE=jsSimulatedProd # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) + +#### Feature-Flags #### +# 🔄 Zusatzfunktionen (Kai, 25.06.2025) +NEXT_PUBLIC_FEATURE_MESSWERTANZEIGE_EINGANG=true +NEXT_PUBLIC_FEATURE_MELDUNG_SPALTE_QUELLE=false +NEXT_PUBLIC_FEATURE_STARTSEITE_SPALTENREIHENFOLGE=false +NEXT_PUBLIC_FEATURE_BERICHTE_SPALTENREIHENFOLGE=false +NEXT_PUBLIC_FEATURE_FILTER_QUELLE=false +NEXT_PUBLIC_FEATURE_MESSWERT_DETAILANZEIGE=false +NEXT_PUBLIC_FEATURE_ADMIN_PASSWORT_AENDERN=false +NEXT_PUBLIC_FEATURE_OPC_CLIENT_ANZAHL=false diff --git a/.env.production b/.env.production index b4880bf..1f97e8b 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.445 +NEXT_PUBLIC_APP_VERSION=1.6.446 NEXT_PUBLIC_CPL_MODE=production \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a0b3ff4..cd77fd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [1.6.446] – 2025-06-25 + +- docs: Zusatzfunktionen (Kai, 25.06.2025) in TODO.md ergänzt + +--- ## [1.6.445] – 2025-06-25 - docs: README diff --git a/components/main/analogInputs/AnalogInputsChart.tsx b/components/main/analogInputs/AnalogInputsChart.tsx index f5273da..366afc0 100644 --- a/components/main/analogInputs/AnalogInputsChart.tsx +++ b/components/main/analogInputs/AnalogInputsChart.tsx @@ -1,7 +1,7 @@ -"use client"; // /components/main/analogeEingaenge/AnalogInputsChart.tsx +"use client"; import React, { useEffect } from "react"; import { Line } from "react-chartjs-2"; -import { getColor } from "../../../utils/colors"; +import { getColor } from "@/utils/colors"; import { Chart as ChartJS, LineElement, @@ -19,6 +19,7 @@ import { useSelector, useDispatch } from "react-redux"; import type { RootState, AppDispatch } from "../../../redux/store"; import { getAnalogInputsHistoryThunk } from "@/redux/thunks/getAnalogInputsHistoryThunk"; +// Basis-Registrierung (ohne Zoom-Plugin) ChartJS.register( LineElement, PointElement, @@ -35,19 +36,32 @@ export default function AnalogInputsChart({ }: { selectedId: number | null; }) { + const zoomEnabled = + process.env.NEXT_PUBLIC_FEATURE_MESSWERTANZEIGE_EINGANG === "true"; const dispatch = useDispatch(); - const { data, isLoading, error } = useSelector( + const { data } = useSelector( (state: RootState) => state.analogInputsHistory ) as { data: { [key: string]: any[] }; - isLoading: boolean; - error: any; }; useEffect(() => { dispatch(getAnalogInputsHistoryThunk()); }, [dispatch]); + // ✅ Zoom-Plugin dynamisch importieren und registrieren + useEffect(() => { + const loadZoomPlugin = async () => { + if (typeof window !== "undefined") { + const zoomPlugin = (await import("chartjs-plugin-zoom")).default; + if (!ChartJS.registry.plugins.get("zoom")) { + ChartJS.register(zoomPlugin); + } + } + }; + loadZoomPlugin(); + }, []); + if (!selectedId) { return (
Bitte einen Messwerteingang auswählen
@@ -77,7 +91,6 @@ export default function AnalogInputsChart({ borderColor: getColor("littwin-blue"), backgroundColor: "rgba(59,130,246,0.5)", borderWidth: 2, - // fill: false, pointRadius: 0, pointHoverRadius: 10, tension: 0.1, @@ -92,8 +105,21 @@ export default function AnalogInputsChart({ tooltip: { mode: "index" as const, intersect: false }, title: { display: true, - text: `Verlauf der letzte 24 Stunden`, + text: `Verlauf der letzten 24 Stunden`, }, + ...(zoomEnabled && { + zoom: { + pan: { + enabled: true, + mode: "x" as const, + }, + zoom: { + wheel: { enabled: true }, + pinch: { enabled: true }, + mode: "x" as const, + }, + }, + }), }, scales: { x: { @@ -113,7 +139,7 @@ export default function AnalogInputsChart({ }, title: { display: true, - text: "Zeit ", + text: "Zeit", }, }, y: { diff --git a/docs/TODO.md b/docs/TODO.md index 331c6c6..45d4e8b 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -10,3 +10,5 @@ - [ ] System: Button bei jedem Messwert für Detailansicht (inkl. Kurve im Popup und Zeitauswahl) - [ ] Einstellungen – Benutzerverwaltung: Admin kann Adminpasswort ändern - [ ] Einstellungen – OPC: Anzahl der aktuellen Clients (ggf. KAS-Variable einbauen) + + ![Zusatzfunktionen Kai 25.06.2025](./TODOsScreenshots/Zusatzfunktionen_25-06-2025.png) diff --git a/docs/TODOsScreenshots/Zusatzfunktionen_25-06-2025.png b/docs/TODOsScreenshots/Zusatzfunktionen_25-06-2025.png new file mode 100644 index 0000000..e679782 Binary files /dev/null and b/docs/TODOsScreenshots/Zusatzfunktionen_25-06-2025.png differ diff --git a/docs/components/README.md b/docs/components/README.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/components/main/analogInputs/AnalogInputsChart.md b/docs/components/main/analogInputs/AnalogInputsChart.md new file mode 100644 index 0000000..7ee6648 --- /dev/null +++ b/docs/components/main/analogInputs/AnalogInputsChart.md @@ -0,0 +1,51 @@ + + +# 📈 AnalogInputsChart + +Die Komponente `AnalogInputsChart` zeigt den Verlauf der Messwerte für einen ausgewählten analogen Eingang an. Sie nutzt `react-chartjs-2` mit `chart.js` (inkl. TimeScale). + +--- + +## ⚙️ Funktion + +- Ruft über `Redux Thunk` die Historie der analogen Eingänge ab +- Zeigt eine Liniendiagramm-Kurve mit Zeit auf der X-Achse und Messwerten auf der Y-Achse +- Berücksichtigt die Auswahl des Messwerteingangs (`selectedId`) + +--- + +## 🧩 Feature-Flag: Zoom & Pan + +Der Zoom- und Pan-Modus (interaktives Scrollen/Ziehen im Chart) wird über ein Feature-Flag gesteuert: + +```env +NEXT_PUBLIC_FEATURE_MESSWERTANZEIGE_EINGANG=true +``` + +### Verhalten: + +- Wenn `true`: Nutzer kann in das Zeitfenster hineinzoomen und sich bewegen (pan). +- Wenn `false`: Chart ist statisch und nur lesbar. + +### Technisch: + +- `chartjs-plugin-zoom` wird **dynamisch nur im Browser** geladen +- Die Optionen für `zoom` und `pan` werden nur gesetzt, wenn das Flag aktiv ist + +--- + +## 📦 Technologien + +- `react-chartjs-2` +- `chart.js` mit `TimeScale` +- `chartjs-plugin-zoom` (lazy import) +- `redux` & `thunks` für Daten +- `date-fns` mit deutscher Lokalisierung + +--- + +## 🔍 Hinweise + +- Der Messwert-Key wird berechnet als `selectedId + 99`, da Backend-Daten mit Key `99`, `100`, usw. zurückkommen. +- Wenn keine Daten vorhanden sind, wird ein entsprechender Hinweis angezeigt. +- Farbschema nutzt `getColor("littwin-blue")` aus den Projektfarben. diff --git a/docs/components/main/analogInputs/AnalogInputsSettingsModal.md b/docs/components/main/analogInputs/AnalogInputsSettingsModal.md new file mode 100644 index 0000000..e41881e --- /dev/null +++ b/docs/components/main/analogInputs/AnalogInputsSettingsModal.md @@ -0,0 +1,70 @@ + + +# ⚙️ AnalogInputsSettingsModal + +Diese Komponente zeigt ein zentriertes Modal zur Konfiguration eines analogen Eingangs. + +--- + +## 🧩 Funktion + +- Wird angezeigt, wenn `isOpen` true ist und ein `selectedInput` gesetzt ist. +- Zeigt alle relevanten Felder zur Konfiguration: + - **Bezeichnung** + - **Offset** (z. B. für Kalibrierung) + - **Faktor** (Multiplikator) + - **Einheit** (Dropdown: V, mA, °C, bar, %) + - **Loggerintervall** (in Minuten) + +--- + +## ✏️ Verwendung + +```tsx + setModalOpen(false)} +/> +``` + +--- + +## 💾 Speichern-Logik + +Beim Klick auf „Speichern“ werden die Einstellungen auf zwei verschiedene Arten verarbeitet: + +### 🔧 Entwicklungsmodus (`localhost`): + +- Daten werden per POST an die lokale API gesendet: + `/api/cpl/updateAnalogInputsSettingsHandler` +- Die Datenstruktur orientiert sich an `window.win_analogInputs*` Variablen + +### 🚀 Produktionsmodus: + +- Daten werden über einen GET-Request mit URL-Parametern an ein CGI-Backend übermittelt: + `/CPL?/Service/ae.ACP&ACN{slot}=...&ACO{slot}=...` + +--- + +## 🧪 Besonderheiten + +- Werte wie `offset` und `factor` werden als String mit `,` oder `.` akzeptiert und korrekt konvertiert. +- Eingabefelder sind per `useState` gebunden. +- Ein `console.log` zeigt `loggerInterval`, wenn `selectedInput` geladen wird. +- Nach erfolgreichem Speichern wird die Seite neu geladen (`location.reload()`), um aktuelle Werte anzuzeigen. + +--- + +## 🛑 Validierung + +- Aktuell keine Validierung gegen ungültige Werte (z. B. negatives Intervall oder leere Felder). +- Sollte ggf. ergänzt werden, wenn das Backend empfindlich auf falsche Werte reagiert. + +--- + +## 🖼️ UI/UX + +- Modal ist zentriert mit dunklem Overlay. +- Abbrechen über „X“-Button oben rechts. +- Tailwind CSS für Layout und Styling verwendet. diff --git a/docs/components/main/analogInputs/AnalogInputsTable.md b/docs/components/main/analogInputs/AnalogInputsTable.md new file mode 100644 index 0000000..0c2490e --- /dev/null +++ b/docs/components/main/analogInputs/AnalogInputsTable.md @@ -0,0 +1,52 @@ + + +# 🧮 AnalogInputsTable + +Die Komponente `AnalogInputsTable` zeigt eine Tabelle mit allen verfügbaren analogen Eingängen an, einschließlich Messwert, Einheit und Bezeichnung. + +--- + +## ⚙️ Funktion + +- Ruft beim Laden die Liste der analogen Eingänge aus dem Redux-Store über `getAnalogInputsThunk()` ab. +- Zeigt alle Eingänge in einer Tabelle mit folgenden Spalten: + - Eingang (ID) + - Messwert + - Einheit + - Bezeichnung + - Aktion (Zahnrad-Icon zur Konfiguration) + +--- + +## 🔄 Interaktion + +- Beim Klick auf eine Tabellenzeile: + - Wird der Eingang als aktiv markiert (`activeId`) + - `setSelectedId` wird gesetzt → z. B. für Diagrammanzeige +- Beim Klick auf das ⚙️-Icon: + - `setSelectedInput` wird mit dem aktuellen Objekt befüllt + - Das Einstellungs-Modal (`AnalogInputsSettingsModal`) wird geöffnet + +--- + +## 📦 Technologien + +- `react-redux` für Zustand und Datenabruf +- `@iconify/react` für Icons (z. B. `mdi/waveform`, `mdi/settings`) +- Tailwind CSS für Styling und Layout +- Typ `AnalogInput` zur Definition der Eingangsdatenstruktur + +--- + +## 🧪 Besonderheiten + +- `unit` ist optional – wird als `"-"` angezeigt, wenn nicht vorhanden +- Die Auswahlfarbe der Zeile (hellblau) zeigt den aktiven Eingang an +- Mobilfreundlich durch `overflow-x-auto` und responsives Tailwind-Layout + +--- + +## 🔍 Hinweise + +- Die `label`-, `value`- und `unit`-Werte stammen direkt aus dem Redux-State `analogInputs` +- Eingänge ohne `id` oder `label` werden gefiltert diff --git a/docs/components/main/analogInputs/README.md b/docs/components/main/analogInputs/README.md new file mode 100644 index 0000000..ed9b9d5 --- /dev/null +++ b/docs/components/main/analogInputs/README.md @@ -0,0 +1,60 @@ + + +# 📂 Komponentenübersicht: Analoge Eingänge + +Dieses Verzeichnis enthält alle React-Komponenten zur Visualisierung und Konfiguration der analogen Eingänge im System. + +--- + +## 📋 Übersicht der Komponenten + +### 1. [`AnalogInputsTable`](./AnalogInputsTable.md) + +Zeigt eine tabellarische Übersicht aller analogen Eingänge mit Messwert, Einheit und Bezeichnung. + +- Auswahl eines Eingangs durch Klick +- Öffnet Einstellungen per Zahnrad-Icon +- Nutzt Redux für Datenabruf + +➡️ Dokumentation: [AnalogInputsTable.md](./AnalogInputsTable.md) + +--- + +### 2. [`AnalogInputsChart`](./AnalogInputsChart.md) + +Zeigt den zeitlichen Verlauf eines Messwerteingangs im Liniendiagramm. + +- Zoom & Pan steuerbar über Feature-Flag `NEXT_PUBLIC_FEATURE_MESSWERTANZEIGE_EINGANG` +- Chart.js mit Zeitachse (TimeScale) +- Daten aus Redux-State + +➡️ Dokumentation: [AnalogInputsChart.md](./AnalogInputsChart.md) + +--- + +### 3. [`AnalogInputsSettingsModal`](./AnalogInputsSettingsModal.md) + +Modal zur Bearbeitung eines analogen Eingangs (Label, Offset, Faktor, Einheit, Speicherintervall). + +- Werte werden lokal oder über API/CGI gespeichert +- Dynamische Anzeige der aktuellen Einstellungen +- Eingaben mit `useState` gebunden + +➡️ Dokumentation: [AnalogInputsSettingsModal.md](./AnalogInputsSettingsModal.md) + +--- + +## 🧩 Technologien + +- React & Redux +- Chart.js / react-chartjs-2 +- Tailwind CSS +- Iconify +- API-Anbindung & lokale Mockdaten + +--- + +## 🗂️ Speicherort + +Pfad: `/components/main/analogInputs/` +Dokumentation: `/docs/components/main/analogInputs/` diff --git a/package-lock.json b/package-lock.json index 6a2ad6f..c5514d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cpl-v4", - "version": "1.6.445", + "version": "1.6.446", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cpl-v4", - "version": "1.6.445", + "version": "1.6.446", "dependencies": { "@fontsource/roboto": "^5.1.0", "@iconify-icons/ri": "^1.2.10", diff --git a/package.json b/package.json index 8ebac1c..ad8f511 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cpl-v4", - "version": "1.6.445", + "version": "1.6.446", "private": true, "scripts": { "dev": "next dev",