Compare commits

...

10 Commits

Author SHA1 Message Date
ISA
4e396a1b10 docs(gisPolylines): ✍️ README mit Datenfluss-Diagramm und Erklärung ergänzt
- Datenfluss zwischen Redux Slices, Thunks, Services und Komponenten visualisiert
- Mermaid-UML hinzugefügt zur Darstellung der Architektur
- Technischer Hintergrund für Einsteiger dokumentiert
- Hinweise zur Datenherkunft (Datenbank vs. TALAS.web WebService)
- Hilfe zur Fehlerbehebung z. B. bei fehlendem LD_Name im Tooltip
2025-06-25 11:02:43 +02:00
ISA
bc331eb7b2 docs: Karten Material Link in README.md hinzugefügt 2025-06-25 09:23:43 +02:00
ISA
016e1a927d refactor: Tooltip-Generierung für Linien ausgelagert und Anzeige von Stationsnamen (LD_Name) hinzugefügt
- `generateLineTooltipContent` in eigene Datei extrahiert
- `useLineData` angepasst, um Stationen aus `gisStationsStaticDistrict` zu übergeben
- Anzeige der Station im Tooltip nun über `LD_Name` statt `matchingLine.name`
- Bugfix: "Station: N/A" wird nun korrekt angezeigt
2025-06-25 08:43:26 +02:00
ISA
89403164c6 refactor: Tooltip-HTML-Generierung aus useLineData ausgelagert
- Funktion `generateLineTooltipContent` aus `useLineData.js` extrahiert
- Neue Datei: `components/gisPolylines/tooltip/generateLineTooltipContent.js`
- Trennung von Logik (Hook) und Darstellung (Tooltip-HTML)
- Verbesserte Lesbarkeit und Wiederverwendbarkeit der Tooltip-Generierung
2025-06-25 07:49:52 +02:00
ISA
7c4fbc3988 refactor: Komponenten-Hooks strukturiert und in passende UI-Unterverzeichnisse verschoben
- useLineData.js → components/gisPolylines/tooltip/
- useLayerVisibility.js → components/mapLayersControlPanel/hooks/
- useAreaMarkersLayer.js → components/area/hooks/
- useDynamicDeviceLayers.js → components/devices/hooks/
- useDataUpdater.js & useMapComponentState.js → components/hooks/

💡 Ziel: Alle UI-bezogenen Hooks an logische Stellen verschoben, um Wartbarkeit zu verbessern.
🔍 Vorteil: Schnellere Navigation bei UI-Fehlern oder Layout-Anpassungen.
2025-06-25 07:21:05 +02:00
ISA
4070429193 docs: 2025-06-24 15:07:00 +02:00
ISA
b6c6fad3b3 docs: uiWidgets icon bug in Gitea 2025-06-24 12:29:51 +02:00
ISA
12fec717d8 docs: uiWidget 2025-06-24 12:01:49 +02:00
ISA
fe3cc48769 docs: Version Info Moda 2025-06-24 11:46:53 +02:00
ISA
82963ead23 docs: VersionInfoModal 2025-06-24 11:29:47 +02:00
76 changed files with 363 additions and 340 deletions

View File

@@ -25,4 +25,4 @@ NEXT_PUBLIC_USE_MOCKS=true
NEXT_PUBLIC_BASE_PATH=/talas5
# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH=
# App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.1.290
NEXT_PUBLIC_APP_VERSION=1.1.300

View File

@@ -26,4 +26,4 @@ NEXT_PUBLIC_BASE_PATH=/talas5
# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH=
# App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.1.290
NEXT_PUBLIC_APP_VERSION=1.1.300

View File

@@ -62,6 +62,7 @@ User-ID.
- Browser: Chrome ab Version 125.0.6420.142 empfohlen
- Karten Material vorhanden in: `C:\inetpub\wwwroot\talas5\TileMap\mapTiles`
![mapTiles](docs/screenshots/mapTiles.png)
Falls nicht vorhanden hier downloaden: http://10.10.0.28/produkte/TALAS.map/mapTiles.zip
---

View File

@@ -1,8 +1,8 @@
// /hooks/layers/useDynamicDeviceLayers.js
import { useEffect, useRef, useState } from "react";
import L from "leaflet";
import { createAndSetDevices } from "../utils/devices/createAndSetDevices";
import { checkOverlappingMarkers } from "../utils/mapUtils";
import { createAndSetDevices } from "@/utils/devices/createAndSetDevices";
import { checkOverlappingMarkers } from "@/utils/mapUtils";
import plusRoundIcon from "@/components/icons/devices/overlapping/PlusRoundIcon";
import { useSelector } from "react-redux";
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice.js";

View File

