docs: md 2 html for confluence

This commit is contained in:
ISA
2025-09-19 11:48:59 +02:00
parent 76280b365b
commit 3d0ce4a2b4
238 changed files with 8790 additions and 5 deletions

View File

@@ -0,0 +1,109 @@
# 🗺️ Dynamische Marker-Verwaltung in MapComponent.js (NodeMap)
Dieses Dokument erklärt, wie Marker dynamisch erstellt, verwaltet und in `MapComponent.js` verwendet
werden inklusive Datenfluss und OverlappingMarkerSpiderfier-Integration.
---
## 🔄 Dynamische Marker-Erzeugung Übersicht
Früher (statisch):
```js
useLayerVisibility(map, talasMarkers, mapLayersVisibility, "TALAS", oms);
```
→ Jeder Marker-Typ war hart codiert.
Jetzt (dynamisch):
```js
const { markerStates, layerRefs } = useDynamicDeviceLayers(
map,
GisSystemStatic,
mapLayersVisibility,
priorityConfig,
oms
);
```
---
## 🔁 Datenfluss Schritt für Schritt
1. **MapComponent.js** ruft den Hook `useDynamicDeviceLayers(...)` auf.
2. Der Hook iteriert über `GisSystemStatic` (Webservice-Liste aller Systeme).
3. Für jedes System wird `createAndSetDevices(...)` aufgerufen.
4. Diese Funktion:
- Holt `Stations` aus Redux (filtered by System-ID)
- Erstellt Marker (Leaflet)
- Rückgabe über Callback `setMarkersFunction(markers)`
5. Die Marker werden per `setMarkerStates()` gespeichert.
6. In MapComponent.js können sie aus `markerStates[SystemName]` gelesen werden.
7. Sichtbarkeit wird über Redux (`mapLayersVisibility`) gesteuert.
8. Überlappende Marker werden über `checkOverlappingMarkers()` + `plusRoundIcon` + OMS angezeigt.
---
## 📦 Marker-Aufbau
### `createAndSetDevices.js`
- Filtert Stations (`Points`) aus `selectGisStationsStaticDistrict`
- Erstellt für jede gültige Station einen Marker:
```js
const marker = L.marker([station.X, station.Y], { ... });
oms.addMarker(marker); // Spiderfier-fähig
```
- Fügt Marker zur richtigen `LayerGroup` hinzu
- Gibt alle Marker über Callback zurück
---
## 🕷️ OverlappingMarkerSpiderfier (OMS)
- Initialisiert in `useInitializeMap(...)` in `MapComponent.js`
- Wird an `useDynamicDeviceLayers` übergeben
- Marker werden dort registriert: `oms.addMarker(marker)`
- Bei Klick auf das PlusIcon:
```js
plusMarker.on("click", () => oms.spiderfy(nearbyMarkers));
```
---
## 📘 Mermaid-Diagramm
```mermaid
flowchart TD
A1[MapComponent] --> B1[useDynamicDeviceLayers]
B1 --> C1[loop über GisSystemStatic]
C1 --> D1[createAndSetDevices]
D1 --> E1[Filter stations aus Redux]
E1 --> F1[erstelle Marker /Leaflet]
F1 --> G1[Marker in LayerGroup einfügen]
G1 --> H1[setMarkerStates im Hook]
H1 --> A2[markerStates zurück nach MapComponent]
A2 --> I1[Map aktualisiert Marker]
A2 --> I2[checkOverlappingMarkers mit OMS]
```
---
## ✅ Vorteile der neuen Lösung
| Vorteil | Beschreibung |
| ------------- | ------------------------------------------------------ |
| 🔄 Flexibel | Neue Geräte-Typen automatisch erkannt |
| 📦 Kompakt | Kein `useState` oder `useLayerVisibility` mehr nötig |
| 🧠 Wartbar | Eine zentrale Logik statt doppelter Komponentenlogik |
| 🕷️ Integriert | OMS funktioniert automatisch bei überlappenden Markern |
---
Letztes Update: automatisch generiert mit ChatGPT (OpenAI)
---
[Zurück zur Übersicht](README.md)