@@ -0,0 +1,40 @@
// /components/gisPolylines/tooltip/generateLineTooltipContent.js
// KEIN useSelector hier!
export function generateLineTooltipContent(statis, matchingLine, values, stations) {
const station = stations.find(s => s.IdLD === statis.IdLD);
const stationName = station?.LD_Name || "N/A";
const messageDisplay = values.messages
.map(
msg =>
`<span class="inline-block text-gray-800">
<span class="inline-block w-2 h-2 rounded-full mr-2" style="background-color: ${msg.prioColor};"></span>
${msg.message}
</span><br>`
)
.join("");
return `
<div class="bg-white rounded-lg m-0 p-2 w-[210px]">
<span class="text-lg font-semibold text-gray-900">${statis.ModulName || "Unknown"}</span><br>
<span class="text-md font-bold text-gray-800">${statis.ModulTyp || "N/A"}</span><br>
<span class="text-md font-bold text-gray-800">Slot: ${statis.Modul || "N/A"}</span><br>
<span class="text-md font-bold text-gray-800">Station: ${stationName}</span>
<br>
<div style="max-width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal;">
${messageDisplay}
</div>
<br>
${
values.messwert
? `<span class="inline-block text-gray-800">Messwert: ${values.messwert}</span><br>`
: ""
}
${
values.schleifenwert
? `<span class="inline-block text-gray-800">Schleifenwert: ${values.schleifenwert}</span>`
: ""
}
</div>
`;
}

View File