View File

@@ -0,0 +1,313 @@
<!-- /docs/architecture.md -->
# 🧠 Architekturübersicht NodeMap
Dieses Dokument beschreibt die technische Gesamtarchitektur des Projekts **NodeMap**, einer
kartenbasierten Webanwendung zur Anzeige, Bearbeitung und Verwaltung von GIS-Daten, POIs und
Gerätestatus.
---
## ⚙️ Technologie-Stack
| Komponente | Beschreibung |
| --------------------- | ---------------------------------------------------------------------- |
| **Frontend** | React 18 + Next.js (App Router) |
| **State-Management** | Redux Toolkit mit zentralem Store, Thunks & Slices |
| **UI** | Tailwind CSS + Leaflet + React-Icons |
| **Backend-Anbindung** | Webservices via `WebServiceMap.asmx` (IIS) + lokale Next.js API für DB |
| **Datenbank** | MySQL (Produktiv & Entwicklung, z.T. via Docker) |
| **Deployment** | Windows Server (IIS), optional per `nssm` als Dienst |
---
## 🔄 Systemübersicht (Ablauf)
```mermaid
sequenceDiagram
participant Browser
participant TALASweb
participant NodeMap
participant MySQL
Browser->>TALASweb: mapTypC.aspx?m=12&u=484
TALASweb-->>Browser: iFrame lädt NodeMap
Browser->>NodeMap: Liest m & u aus URL
NodeMap->>TALASweb: WebService-Requests (5 APIs)
NodeMap->>MySQL: API-Anfragen zu POIs, Geräten, Linien
NodeMap-->>Browser: Interaktive Karte anzeigen
```
---
## 🗺️ Architekturüberblick
```
+------------------+ +------------------+ +------------------+
| Leaflet Map | <---> | Redux Store | <---> | Webservices |
| (Interaktivität) | | (Status & Data) | | (IIS, .asmx) |
+------------------+ +------------------+ +------------------+
^
|
v
+------------------+ +------------------+ +-------------------+
| POI-Komponenten | <---> | Redux Slices | <---> | Next.js API-Routen|
| (Add/Edit) | | (z.B. poiSlice) | | (Datenbank) |
+------------------+ +------------------+ +-------------------+
```
---
## 🔁 Datenfluss (Beispiel: POI anzeigen)
1. Leaflet-Karte lädt bei `MapComponent` Mounting
2. Redux-Thunk `fetchPoiMarkersThunk` wird ausgelöst
3. Thunk ruft `fetchPoiDataService.js` (DB) oder Webservice (IIS) auf
4. Ergebnisse werden im Slice `readPoiMarkersStoreSlice` gespeichert
5. Komponenten lesen POI-Daten über `useSelector(...)` aus dem Store
6. POIs werden als Marker in Leaflet gesetzt
---
## 📁 Schlüsselfunktionen & Module
| Bereich | Datei/Modul | Aufgabe |
| ------------- | --------------------------------------------------------------- | ---------------------------------------- |
| Kartenlogik | `MapComponent.js` | Zentrale Initialisierung und Layer-Logik |
| Webservices | `services/webservice/` | Kommunikation mit TALAS V5 Webservice |
| Datenbank | `services/database/` | Zugriff auf lokale Next.js-API & DB |
| POIs | `AddPOIModal.js`, `PoiUpdateModal.js` | UI für POI-Erstellung & -Bearbeitung |
| Redux | `redux/slices/`, `redux/thunks/`, `redux/store` | Globaler State, API-Steuerung |
| Konfiguration | `.env.development`,`.env.production`, `config.js`, dynamic URLs | IP, basePath, Ports |
---
## 🧩 Besonderheiten
- **Konfigurierbarer basePath:**
- **Konfigurierbarer basePath:**
Pfad wie `/talas5` ist optional und wird jetzt in `public/config.json` als `basePath` gepflegt
werden.
Die Konfiguration erfolgt je nach Umgebung über:
- `.env.development` für lokale Entwicklung
- `.env.production` für produktiven Einsatz
- **Rechteabhängige UI:**
Funktionen (z.B. POI bearbeiten) basieren auf Benutzerrechten (`IdRight`) vom Server.
- **Zentrale Komponentensteuerung:**
Komponenten wie `MapLayersControlPanel` oder `CoordinatePopup` kontrollieren Layer & Interaktion.
- **Kontextmenü-Logik:**
Marker & Polylinien besitzen eigene Kontextmenüs dynamisch zusammengesetzt und verwaltet.
---
## 📦 Versionierung & Builds
- Version wird mit Husky Bibliothek automatisch erhöhert in `scripts/bumpVersion.js`
---
## 📚 Weiterführende Dokumentation
- [`build-and-deploy.md`](./build-and-deploy.md)
- [`env.local.schema.md`](./env.local.schema.md)
- [`redux/slices/`](./redux/slices/)
- [`services/webservice/`](./services/webservice/)
---
## Dynamische Layer-Verwaltung mit Redux
```mermaid
flowchart TD
%% Webservice
subgraph Webservice
A1[GisSystemStatic API]
A2[GisStationsStaticDistrict API]
end
%% Redux
subgraph Redux
B1[fetchGisSystemStaticThunk]
B2[fetchGisStationsStaticDistrictThunk]
C1["gisSystemStaticSlice → selectGisSystemStatic"]
C2["gisStationsStaticDistrictSlice → selectGisStationsStaticDistrict"]
C3["mapLayersSlice → mapLayersVisibility"]
end
%% React
subgraph React-Komponente
D1[MapComponent.js]
D2["useEffect: dynamische Layer"]
D3["createAndSetDevices"]
D4["layerRefs (useRef)"]
D5["markerStates (useState)"]
D6["useEffect: Sichtbarkeit prüfen"]
D7["Map aktualisieren / add/remove"]
D8["checkOverlappingMarkers"]
end
%% Datenfluss
A1 --> B1 --> C1 --> D2
A2 --> B2 --> C2 --> D3
C3 --> D6
D2 --> D3
D3 --> D4
D3 --> D5
D5 --> D6
D6 --> D7
D6 --> D8
D7 --> D1
```
---
Jetzt (dynamisch & Redux-basiert): MapComponent.js ruft folgenden Hook auf:
js Copy Edit const { markerStates, layerRefs } = useDynamicDeviceLayers(map, GisSystemStatic,
mapLayersVisibility, priorityConfig, oms); useDynamicDeviceLayers.js verarbeitet die
GisSystemStatic-Liste:
Jedes System (z.B. "TALAS", "ECI", "Cisco") bekommt einen eigenen Marker-Layer.
Die Marker werden erstellt durch:
js Copy Edit createAndSetDevices(...) // Systemweise Marker erzeugen createAndSetDevices.js:
Filtert alle Stations aus staticDistrictData, deren System === IdSystem.
Erstellt Marker für jedes Gerät.
Bindet Popup, Kontextmenü, Styling, Bounce usw.
Ruft setMarkersFunction(markers) auf → Übergibt die Marker zurück an den Hook.
Der Hook speichert:
js Copy Edit setMarkerStates((prev) => ({ ...prev, [Name]: newMarkers })); MapComponent.js hat dann:
Zugriff auf alle Marker dynamisch über markerStates (ein Objekt mit Schlüssel = Systemname)
Sichtbarkeit und OverlappingMarkerSpiderfier werden damit verarbeitet.
---
🔁 Die Geräte-Marker sind nicht mehr fest codiert, sondern werden dynamisch erzeugt anhand der
Webservice-Daten GisSystemStatic.
🔄 Sichtbarkeit (Checkbox im Control Panel) löst ein Event visibilityChanged aus → MapComponent
reagiert und rendert Marker neu.
🕷️ Überlappende Marker werden mit checkOverlappingMarkers + PlusRoundIcon verarbeitet.
```mermaid
flowchart TD
A1[MapComponent] --> B1[useDynamicDeviceLayers]
B1 --> C1[loop über GisSystemStatic]
C1 --> D1[createAndSetDevices]
D1 --> E1[Filter stations aus Redux]
E1 --> F1[erstelle Marker /Leaflet]
F1 --> G1[Marker in LayerGroup einfügen]
G1 --> H1[setMarkerStates im Hook]
H1 --> A2[markerStates zurück nach MapComponent]
A2 --> I1[Map aktualisiert Marker]
A2 --> I2[checkOverlappingMarkers mit OMS]
```
---
10.06.2025
# Datenfluss-Konzept: WebSocket ↔ Redux ↔ UI
Dieses Dokument beschreibt den technischen Ablauf des Live-Datenflusses im NodeMap-Projekt, um neue
Entwickler\:innen beim Onboarding zu unterstützen.
## ᵀᵃᵗᵉᵖᵏᴼᵏᴼᵉ: Architekturübersicht
```mermaid
sequenceDiagram
autonumber
participant WS_Server as WebSocket Server
participant WebService as TALAS WebService
participant Browser
participant ReduxStore as Redux Store
participant UI as React Leaflet UI
loop Alle 5 Sekunden
WS_Server->>WebService: fetch endpointX
alt Daten haben sich geändert
WS_Server-->>Browser: emit 'endpointXUpdated'
Browser->>ReduxStore: dispatch(fetchEndpointXThunk())
ReduxStore->>WebService: fetch endpointX
WebService-->>ReduxStore: JSON response
ReduxStore-->>UI: update Slice
UI-->>User: re-render Markers
else Keine Änderung
WS_Server-->>WS_Server: keine Aktion
end
end
```
## Beteiligte Komponenten
### WebSocket Server (`server.js`)
- Ruft regelmäßig (`setInterval`) die Webservice-Endpunkte auf.
- Erkennt Änderungen durch JSON-Vergleich (`JSON.stringify`).
- Sendet WebSocket-Events nur bei echten Änderungen.
### Client: MapComponent
- Hört auf `socket.on("endpointXUpdated")`.
- Ruft dann gezielt den passenden Redux-Thunk auf (z.B. `fetchGisLinesStatusThunk`).
### Redux Store & Thunks
- Jeder Endpunkt besitzt:
- einen `Service` (API-Fetch)
- einen `Thunk` (Redux-Logik)
- einen `Slice` (State-Verwaltung)
### React UI (Leaflet Map)
- Beobachtet relevante Redux-Slices via `useSelector()`.
- Aktualisiert Marker, Tooltip und Popup über `createAndSetDevices()` und
`useDynamicDeviceLayers()`.
## Beispiel-Endpunkte
| Endpunktname | WebSocket Event | Redux Thunk |
| --------------------------- | ---------------------------------- | --------------------------------------- |
| `GisLinesStatus` | `GisLinesStatusUpdated` | `fetchGisLinesStatusThunk()` |
| `GisStationsMeasurements` | `GisStationsMeasurementsUpdated` | `fetchGisStationsMeasurementsThunk()` |
| `GisStationsStaticDistrict` | `GisStationsStaticDistrictUpdated` | `fetchGisStationsStaticDistrictThunk()` |
| `GisStationsStatusDistrict` | `GisStationsStatusDistrictUpdated` | `fetchGisStationsStatusDistrictThunk()` |
## Vorteile
- UI aktualisiert sich nur bei echten Datenänderungen → weniger Re-Renders.
- Live-Synchronisation zwischen Datenquelle und Anzeige.
- Skalierbar für beliebige Endpunkte.
## ToDo/Erweiterungen
- Automatische Reconnect-Logik für WebSocket.
- Anzeige des letzten Update-Zeitpunkts in UI.
- Logging-UI für WebSocket-Messages zur Diagnose.
---
> Letzte Änderung: `{{heutiges Datum}}` von Ismail Ali
---
[Zurück zur Übersicht](README.md)