@@ -0,0 +1,91 @@
// /components/gisPolylines/tooltip/useLineData.js
import { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { selectGisLinesStatusFromWebservice } from "@/redux/slices/webservice/gisLinesStatusSlice";
import { fetchGisLinesThunk } from "@/redux/thunks/database/polylines/fetchGisLinesThunk";
import { fetchGisLinesStatusThunk } from "@/../redux/thunks/webservice/fetchGisLinesStatusThunk";
import { generateLineTooltipContent } from "./generateLineTooltipContent";
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice";
const useLineData = () => {
const dispatch = useDispatch();
const { data: statisData } = useSelector(selectGisLinesStatusFromWebservice);
const linesData = useSelector(state => state.gisLinesFromDatabase.data);
const [lineColors, setLineColors] = useState({});
const [tooltipContents, setTooltipContents] = useState({});
const stations = useSelector(selectGisStationsStaticDistrict)?.Points ?? [];
useEffect(() => {
dispatch(fetchGisLinesThunk());
dispatch(fetchGisLinesStatusThunk());
}, [dispatch]);
useEffect(() => {
if (!statisData || !Array.isArray(statisData)) return;
const colorsByModule = {};
const newTooltipContents = {};
const valueMap = {};
const sortedStatis = [...statisData].sort((a, b) => a.Level - b.Level);
sortedStatis.forEach(statis => {
const key = `${statis.IdLD}-${statis.Modul}`;
if (!valueMap[key]) {
valueMap[key] = {
messages: [],
messwert: undefined,
schleifenwert: undefined,
};
}
if (
statis.DpName.endsWith("_Messwert") &&
statis.Value !== "True" &&
!valueMap[key].messwert
) {
valueMap[key].messwert = statis.Value;
}
if (statis.DpName.endsWith("_Schleifenwert") && !valueMap[key].schleifenwert) {
valueMap[key].schleifenwert = statis.Value;
}
if (statis.Message && statis.Message !== "?") {
valueMap[key].messages.push({
message: statis.Message,
prioColor:
statis.PrioColor && statis.PrioColor !== "#ffffff" ? statis.PrioColor : "green",
});
}
});
sortedStatis.forEach(statis => {
const key = `${statis.IdLD}-${statis.Modul}`;
const matchingLine = linesData.find(
item => item.idLD === statis.IdLD && item.idModul === statis.Modul
);
if (matchingLine) {
const values = valueMap[key];
colorsByModule[key] = values.messages.length > 0 ? values.messages[0].prioColor : "green";
newTooltipContents[key] = generateLineTooltipContent(
statis,
matchingLine,
values,
stations
);
}
});
setLineColors(colorsByModule);
setTooltipContents(newTooltipContents);
}, [statisData, linesData, stations]);
return { lineColors, tooltipContents };
};
export default useLineData;

View File

@@ -4,11 +4,11 @@ import { useDispatch } from "react-redux";
// import type { AppDispatch } from "../redux/store";
// ✅ Thunks aus korrektem Pfad importieren
import { fetchGisLinesStatusThunk } from "../redux/thunks/webservice/fetchGisLinesStatusThunk";
import { fetchGisStationsMeasurementsThunk } from "../redux/thunks/webservice/fetchGisStationsMeasurementsThunk";
import { fetchGisStationsStaticDistrictThunk } from "../redux/thunks/webservice/fetchGisStationsStaticDistrictThunk";
import { fetchGisStationsStatusDistrictThunk } from "../redux/thunks/webservice/fetchGisStationsStatusDistrictThunk";
import { fetchGisSystemStaticThunk } from "../redux/thunks/webservice/fetchGisSystemStaticThunk";
import { fetchGisLinesStatusThunk } from "@/redux/thunks/webservice/fetchGisLinesStatusThunk";
import { fetchGisStationsMeasurementsThunk } from "@/redux/thunks/webservice/fetchGisStationsMeasurementsThunk";
import { fetchGisStationsStaticDistrictThunk } from "@/redux/thunks/webservice/fetchGisStationsStaticDistrictThunk";
import { fetchGisStationsStatusDistrictThunk } from "@/redux/thunks/webservice/fetchGisStationsStatusDistrictThunk";
import { fetchGisSystemStaticThunk } from "@/redux/thunks/webservice/fetchGisSystemStaticThunk";
const REFRESH_INTERVAL = parseInt(process.env.NEXT_PUBLIC_REFRESH_INTERVAL || "10000");

View File

@@ -13,11 +13,11 @@ import plusRoundIcon from "../icons/devices/overlapping/PlusRoundIcon.js";
import { restoreMapSettings, checkOverlappingMarkers } from "../../utils/mapUtils.js";
import addItemsToMapContextMenu from "@/components/contextmenu/useMapContextMenu.js";
import useAreaMarkersLayer from "@/hooks/useAreaMarkersLayer.js";
import useAreaMarkersLayer from "@/components/area/hooks/useAreaMarkersLayer.js";
import { setupPolylines } from "@/utils/polylines/setupPolylines.js";
import { setupPOIs } from "@/utils/setupPOIs.js";
import useLineData from "@/hooks/useLineData.js";
import { useMapComponentState } from "@/hooks/useMapComponentState.js";
import useLineData from "@/components/gisPolylines/tooltip/useLineData.js";
import { useMapComponentState } from "@/components/hooks/useMapComponentState.js";
import CoordinatePopup from "@/components/contextmenu/CoordinatePopup.js";
//----------Ui Widgets----------------
import MapLayersControlPanel from "@/components/uiWidgets/mapLayersControlPanel/MapLayersControlPanel.js";
@@ -74,9 +74,9 @@ import { fetchPoiIconsDataThunk } from "@/redux/thunks/database/pois/fetchPoiIco
import { fetchPoiTypThunk } from "@/redux/thunks/database/pois/fetchPoiTypThunk.js";
import { updateAreaThunk } from "@/redux/thunks/database/area/updateAreaThunk";
import useDynamicDeviceLayers from "@/hooks/useDynamicDeviceLayers.js";
import useDynamicDeviceLayers from "@/components/devices/hooks/useDynamicDeviceLayers.js";
import useDataUpdater from "@/hooks/useDataUpdater";
import useDataUpdater from "@/components/hooks/useDataUpdater.js";
import { cleanupPolylinesForMemory } from "@/utils/polylines/cleanupPolylinesForMemory";
import { cleanupMarkers } from "@/utils/common/cleanupMarkers";
import { monitorHeapAndReload } from "@/utils/common/monitorMemory";

View File

@@ -159,7 +159,7 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
>
<div className="flex flex-col mb-4">
<label htmlFor="description" className="block mb-2 font-bold text-sm text-gray-700">
Beschreibung:
Bezeichnung:
</label>
<input
type="text"
@@ -167,7 +167,7 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
name="description"
value={description}
onChange={e => setDescription(e.target.value)}
placeholder="Beschreibung der Station"
placeholder="Bezeichnung eingeben..."
className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm"
/>
</div>

View File

@@ -51,3 +51,21 @@ die Daten von DB auch mit WebSocket gelöst werden
- [x] TODO: POI bearbeiten funktioniert es nicht
- [ ] TODO: Linien Links noch mit Port 3000
- [ ] TODO: Checkliste für README.md vorbereiten
## 🐞 Aktuelle Bugs
- [ ] Tooltip zeigt `unknown` bei bestimmten Linien
→ prüfen in `setupPolylines.js`, ob alle Geräte korrekt benannt sind
- [ ] Tooltip zeigt `N/A` bei Station → untersuchen, ob `station.Name` in `createAndSetDevices.js`
gesetzt wird
## ✨ Ideen & Verbesserungen
- [ ] ESC-Taste schließt `VersionInfoModal`
- [ ] Zurück-Link in jedem `.md` Footer automatisieren
## 🧹 Technische Schulden
- [ ] Redundante Kontextmenülogik auflösen
- [ ] Bessere Trennung zwischen Mock- und Live-API in Service-Funktionen

View File

@@ -4,6 +4,8 @@
Zeigt ein modales Fenster mit Koordinateninformationen an, z.B. aus einem Kontextmenü heraus.
![CoordinatePopup](../../screenshots/CoordinatePopup.png)
## Features
- Darstellung eines Koordinatenwerts (`lat,lng`)

View File

@@ -2,9 +2,11 @@
# 🖱️ `contextmenu/` Kontextmenü-Komponenten
Dieses Verzeichnis enthält Komponenten und Hooks zur Anzeige und Steuerung von Kontextmenüs in der Leaflet-Kartenanwendung. Sie dienen der Interaktion mit POIs, Koordinaten und Layer-Objekten per Rechtsklick.
Dieses Verzeichnis enthält Komponenten und Hooks zur Anzeige und Steuerung von Kontextmenüs in der
Leaflet-Kartenanwendung. Sie dienen der Interaktion mit POIs, Koordinaten und Layer-Objekten per
Rechtsklick.
---
## ![useMapContextMenu](../../screenshots/useMapContextMenu.png)
## 📂 Enthaltene Dateien

View File

@@ -5,6 +5,8 @@
Initialisiert Kontextmenüeinträge für die Leaflet-Karte.
Wird typischerweise in `initializeMap()` oder `MapComponent` verwendet.
![useMapContextMenu](../../screenshots/useMapContextMenu.png)
## Kontextmenüeinträge
| Eintrag | Funktion |

View File

@@ -4,6 +4,8 @@
Ein einfaches benutzerdefiniertes Kontextmenü zur Interaktion mit Linien (Polylinien) auf der Karte.
![GIS Ployline contextmenu](../../screenshots/PolylineContextMenu.png)
## Zweck
Das Menü erlaubt folgende Interaktionen:

View File

@@ -1,3 +1,124 @@
<!-- /docs/components/gisPolylines/README.md -->
# 📄 Übersicht: docs/components/gisPolylines
- [PolylineContextMenu](PolylineContextMenu.md)
Diese Komponente verwaltet die Darstellung und Interaktion von GIS-Polylinien in der
Leaflet-Karte.
Sie kombiniert Statusdaten, statische Linien und Stationsdaten zu Tooltips und Farben.
---
## 🧬 Data Flow Diagram
Dieses Diagramm zeigt den **Datenfluss** zwischen den Redux-Slices, Thunks, Service-Funktionen und
den React-Komponenten,
die für die Anzeige der **GIS-Polylinien** zuständig sind.
### 📖 Ablauf erklärt
1. **Beim Laden der Seite** ruft die Hook `useLineData` mehrere Thunks auf:
- Diese laden Linien, Statusdaten und Stationsdaten über entsprechende Service-Funktionen.
2. Die Thunks speichern die geladenen Daten in Redux-Slices.
3. `useLineData` liest diese Redux-Daten aus und kombiniert sie:
- Zuordnung nach `idLD` und `Modul`
4. Daraus entsteht:
- Eine Prioritätsfarbe für die Linie
- Ein Tooltip-HTML mit Modulname, Slot, Station (LD_Name) und Statusmeldungen.
5. Diese Daten werden weitergegeben an:
- `generateLineTooltipContent` → für Tooltips bei Hover
- `PolylineContextMenu` → für Kontextmenü bei Rechtsklick
- Leaflet Polyline-Komponente → für farbige Darstellung
```mermaid
graph TD
subgraph Redux Store
A1[gisLinesFromDatabase Slice]
A2[gisLinesStatusFromWebservice Slice]
A3[gisStationsStaticDistrict Slice]
end
subgraph Thunks
T1[fetchGisLinesThunk]
T2[fetchGisLinesStatusThunk]
T3[fetchGisStationsStaticDistrictThunk]
end
subgraph Services
S1[fetchGisLinesService]
S2[fetchGisLinesStatusService]
S3[fetchGisStationsStaticDistrictService]
end
subgraph Komponenten
C1[useLineData Hook]
C2[generateLineTooltipContent]
C3[PolylineContextMenu.js]
C4[Leaflet Polyline Rendering]
end
T1 --> S1
T2 --> S2
T3 --> S3
T1 --> A1
T2 --> A2
T3 --> A3
A1 --> C1
A2 --> C1
A3 --> C1
C1 --> C2
C2 --> C4
C1 --> C3
```
---
## 📦 Wichtige Dateien
| Datei | Zweck |
| ------------------------------------------------------------------------ | -------------------------------------------------------------------- |
| [`useLineData.js`](tooltip/useLineData.js) | Holt Linien-, Status- und Stationsdaten aus Redux und kombiniert sie |
| [`generateLineTooltipContent.js`](tooltip/generateLineTooltipContent.js) | Baut HTML für die Tooltips |
| [`PolylineContextMenu.js`](PolylineContextMenu.md) | Kontextmenü zur Interaktion mit Linien |
---
![GIS Polylines](../../screenshots/gisPolylines.png)
---
[Zurück zur Übersicht](../../README.md)
---
## 📘 Technischer Hintergrund für Einsteiger
Diese Komponente verbindet Daten aus **zwei unterschiedlichen Systemen**:
1. **NodeMap App (Next.js API)**
→ liefert die **Geometrie der Linien** direkt aus der Datenbank (ohne Webservice).
2. **TALAS.web WebService**
→ liefert **Statusinformationen und Stationsnamen** (LD_Name).
### 🔄 Ablauf im Detail
- **Liniengeometrie** (`idLD`, `idModul`, `points`) kommt über `fetchGisLinesThunk` aus der
Datenbank.
- **Statusinformationen** (Meldungen, Farben, Modulname, Slot) kommen über
`fetchGisLinesStatusThunk`.
- **Stationsnamen** (LD_Name) kommen über `fetchGisStationsStaticDistrictThunk`.
- Die Hook `useLineData.js` verbindet alle Infos → erzeugt Tooltip-HTML & Farblogik.
- `generateLineTooltipContent.js` erstellt den konkreten Tooltip-HTML-String.
### 🧠 Wichtig für Debugging
- **Zuordnung** erfolgt immer über `idLD` und `Modul`.
- Stationen findest du im Slice `gisStationsStaticDistrict.Points[] → LD_Name`
- Linien findest du im Slice `gisLinesFromDatabase`
- Statusinfos findest du im Slice `gisLinesStatusFromWebservice`
🛠 **Fehler wie "Station: N/A"** entstehen, wenn `idLD` im Status vorhanden ist, aber keine passende
Station in `gisStationsStaticDistrict` gefunden wurde.

View File

@@ -4,6 +4,8 @@
Ein einfacher, grauer runder Marker als Stützpunkt in einer Polyline.
![CircleIcon](../../../screenshots/CircleIcon.png)
## Eigenschaften
- Stil: grauer Kreis mit schwarzem Rand

View File

@@ -4,6 +4,8 @@
Ein Viereck zur Markierung des Endpunkts einer Polyline.
![EndIcon](../../../screenshots/EndIcon.png)
## Eigenschaften
- Stil: graues Quadrat mit schwarzem Rand

View File

@@ -3,4 +3,6 @@
- [CircleIcon](CircleIcon.md)
- [EndIcon](EndIcon.md)
- [StartIcon](StartIcon.md)
- [SupportPointIcons](SupportPointIcons.md)
- [SupportPointIcons](SupportPointIcons.md)
![gisPolylinesIcons](../../../screenshots/gisPolylinesIcons.png)

View File

@@ -4,6 +4,8 @@
Ein SVG-Dreieck zur Markierung des Startpunkts einer Polyline.
![StartIcon](../../../screenshots/StartIcon.png)
## Eigenschaften
- Schwarzes Dreieck mit grauem Overlay (Polygon SVG)

View File

@@ -4,6 +4,8 @@
Definiert zwei Icons für interaktive Stützpunkte in einer Polyline:
![CircleIcon](../../../screenshots/CircleIcon.png)
## AddSupportPointIcon
- Grüner Kreis mit weißem Rand und Pluszeichen

View File

@@ -5,6 +5,8 @@
Ein einfaches Leaflet-Icon, das ein rundes Pluszeichen darstellt.
Wird für zusätzliche UI-Markierungen auf Geräten oder überlappenden Icons verwendet.
![PlusRoundIcon](../../../../screenshots/PlusRoundIcon.png)
## Eigenschaften
| Attribut | Wert |

View File

@@ -1,3 +1,5 @@
# 📄 Übersicht: docs/components/icons/devices/overlapping
- [PlusRoundIcon](PlusRoundIcon.md)
- [PlusRoundIcon](PlusRoundIcon.md)
![PlusRoundIcon](../../../../screenshots/PlusRoundIcon.png)

View File

@@ -5,7 +5,7 @@
Die zentrale React-Komponente zur Darstellung und Steuerung der Leaflet-Karte.
Bindet alle Marker, Layer, POIs, Linien und das Kontextmenü dynamisch ein.
---
![Overview](../../screenshots/overview1.png)
## 🎯 Zweck
@@ -41,6 +41,8 @@ Verwendet umfangreiche Redux-Slices zur Steuerung von:
- Sichtbarkeit einzelner Layergruppen
- Aktuelle Selektion (Area, Gerät, POI)
![ReduxSlices](../../screenshots/ReaduxSlices.png)
---
## 🔧 Lokale Steuerung
@@ -49,6 +51,8 @@ Verwendet umfangreiche Redux-Slices zur Steuerung von:
- Karte speichert Zoom & Center dauerhaft im Browser
- Kontextmenü-Einträge ändern sich je nach Rechten & Modus
![LocalStorage](../../screenshots/LocalStorage.png)
---
## 🧪 Besonderheiten

View File

@@ -1,3 +1,8 @@
# 📄 Übersicht: docs/components/mainComponent
- [MapComponent](MapComponent.md)
Die zentrale React-Komponente zur Darstellung und Steuerung der Leaflet-Karte.
Bindet alle Marker, Layer, POIs, Linien und das Kontextmenü dynamisch ein.
- [MapComponent](MapComponent.md)
![Overview](../../screenshots/overview1.png)

View File

@@ -5,6 +5,8 @@
Zeigt ein modales Formular an, um einen neuen POI auf der Karte zu erstellen.
Die Koordinaten (`latlng`) werden automatisch übernommen.
![POI hinzufügen Modal](../../screenshots/AddPOIModal.png)
## Funktionen
- POI-Name, Typ und zugehöriges Gerät auswählbar

View File

@@ -4,6 +4,8 @@
Ein Dialog zur Aktualisierung oder Löschung bestehender POIs.
![POI Update Modal](../../screenshots/PoiUpdateModal.png)
## Features
- Zeigt aktuellen Namen, Beschreibung, Gerät und Typ

View File

@@ -1,4 +1,6 @@
# 📄 Übersicht: docs/components/pois
- [AddPOIModal](AddPOIModal.md)
- [PoiUpdateModal](PoiUpdateModal.md)
- [PoiUpdateModal](PoiUpdateModal.md)
![POIs](../../screenshots/POIs.png)

View File

@@ -1,6 +1,6 @@
<!-- /docs/components/uiWidgets/CoordinateInput.md -->
# 📍 CoordinateInput.js
# CoordinateInput.js
Die Komponente `CoordinateInput` stellt ein einfaches Eingabefeld für geografische Koordinaten
(Latitude, Longitude) bereit.

View File

@@ -1,4 +1,7 @@
# 📄 Übersicht: docs/components/uiWidgets
# 📄 UI-Widgets
- [mapLayersControlPanel](mapLayersControlPanel/mapLayersControlPanel.md)
- [CoordinateInput](CoordinateInput.md)
- [VersionInfoModal](VersionInfoModal.md)
- [VersionInfoModal](VersionInfoModal.md)
![uiWidgets.png](../../screenshots/uiWidgets.png)

View File

@@ -8,6 +8,10 @@ Es wird meist im Footer oder als Info-Schaltfläche in der Benutzeroberfläche e
---
![VersionInfoModal](../../screenshots/VersionInfoModal.png)
---
## 🔧 Pfad
```bash
@@ -23,7 +27,8 @@ Die Komponente informiert Nutzer über:
- Die **aktuelle TALAS.Map Version**
- Die **Firmenadresse und Kontaktdaten** der Littwin Systemtechnik GmbH & Co. KG
- Eine zentral platzierte Grafik mit dem TALAS-Logo
- Eine Schaltfläche zum Schließen des Modals
- Eine Schaltfläche zum Schließen des Modals
![VersionInfoModal](../../screenshots/VersionInfoModal2.png)
---
@@ -46,20 +51,6 @@ Die Komponente informiert Nutzer über:
---
## 🧩 Inhalt im Modal
```plaintext
+--------------------------+
| [Logo_TALAS.png] |
| Littwin GmbH Adresse |
| Telefon & E-Mail |
| Version: 1.1.188 |
| [Schließen] Button |
+--------------------------+
```
---
## 🎨 Gestaltung
- Modal-Layout mit Tailwind CSS (`fixed`, `z-50`, `bg-white`, `rounded`, `shadow`)
@@ -75,7 +66,7 @@ Die Komponente informiert Nutzer über:
| `showVersionInfoModal = true` | Modal wird angezeigt |
| Klick auf Hintergrund | Modal wird geschlossen |
| Klick auf „Schließen“-Button | Modal wird geschlossen |
| Version `APP_VERSION = 1.1.188` | Text „TALAS.Map Version 1.1.188“ sichtbar |
| Version `APP_VERSION = 1.1.290` | Text „TALAS.Map Version 1.1.290“ sichtbar |
---
@@ -89,7 +80,6 @@ Die Komponente informiert Nutzer über:
## 🛠 Verbesserungsideen
- ESC-Taste als Schließen-Funktion ergänzen
- Option für dynamische Anzeige von Changelog-Link
- Automatischer Import von Version via `process.env.NEXT_PUBLIC_APP_VERSION`
---

View File

@@ -1,15 +0,0 @@
<!-- /docs/hooks/layers/useCiscoRouterMarkersLayer.md -->
# 🌐 useCiscoRouterMarkersLayer.js
Hook zur Verwaltung aller Cisco-Router-Marker in der Leaflet-Karte.
## Funktionen
- Lädt Geräte per `createAndSetDevices(6, ...)`
- Fügt Marker hinzu & registriert Popup/Kontextmenü
- Verwendet `checkOverlappingMarkers(...)`
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,15 +0,0 @@
<!-- /docs/hooks/layers/useDauzMarkersLayer.md -->
# 🔧 useDauzMarkersLayer.js
Spezialisierter Hook zur Verwaltung von DAUZ-Gerätemarkern (System-ID: 110)
## Verhalten
- Marker mit Popup & Kontextmenü
- Nutzung von `createAndSetDevices(...)`
- Sichtbarkeit direkt über Kartenlayer steuerbar
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,15 +0,0 @@
<!-- /docs/hooks/layers/useEciMarkersLayer.md -->
# 🛰️ useEciMarkersLayer.js
Verwaltet die Darstellung und Events für ECI-Marker (System-ID: 2)
## Features
- Kontextmenü & Popup für jeden Marker
- Erkennung überlappender Marker (`checkOverlappingMarkers`)
- Nutzung von `createAndSetDevices(...)`
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,15 +0,0 @@
<!-- /docs/hooks/layers/useGmaMarkersLayer.md -->
# 🌡️ useGmaMarkersLayer.js
Spezialhook für GMA-Marker mit Messwertanzeige (LT, FBT, GT, RLF).
## Besonderheiten
- Tooltip enthält Temperatur-/Feuchtigkeitswerte aus Redux
- Eigenes Kontextmenü mit Zoom/Zentrieren
- Verwendet `marker.options.areaName` zur Messzuordnung
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,14 +0,0 @@
<!-- /docs/hooks/layers/useLteModemMarkersLayer.md -->
# 📶 useLteModemMarkersLayer.js
Steuert Marker vom Typ LTE-Modem (System-ID: 5)
## Features
- Standard-Kontextmenü + Popup
- Integration mit OMS und Overlap-Check
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,14 +0,0 @@
<!-- /docs/hooks/layers/useMessstellenMarkersLayer.md -->
# 🧾 useMessstellenMarkersLayer.js
Für Messstellen-Marker (System-ID: 13)
## Verhalten
- Einfache Marker mit Tooltip
- Nutzung von `createAndSetDevices(...)` + Kontextmenü
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,14 +0,0 @@
<!-- /docs/hooks/layers/useOtdrMarkersLayer.md -->
# 🔍 useOtdrMarkersLayer.js
Darstellung von OTDR-Messpunkten (System-ID: 9)
## Funktionen
- Popup-Interaktion beim Hover
- Marker mit Kontextmenü via `addContextMenuToMarker`
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,11 +0,0 @@
# 🏭 useSiemensMarkersLayer.js
Für Siemens-Geräte (System-ID: 8).
- Marker mit Kontextmenü und Overlap-Prüfung
- Integration mit OMS
- Nutzung von `checkOverlappingMarkers(...)`
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,11 +0,0 @@
# 📡 useSmsfunkmodemMarkersLayer.js
Filtert `GisSystemStatic` nach SMS Modem (System 111 oder Name).
- Icon: `/img/icons/pois/sms-funkmodem.png`
- Kontextmenü & Popup
- Sichtbarkeit über `isVisible` steuerbar
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,11 +0,0 @@
# ❔ useSonstigeMarkersLayer.js
Für alle Geräte mit System-ID 200 (Sonstige).
- Klassische Leaflet-Marker
- Kontextmenü und Popup
- Nutzung von `createAndSetDevices(...)`
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,10 +0,0 @@
# 🌐 useTalasMarkersLayer.js
Für TALAS-Systeme (System-ID: 1).
- Popup + Kontextmenü auf Marker
- Fügt Marker zuerst zu OMS, dann zu Karte hinzu
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,10 +0,0 @@
# 🔗 useTalasiclMarkersLayer.js
Spezialhook für Geräte vom Typ TALASICL (System-ID: 100).
- Erstellt Marker mit Standardverhalten
- Kontextmenü, Popup, Overlap-Prüfung
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,10 +0,0 @@
# ⚙️ useTkComponentsMarkersLayer.js
Für TK-Komponenten (System-ID: 30).
- Lädt Marker via `createAndSetDevices`
- Marker-Koordinaten können debug-geloggt werden
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,11 +0,0 @@
# 💡 useUlafMarkersLayer.js
Spezialhook für ULAF-Systeme (System-ID: 0).
- Marker mit ULAF-Icon
- Kontextmenü und Popup (statisch)
- Dynamisch generierter Popupinhalt
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,10 +0,0 @@
# 🧰 useWagoMarkersLayer.js
Für WAGO-Systeme (System-ID: 7).
- Kontextmenü, Popup, Overlapping-Support
- OMS-Integration und Layer-Hinzufügung
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -1,11 +0,0 @@
# 🔷 useWdmMarkersLayer.js
Verwaltet WDM-Marker (System-ID: 10) in Leaflet.
- Marker mit Kontextmenü
- Mouseover-Popup
- Nutzung von `createAndSetDevices(...)`
---
[Zurück zur Übersicht](../../README.md)

View File

@@ -5,6 +5,9 @@
Custom Hook zur Initialisierung von Leaflet-Markern für ein bestimmtes System.
Bindet `createAndSetDevices(...)` automatisch in einen `useEffect`.
Beispiel: TALAS Layer ist mit Pfeilen markiert
![TALAS-Layer](../screenshots/TALAS-Layer.png)
## Parameter
- `systemId`: ID des Gerätesystems (z.B. 1 = TALAS)

View File

@@ -4,6 +4,9 @@
Verwaltet alle Marker-Layergruppen dynamisch und modular in einem zentralen Hook.
Beispiel: TALAS Layer ist mit Pfeilen markiert
![TALAS-Layer](../screenshots/TALAS-Layer.png)
## Funktionen
- Initialisiert LayerGroups für 15+ Gerätesysteme

View File

@@ -4,11 +4,18 @@
Custom Hook zur dynamischen Steuerung von Layer-Sichtbarkeit basierend auf Redux.
Beispiel: TALAS Layer ist mit Pfeilen markiert
![TALAS-Layer](../screenshots/mapLayersVisibilityTALAS.png)
Redux
![TALAS-Layer](../screenshots/mapLayersVisibilityRedux.png)
Local Storage
![TALAS-Layer](../screenshots/mapLayersVisibility.png)
## Features
- Entfernt oder zeigt Marker je nach `mapLayersVisibility`
- Nutzt `OverlappingMarkerSpiderfier` (`oms`)
- Normalisiert Layer-Keys (z.B. `"GMA"``"gma"`)
- Nutzt `OverlappingMarkerSpiderfier`
- Nutzt Layer-IDs
## Intern

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
docs/screenshots/POIs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -1,94 +0,0 @@
// hooks/useLineData.js //fix v1.0.8.1
import { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { selectGisLinesStatusFromWebservice } from "../redux/slices/webservice/gisLinesStatusSlice";
import { fetchGisLinesThunk } from "../redux/thunks/database/polylines/fetchGisLinesThunk";
import { fetchGisLinesStatusThunk } from "../redux/thunks/webservice/fetchGisLinesStatusThunk";
const useLineData = () => {
const dispatch = useDispatch();
const { data: statisData } = useSelector(selectGisLinesStatusFromWebservice);
const linesData = useSelector((state) => state.gisLinesFromDatabase.data);
const [lineColors, setLineColors] = useState({});
const [tooltipContents, setTooltipContents] = useState({});
useEffect(() => {
dispatch(fetchGisLinesThunk());
dispatch(fetchGisLinesStatusThunk());
}, [dispatch]);
useEffect(() => {
if (!statisData || !Array.isArray(statisData)) return;
const colorsByModule = {};
const newTooltipContents = {};
const valueMap = {};
const sortedStatis = [...statisData].sort((a, b) => a.Level - b.Level);
sortedStatis.forEach((statis) => {
const key = `${statis.IdLD}-${statis.Modul}`;
if (!valueMap[key]) {
valueMap[key] = {
messages: [],
messwert: undefined,
schleifenwert: undefined,
};
}
if (statis.DpName.endsWith("_Messwert") && statis.Value !== "True" && !valueMap[key].messwert) {
valueMap[key].messwert = statis.Value;
}
if (statis.DpName.endsWith("_Schleifenwert") && !valueMap[key].schleifenwert) {
valueMap[key].schleifenwert = statis.Value;
}
if (statis.Message && statis.Message !== "?") {
valueMap[key].messages.push({
message: statis.Message,
prioColor: statis.PrioColor && statis.PrioColor !== "#ffffff" ? statis.PrioColor : "green",
});
}
});
sortedStatis.forEach((statis) => {
const key = `${statis.IdLD}-${statis.Modul}`;
const matchingLine = linesData.find((item) => item.idLD === statis.IdLD && item.idModul === statis.Modul);
if (matchingLine) {
const values = valueMap[key];
const messageDisplay = values.messages.map((msg) => `<span class="inline-block text-gray-800"><span class="inline-block w-2 h-2 rounded-full mr-2" style="background-color: ${msg.prioColor};"></span>${msg.message}</span><br>`).join("");
colorsByModule[key] = values.messages.length > 0 ? values.messages[0].prioColor : "green";
newTooltipContents[key] = `
<div class="bg-white rounded-lg m-0 p-2 w-[210px]">
<span class="text-lg font-semibold text-gray-900">${statis.ModulName || "Unknown"}</span>
<br>
<span class="text-md font-bold text-gray-800">${statis.ModulTyp || "N/A"}</span>
<br>
<span class="text-md font-bold text-gray-800">Slot: ${statis.Modul || "N/A"}</span>
<br>
<span class="text-md font-bold text-gray-800">Station: ${matchingLine.name || "N/A"}</span>
<br>
<div style="max-width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal;">
${messageDisplay}
</div>
<br>
${values.messwert ? `<span class="inline-block text-gray-800">Messwert: ${values.messwert}</span><br>` : ""}
${values.schleifenwert ? `<span class="inline-block text-gray-800">Schleifenwert: ${values.schleifenwert}</span>` : ""}
</div>
`;
}
});
setLineColors(colorsByModule);
setTooltipContents(newTooltipContents);
}, [statisData, linesData]);
return { lineColors, tooltipContents };
};
export default useLineData;

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "nodemap",
"version": "1.1.290",
"version": "1.1.300",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "nodemap",
"version": "1.1.290",
"version": "1.1.300",
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",

View File

@@ -1,6 +1,6 @@
{
"name": "nodemap",
"version": "1.1.290",
"version": "1.1.300",
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",