fix: Marker-Duplikate & Spiderfy repariert | version 1.1.230
This commit is contained in:
261
CHANGELOG.md
261
CHANGELOG.md
@@ -4,17 +4,39 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
|
||||
|
||||
---
|
||||
|
||||
## [1.1.230] – 2025-06-04
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
- Gerätemarker wurden bei jeder Datenaktualisierung mehrfach gezeichnet → Marker-Layer vor dem
|
||||
Neuladen jetzt korrekt geleert
|
||||
- OverlappingMarkerSpiderfier (Spiderfy) bei überlappenden Geräten reaktiviert
|
||||
|
||||
### ♻️ Refactor
|
||||
|
||||
- Markerlogik in `useDynamicDeviceLayers.js` verbessert: Sichtbarkeit, Ersetzung und OMS-Handling
|
||||
zentral geregelt
|
||||
|
||||
### 🔧 Version
|
||||
|
||||
- 📦 `appVersion.js` auf Version `1.1.230` erhöht
|
||||
|
||||
---
|
||||
|
||||
## [1.1.216] – 2025-06-02
|
||||
|
||||
### Hinzugefügt
|
||||
|
||||
- Einheitliche Verwendung der Funktion `openInNewTab()` für Kontextmenü-Link bei Geräten, Linien und GMA.
|
||||
- Kontextmenüpunkt „Station öffnen (Tab)“ öffnet nun korrekt `/devices/cpl.aspx?...` anstelle von z. B. `/cpl.aspx?...`.
|
||||
- Einheitliche Verwendung der Funktion `openInNewTab()` für Kontextmenü-Link bei Geräten, Linien und
|
||||
GMA.
|
||||
- Kontextmenüpunkt „Station öffnen (Tab)“ öffnet nun korrekt `/devices/cpl.aspx?...` anstelle von
|
||||
z. B. `/cpl.aspx?...`.
|
||||
|
||||
### Geändert
|
||||
|
||||
- Port 3000 wird aus generierten Links entfernt (auch in Entwicklungsumgebung).
|
||||
- `setupPolylines.js`, `contextMenuUtils.js` und `useGmaMarkersLayer.js` angepasst, um einheitliche Navigation zu gewährleisten.
|
||||
- `setupPolylines.js`, `contextMenuUtils.js` und `useGmaMarkersLayer.js` angepasst, um einheitliche
|
||||
Navigation zu gewährleisten.
|
||||
|
||||
---
|
||||
|
||||
@@ -23,12 +45,14 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
|
||||
### Hinzugefügt
|
||||
|
||||
- Leaflet-Kontextmenü für Geräte-Marker (Stations/Geräte) aktiviert
|
||||
- Menüpunkt „Station öffnen (Tab)“ erscheint nun direkt im Marker-Kontextmenü, basierend auf `marker.options.link`
|
||||
- Menüpunkt „Station öffnen (Tab)“ erscheint nun direkt im Marker-Kontextmenü, basierend auf
|
||||
`marker.options.link`
|
||||
- Redux-Abhängigkeit (`selectedDevice`) für Kontextmenü entfernt
|
||||
|
||||
### Geändert
|
||||
|
||||
- `addContextMenuToMarker` prüft nun direkt auf `marker.options.idDevice` und `link` anstatt globalen Zustand
|
||||
- `addContextMenuToMarker` prüft nun direkt auf `marker.options.idDevice` und `link` anstatt
|
||||
globalen Zustand
|
||||
|
||||
---
|
||||
|
||||
@@ -38,11 +62,13 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
|
||||
|
||||
- Dynamische Initialisierung aller Gerätegruppen-Layer (system-<IdSystem>) über GIS-Systemdaten.
|
||||
- Automatische Sichtbarkeitssteuerung in `mapLayersSlice` basierend auf `IdSystem`.
|
||||
- Mermaid-Diagramm zur Dokumentation der Architektur in `/docs/architecture/device-layer-connection-final.md`.
|
||||
- Mermaid-Diagramm zur Dokumentation der Architektur in
|
||||
`/docs/architecture/device-layer-connection-final.md`.
|
||||
|
||||
### Changed
|
||||
|
||||
- Vergleichslogik zwischen `gisStationsStaticDistrict[].System` und `gisSystemStatic[].IdSystem` von `Name` auf `IdSystem` umgestellt.
|
||||
- Vergleichslogik zwischen `gisStationsStaticDistrict[].System` und `gisSystemStatic[].IdSystem` von
|
||||
`Name` auf `IdSystem` umgestellt.
|
||||
- `MapLayersControlPanel` verwendet jetzt konsistent `system-<IdSystem>` als Key.
|
||||
- `useDynamicDeviceLayers` baut Layer-Gruppen und Marker-Zuordnung ebenfalls über `IdSystem` auf.
|
||||
|
||||
@@ -57,7 +83,8 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
|
||||
### 🐞 Fixed
|
||||
|
||||
- Fehler behoben: Kontextmenü „Station öffnen (Tab)“ wurde bei Geräten/Stationen mehrfach angezeigt
|
||||
- Ursache war doppelte Registrierung bei jedem Rechtsklick – jetzt mit `contextMenuCreated`-Flag verhindert
|
||||
- Ursache war doppelte Registrierung bei jedem Rechtsklick – jetzt mit `contextMenuCreated`-Flag
|
||||
verhindert
|
||||
- Datei `createAndSetDevices.js` entsprechend angepasst
|
||||
|
||||
### 🔧 Version
|
||||
@@ -66,13 +93,11 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
|
||||
|
||||
---
|
||||
|
||||
[1.1.190] – 2025-05-27
|
||||
🐞 Fixed
|
||||
Dropdown im UI Widget MapLayersControlPanel zeigte keine Stations-/Bereichsnamen an
|
||||
🔧 Fehler behoben: Zugriff auf GisStationsStaticDistrict.Points statt auf das Objekt selbst
|
||||
[1.1.190] – 2025-05-27 🐞 Fixed Dropdown im UI Widget MapLayersControlPanel zeigte keine
|
||||
Stations-/Bereichsnamen an 🔧 Fehler behoben: Zugriff auf GisStationsStaticDistrict.Points statt auf
|
||||
das Objekt selbst
|
||||
|
||||
📄 Dokumentation
|
||||
Neue technische Markdown-Dokumentationen erstellt:
|
||||
📄 Dokumentation Neue technische Markdown-Dokumentationen erstellt:
|
||||
|
||||
/docs/components/uiWidgets/mapLayersControlPanel/MapLayersControlPanel.md
|
||||
|
||||
@@ -82,8 +107,7 @@ Neue technische Markdown-Dokumentationen erstellt:
|
||||
|
||||
/docs/components/uiWidgets/CoordinateInput.md
|
||||
|
||||
🔧 Version
|
||||
📦 Version erhöht auf 1.1.190
|
||||
🔧 Version 📦 Version erhöht auf 1.1.190
|
||||
|
||||
---
|
||||
|
||||
@@ -97,7 +121,8 @@ Neue technische Markdown-Dokumentationen erstellt:
|
||||
|
||||
### 🧠 Architektur
|
||||
|
||||
- `fetchGisLinesStatusService.js`, `fetchGisStationsStaticDistrictService.js`, `useGmaMarkersLayer.js`, `setupPolylines.js` u. a. angepasst
|
||||
- `fetchGisLinesStatusService.js`, `fetchGisStationsStaticDistrictService.js`,
|
||||
`useGmaMarkersLayer.js`, `setupPolylines.js` u. a. angepasst
|
||||
- Links wie `Station öffnen (Tab)` oder WebService-URLs bauen sich nun dynamisch je nach basePath
|
||||
|
||||
### 📄 Dokumentation
|
||||
@@ -118,7 +143,8 @@ Neue technische Markdown-Dokumentationen erstellt:
|
||||
`/docs/pages/api/talas_v5_DB/priorityConfig.md`
|
||||
- Beschreibt die API `/api/talas_v5_DB/priorityConfig`
|
||||
- Enthält Beispielantwort, Datenstruktur, SQL, Fehlerhandling
|
||||
- Besonderheit: Anwendung der Prioritätswerte (`level`) zur Sortierung von Leaflet-Markern bei Überlappung
|
||||
- Besonderheit: Anwendung der Prioritätswerte (`level`) zur Sortierung von Leaflet-Markern bei
|
||||
Überlappung
|
||||
|
||||
### 🧠 Architektur
|
||||
|
||||
@@ -162,8 +188,10 @@ Neue technische Markdown-Dokumentationen erstellt:
|
||||
### 🔥 Removed
|
||||
|
||||
- Verzeichnis `/webServiceMockdata/` vollständig gelöscht
|
||||
- Alle früheren Mock-Daten wurden durch einen realistischen Setup mit MySQL (Docker) und TALAS.web (unter IIS) ersetzt
|
||||
- Kein fetch() oder Dateizugriff auf diese Daten mehr im Projekt vorhanden (geprüft via VSCode „Find in Files“)
|
||||
- Alle früheren Mock-Daten wurden durch einen realistischen Setup mit MySQL (Docker) und TALAS.web
|
||||
(unter IIS) ersetzt
|
||||
- Kein fetch() oder Dateizugriff auf diese Daten mehr im Projekt vorhanden (geprüft via VSCode
|
||||
„Find in Files“)
|
||||
- Die Tests laufen nun gegen reale Backends (lokal & remote)
|
||||
|
||||
### 🧠 Architektur
|
||||
@@ -203,13 +231,12 @@ Neue technische Markdown-Dokumentationen erstellt:
|
||||
|
||||
---
|
||||
|
||||
📦 [1.1.183] – 2025-05-27
|
||||
♻️ Refactor
|
||||
Die Hilfsfunktion saveLineData() wurde vollständig entfernt:
|
||||
📦 [1.1.183] – 2025-05-27 ♻️ Refactor Die Hilfsfunktion saveLineData() wurde vollständig entfernt:
|
||||
|
||||
In markerUtils.js und poiUtils.js ersetzt durch updatePolylineCoordinatesThunk via Redux
|
||||
|
||||
Zentrale Dispatch-Hilfsfunktion savePolylineRedux() erstellt für alle Linienaktionen (Einfügen, Verschieben, Entfernen)
|
||||
Zentrale Dispatch-Hilfsfunktion savePolylineRedux() erstellt für alle Linienaktionen (Einfügen,
|
||||
Verschieben, Entfernen)
|
||||
|
||||
Einheitliche Verwendung des Redux-Dispatch in Utility-Dateien:
|
||||
|
||||
@@ -219,13 +246,11 @@ Fehlerbehandlung über .unwrap().catch(...) integriert
|
||||
|
||||
Map-Utilities und POI-Utilities sind nun Redux-kompatibel und testbar
|
||||
|
||||
✅ Clean
|
||||
saveLineData aus mapUtils.js gelöscht
|
||||
✅ Clean saveLineData aus mapUtils.js gelöscht
|
||||
|
||||
Alle Marker-Operationen speichern ihre Koordinaten ausschließlich über Redux
|
||||
|
||||
🧠 Architektur
|
||||
Redux-Toolkit Standardstruktur umgesetzt:
|
||||
🧠 Architektur Redux-Toolkit Standardstruktur umgesetzt:
|
||||
|
||||
updatePolylineCoordinatesService.js
|
||||
|
||||
@@ -233,10 +258,10 @@ updatePolylineCoordinatesThunk.js
|
||||
|
||||
Nutzung außerhalb React-Komponenten über store.dispatch(...)
|
||||
|
||||
Leaflet-Logik (z. B. marker.setLatLng(), map.removeLayer()) bleibt in Utility-Dateien – Redux kümmert sich nur um Daten
|
||||
Leaflet-Logik (z. B. marker.setLatLng(), map.removeLayer()) bleibt in Utility-Dateien – Redux
|
||||
kümmert sich nur um Daten
|
||||
|
||||
🔧 Version
|
||||
📦 Version erhöht auf 1.1.183
|
||||
🔧 Version 📦 Version erhöht auf 1.1.183
|
||||
|
||||
---
|
||||
|
||||
@@ -272,18 +297,18 @@ Leaflet-Logik (z. B. marker.setLatLng(), map.removeLayer()) bleibt in Utility-
|
||||
|
||||
---
|
||||
|
||||
[1.1.181] – 2025-05-26
|
||||
♻️ Refactor
|
||||
setupPolylines.js von direktem fetch() auf sauberes Redux-Muster umgestellt:
|
||||
[1.1.181] – 2025-05-26 ♻️ Refactor setupPolylines.js von direktem fetch() auf sauberes Redux-Muster
|
||||
umgestellt:
|
||||
|
||||
Statt fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates") wird jetzt updatePolylineCoordinatesThunk() verwendet
|
||||
Statt fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates") wird jetzt
|
||||
updatePolylineCoordinatesThunk() verwendet
|
||||
|
||||
Die Request-Daten werden an ein zentrales Service-Modul (updatePolylineCoordinatesService.js) übergeben
|
||||
Die Request-Daten werden an ein zentrales Service-Modul (updatePolylineCoordinatesService.js)
|
||||
übergeben
|
||||
|
||||
Async-Handling erfolgt über .unwrap().then().catch() zur besseren Fehlerkontrolle
|
||||
|
||||
🧠 Architektur
|
||||
Einheitliches Redux-Schema umgesetzt:
|
||||
🧠 Architektur Einheitliches Redux-Schema umgesetzt:
|
||||
|
||||
Service: updatePolylineCoordinatesService.js
|
||||
|
||||
@@ -293,19 +318,15 @@ Thunk: updatePolylineCoordinatesThunk.js
|
||||
|
||||
Redux Toolkit-konforme store.dispatch(...)-Verwendung in Utility-Datei (außerhalb von React-Kontext)
|
||||
|
||||
✅ Clean
|
||||
Alle direkten fetch-Aufrufe aus setupPolylines.js entfernt
|
||||
✅ Clean Alle direkten fetch-Aufrufe aus setupPolylines.js entfernt
|
||||
|
||||
Kein hartcodiertes URL-Handling mehr – alles läuft über zentrale Redux-Logik
|
||||
|
||||
🔧 Version
|
||||
📦 Version erhöht auf 1.1.181
|
||||
🔧 Version 📦 Version erhöht auf 1.1.181
|
||||
|
||||
---
|
||||
|
||||
[1.1.180] – 2025-05-26
|
||||
♻️ Refactor
|
||||
poiTypesSlice.js wurde bereinigt:
|
||||
[1.1.180] – 2025-05-26 ♻️ Refactor poiTypesSlice.js wurde bereinigt:
|
||||
|
||||
Alte createAsyncThunk-Definition entfernt (direkter fetch im Slice)
|
||||
|
||||
@@ -317,26 +338,24 @@ Service → Thunk → Slice
|
||||
|
||||
Keine Logik mehr im Slice selbst
|
||||
|
||||
Verwendete Komponenten (MapComponent, AddPOIModal) rufen jetzt korrekt dispatch(fetchPoiTypThunk()) auf
|
||||
Verwendete Komponenten (MapComponent, AddPOIModal) rufen jetzt korrekt dispatch(fetchPoiTypThunk())
|
||||
auf
|
||||
|
||||
🐞 Fixed
|
||||
Fehler fetchPoiTypes is not a function behoben durch Entfernen des alten Imports aus poiTypesSlice
|
||||
🐞 Fixed Fehler fetchPoiTypes is not a function behoben durch Entfernen des alten Imports aus
|
||||
poiTypesSlice
|
||||
|
||||
Richtiger Import fetchPoiTypThunk nun überall verwendet
|
||||
|
||||
🧠 Architektur
|
||||
Redux-Slice enthält nur noch Zustand & Status – keine Abfragen mehr
|
||||
🧠 Architektur Redux-Slice enthält nur noch Zustand & Status – keine Abfragen mehr
|
||||
|
||||
fetchPoiTypService.js stellt fetch()-Logik bereit, Thunk übernimmt Fehlerbehandlung
|
||||
|
||||
🔧 Version
|
||||
📦 Version erhöht auf 1.1.180
|
||||
🔧 Version 📦 Version erhöht auf 1.1.180
|
||||
|
||||
---
|
||||
|
||||
[1.1.177] – 2025-05-26
|
||||
✨ UI-Verbesserung
|
||||
POI-Tooltip auf der Karte wird jetzt bei Mouseover angezeigt (nicht mehr per Klick).
|
||||
[1.1.177] – 2025-05-26 ✨ UI-Verbesserung POI-Tooltip auf der Karte wird jetzt bei Mouseover
|
||||
angezeigt (nicht mehr per Klick).
|
||||
|
||||
Tooltip ist einheitlich gestaltet mit Tailwind CSS:
|
||||
|
||||
@@ -350,46 +369,41 @@ Blaue Überschrift, graue Beschriftung
|
||||
|
||||
Einheitlicher Stil für alle Marker-Tooltips (setupPOIs.js angepasst).
|
||||
|
||||
✅ Clean
|
||||
Alte bindPopup()-Logik entfernt – kein manuelles Öffnen/Schließen mehr nötig
|
||||
✅ Clean Alte bindPopup()-Logik entfernt – kein manuelles Öffnen/Schließen mehr nötig
|
||||
|
||||
closePopup() aus mouseout-Handler entfernt
|
||||
|
||||
Tooltip verwendet sticky: true, folgt der Maus
|
||||
|
||||
🔧 Version
|
||||
📦 Version erhöht auf 1.1.177
|
||||
🔧 Version 📦 Version erhöht auf 1.1.177
|
||||
|
||||
---
|
||||
|
||||
[1.1.176] – 2025-05-26
|
||||
🐞 Fixed
|
||||
Problem behoben, dass das Modal „POI hinzufügen“ nach erfolgreichem Submit nicht geschlossen wurde und die Meldung „Wird hinzugefügt…“ dauerhaft sichtbar blieb.
|
||||
[1.1.176] – 2025-05-26 🐞 Fixed Problem behoben, dass das Modal „POI hinzufügen“ nach erfolgreichem
|
||||
Submit nicht geschlossen wurde und die Meldung „Wird hinzugefügt…“ dauerhaft sichtbar blieb.
|
||||
|
||||
Ursache: Die Service-Datei addPoiService.js verwendete die falsche URL /addLocation statt /addPoi.
|
||||
|
||||
Die unwrap()-Verwendung im AddPOIModal.js wurde beibehalten und korrekt abgeschlossen.
|
||||
|
||||
✅ Clean
|
||||
resetAddPoiStatus() wird jetzt direkt nach onClose() dispatcht, um Status in Redux auf idle zurückzusetzen.
|
||||
✅ Clean resetAddPoiStatus() wird jetzt direkt nach onClose() dispatcht, um Status in Redux auf idle
|
||||
zurückzusetzen.
|
||||
|
||||
Ladeindikator „Wird hinzugefügt...“ wird zuverlässig entfernt.
|
||||
|
||||
Fehleranzeige funktioniert weiterhin über Redux (status === "failed" und error).
|
||||
|
||||
🧠 Architektur
|
||||
Vollständige Redux-Anbindung des Modals über addPoiSlice, addPoiThunk, addPoiService und addPoi.js.
|
||||
🧠 Architektur Vollständige Redux-Anbindung des Modals über addPoiSlice, addPoiThunk, addPoiService
|
||||
und addPoi.js.
|
||||
|
||||
Thunk-Erfolg löst incrementTrigger() aus und synchronisiert die Marker auf der Karte durch erneutes Laden via fetchPoiMarkersThunk().
|
||||
Thunk-Erfolg löst incrementTrigger() aus und synchronisiert die Marker auf der Karte durch erneutes
|
||||
Laden via fetchPoiMarkersThunk().
|
||||
|
||||
🔧 Version
|
||||
📦 Version erhöht auf 1.1.176
|
||||
🔧 Version 📦 Version erhöht auf 1.1.176
|
||||
|
||||
---
|
||||
|
||||
[1.1.174] – 2025-05-26
|
||||
♻️ Refactor
|
||||
useDrawLines.js vollständig auf Redux umgestellt:
|
||||
[1.1.174] – 2025-05-26 ♻️ Refactor useDrawLines.js vollständig auf Redux umgestellt:
|
||||
|
||||
Entfernt: direkter fetch("/api/talas_v5_DB/gisLines/readGisLines")
|
||||
|
||||
@@ -397,8 +411,7 @@ Stattdessen: Redux fetchGisLinesThunk() + selectGisLines verwendet
|
||||
|
||||
Datenverarbeitung der points erfolgt reaktiv über Redux-State
|
||||
|
||||
🧠 Architektur
|
||||
useDrawLines.js verwendet jetzt:
|
||||
🧠 Architektur useDrawLines.js verwendet jetzt:
|
||||
|
||||
fetchGisLinesService (Service)
|
||||
|
||||
@@ -408,21 +421,17 @@ gisLinesSlice mit Selektor selectGisLines
|
||||
|
||||
State wird automatisch im Redux verwaltet (loading/succeeded/failed)
|
||||
|
||||
✅ Cleanup
|
||||
Promise-Kette .then().catch() durch useSelector-basierten Effekt ersetzt
|
||||
✅ Cleanup Promise-Kette .then().catch() durch useSelector-basierten Effekt ersetzt
|
||||
|
||||
Fehlerausgabe bei ungültigen points strukturiert behandelt
|
||||
|
||||
Hook ist nun Redux-konform und testbar
|
||||
|
||||
🔧 Version
|
||||
📦 Version erhöht auf 1.1.174
|
||||
🔧 Version 📦 Version erhöht auf 1.1.174
|
||||
|
||||
---
|
||||
|
||||
[1.1.173] – 2025-05-26
|
||||
♻️ Refactor
|
||||
useMapComponentState.js vollständig auf Redux umgestellt:
|
||||
[1.1.173] – 2025-05-26 ♻️ Refactor useMapComponentState.js vollständig auf Redux umgestellt:
|
||||
|
||||
Entfernt: lokale fetch(...)-Aufrufe
|
||||
|
||||
@@ -436,22 +445,19 @@ priorityConfig → über priorityConfigSlice + fetchPriorityConfigThunk
|
||||
|
||||
poiLayerVisible → direkter Zugriff über Redux-Zustand
|
||||
|
||||
🧠 Architektur
|
||||
useMapComponentState.js ist jetzt rein selektorbasiert
|
||||
🧠 Architektur useMapComponentState.js ist jetzt rein selektorbasiert
|
||||
|
||||
Standardstruktur Service → Thunk → Slice vollständig eingehalten
|
||||
|
||||
Komponente reagiert nur noch auf Redux-Status (z. B. poiTypStatus === "succeeded")
|
||||
|
||||
✅ Cleanup
|
||||
useState() für priorityConfig und locationDeviceData entfernt
|
||||
✅ Cleanup useState() für priorityConfig und locationDeviceData entfernt
|
||||
|
||||
deviceName wird direkt aus Redux-Daten abgeleitet
|
||||
|
||||
Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
🔧 Version
|
||||
📦 Version erhöht auf 1.1.173
|
||||
🔧 Version 📦 Version erhöht auf 1.1.173
|
||||
|
||||
---
|
||||
|
||||
@@ -460,7 +466,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
### 🐞 Fixed
|
||||
|
||||
- POI-Icons wurden immer als `poi-marker-icon-4.png` dargestellt, egal welcher Typ
|
||||
- Ursache: `setupPOIs.js` hat versehentlich `poi.idPoi === poi.idPoi` geprüft statt `poi.idPoiTyp === ...`
|
||||
- Ursache: `setupPOIs.js` hat versehentlich `poi.idPoi === poi.idPoi` geprüft statt
|
||||
`poi.idPoiTyp === ...`
|
||||
|
||||
### ✅ Clean
|
||||
|
||||
@@ -591,7 +598,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
- Fehler behoben: `userRights.includes(56)` schlug fehl, da Rechteobjekte `{ IdRight }` enthalten – ersetzt durch `.some(r => r.IdRight === 56)`
|
||||
- Fehler behoben: `userRights.includes(56)` schlug fehl, da Rechteobjekte `{ IdRight }` enthalten –
|
||||
ersetzt durch `.some(r => r.IdRight === 56)`
|
||||
- Kontextmenü „POI bearbeiten“ wird jetzt korrekt angezeigt
|
||||
- Modal öffnet sich nur noch bei gültiger Berechtigung (56)
|
||||
|
||||
@@ -630,7 +638,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
- Bug behoben: neu hinzugefügter POI zeigte Standard-Icon → Icon-Liste wird nach dem Hinzufügen erneut geladen
|
||||
- Bug behoben: neu hinzugefügter POI zeigte Standard-Icon → Icon-Liste wird nach dem Hinzufügen
|
||||
erneut geladen
|
||||
|
||||
### ✅ Clean
|
||||
|
||||
@@ -675,11 +684,13 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
### Removed
|
||||
|
||||
- `config.js` vollständig gelöscht – keine Abhängigkeiten mehr im Projekt
|
||||
- Funktion `isMockMode()` entfernt – direkter Zugriff auf `process.env.NEXT_PUBLIC_USE_MOCK_API` ersetzt zentrale Hilfsfunktion
|
||||
- Funktion `isMockMode()` entfernt – direkter Zugriff auf `process.env.NEXT_PUBLIC_USE_MOCK_API`
|
||||
ersetzt zentrale Hilfsfunktion
|
||||
|
||||
### Changed
|
||||
|
||||
- `fetchUserRightsService.js`, `fetchGisSystemStaticService.js` und `useMapComponentState.js` angepasst:
|
||||
- `fetchUserRightsService.js`, `fetchGisSystemStaticService.js` und `useMapComponentState.js`
|
||||
angepasst:
|
||||
- Verwendet dynamisch `window.location` + `.env.local` statt config.js
|
||||
- Verbesserte Übersichtlichkeit und zentrale Steuerung über `.env.local`
|
||||
|
||||
@@ -700,7 +711,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### Entfernt
|
||||
|
||||
- `webserviceGisLinesStatusUrl` aus `config.js` entfernt – URL wird zentral in `fetchGisLinesStatusService.js` aufgebaut.
|
||||
- `webserviceGisLinesStatusUrl` aus `config.js` entfernt – URL wird zentral in
|
||||
`fetchGisLinesStatusService.js` aufgebaut.
|
||||
|
||||
### Geändert
|
||||
|
||||
@@ -718,7 +730,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### Geändert
|
||||
|
||||
- `MapComponent.js` angepasst: `useLoadUserRights.js` entfernt, stattdessen Thunk + Selector verwendet
|
||||
- `MapComponent.js` angepasst: `useLoadUserRights.js` entfernt, stattdessen Thunk + Selector
|
||||
verwendet
|
||||
- `fetchUserRightsThunk` direkt in `MapComponent.js` integriert
|
||||
|
||||
### Architektur
|
||||
@@ -754,13 +767,15 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
### Changed
|
||||
|
||||
- 🔁 Geräte-/Stationsanzeige vollständig auf **Redux-Store** umgestellt:
|
||||
- `createAndSetDevices.js` verwendet jetzt nur noch Redux-Selectoren (`selectGisStationsStaticDistrict`, `selectGisStationsStatusDistrict`)
|
||||
- `createAndSetDevices.js` verwendet jetzt nur noch Redux-Selectoren
|
||||
(`selectGisStationsStaticDistrict`, `selectGisStationsStatusDistrict`)
|
||||
- Entfernt: direkter `fetch(...)`-Zugriff über `config.js`
|
||||
- Kein Zugriff mehr auf `mapGisStationsStaticDistrictUrl` / `StatusDistrictUrl`
|
||||
|
||||
### Fixed
|
||||
|
||||
- ✅ Fehler "❌ Redux enthält keine gültigen Geräte-/Statusdaten!" gelöst durch korrekte Abfrage `state.gisStationsStaticDistrict.data.Points`
|
||||
- ✅ Fehler "❌ Redux enthält keine gültigen Geräte-/Statusdaten!" gelöst durch korrekte Abfrage
|
||||
`state.gisStationsStaticDistrict.data.Points`
|
||||
- ✅ Marker erscheinen wieder zuverlässig durch saubere Trennung von Datenquelle und Darstellung
|
||||
|
||||
### Architecture
|
||||
@@ -815,7 +830,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
### Refactored
|
||||
|
||||
- Entfernt: manuelle Fetch-Funktion und lokalen `isDataLoaded`-State für `DataSheet`
|
||||
- Hinzugefügt: Anzeige des Panels erfolgt jetzt über Redux Store (`GisStationsStaticDistrict.Points`)
|
||||
- Hinzugefügt: Anzeige des Panels erfolgt jetzt über Redux Store
|
||||
(`GisStationsStaticDistrict.Points`)
|
||||
- Verbesserte Kontrolle über Sichtbarkeit der Layer-Steuerung auf Basis von Store-Daten
|
||||
|
||||
---
|
||||
@@ -829,7 +845,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
- Neuer Thunk: `fetchGisLinesThunk.js` unter `/redux/thunks/database/`
|
||||
- Neuer Slice: `gisLinesSlice.js` mit Statusverwaltung (idle/loading/succeeded/failed)
|
||||
- Redux-Selektor `selectGisLines` in `MapComponent.js` genutzt
|
||||
- Direkter `fetch("/api/talas_v5_DB/gisLines/readGisLines")` entfernt und durch `dispatch(fetchGisLinesThunk())` ersetzt
|
||||
- Direkter `fetch("/api/talas_v5_DB/gisLines/readGisLines")` entfernt und durch
|
||||
`dispatch(fetchGisLinesThunk())` ersetzt
|
||||
- Alle Linien-Daten werden nun zentral über Redux geladen und in `linePositions` umgewandelt
|
||||
|
||||
### Version
|
||||
@@ -852,8 +869,10 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### Fixed
|
||||
|
||||
- ❌ Fehler `fetchPriorityConfigThunk is not defined` behoben durch Import und richtigen Store-Zugriff
|
||||
- ❌ Bug: Redux Slice zeigte keine Daten – Ursache war fehlendes `dispatch` der Thunk-Funktion → behoben
|
||||
- ❌ Fehler `fetchPriorityConfigThunk is not defined` behoben durch Import und richtigen
|
||||
Store-Zugriff
|
||||
- ❌ Bug: Redux Slice zeigte keine Daten – Ursache war fehlendes `dispatch` der Thunk-Funktion →
|
||||
behoben
|
||||
|
||||
### Cleanup
|
||||
|
||||
@@ -862,7 +881,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
### Architekturhinweis
|
||||
|
||||
- 🔄 Komponente wie `MapComponent` ist der Trigger:
|
||||
Thunks, Services und Redux-Slices alleine führen nichts aus – sie müssen durch ein `dispatch(...)` aktiviert werden.
|
||||
Thunks, Services und Redux-Slices alleine führen nichts aus – sie müssen durch ein `dispatch(...)`
|
||||
aktiviert werden.
|
||||
|
||||
### Version
|
||||
|
||||
@@ -875,10 +895,13 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
### Changed
|
||||
|
||||
- 🧱 `fetchLocationDevices.js` wurde vollständig entfernt (lag zuvor unter `/redux/api/fromDB/`)
|
||||
- Stattdessen wird der neue Service `fetchLocationDevicesService.js` in `/services/database/` verwendet
|
||||
- Stattdessen wird der neue Service `fetchLocationDevicesService.js` in `/services/database/`
|
||||
verwendet
|
||||
- Neuer Thunk `fetchLocationDevicesThunk.js` unter `/redux/thunks/database/` eingeführt
|
||||
- `locationDevicesFromDBSlice.js` ersetzt durch `locationDevicesSlice.js` mit Anbindung an den neuen Thunk
|
||||
- `MapComponent.js` nutzt jetzt `dispatch(fetchLocationDevicesThunk())` zur Initialisierung der Geräte
|
||||
- `locationDevicesFromDBSlice.js` ersetzt durch `locationDevicesSlice.js` mit Anbindung an den neuen
|
||||
Thunk
|
||||
- `MapComponent.js` nutzt jetzt `dispatch(fetchLocationDevicesThunk())` zur Initialisierung der
|
||||
Geräte
|
||||
|
||||
### Cleanup
|
||||
|
||||
@@ -895,7 +918,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### Cleanup
|
||||
|
||||
- 🧼 Veraltete GIS-API-Fetch-Dateien entfernt, da nun vollständig durch zentrale Redux-Architektur ersetzt:
|
||||
- 🧼 Veraltete GIS-API-Fetch-Dateien entfernt, da nun vollständig durch zentrale Redux-Architektur
|
||||
ersetzt:
|
||||
- `fetchGisStationsMeasurements.js`
|
||||
- `fetchGisStationsStatic.js`
|
||||
- `fetchGisStationsStaticDistrict.js`
|
||||
@@ -937,7 +961,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
- `fetchGisStationsStaticDistrict.js`
|
||||
- `fetchGisStationsStatusDistrict.js`
|
||||
- `fetchGisSystemStatic.js`
|
||||
- Alle Datenquellen werden jetzt ausschließlich über zentrale Redux Thunks und zugehörige Services geladen
|
||||
- Alle Datenquellen werden jetzt ausschließlich über zentrale Redux Thunks und zugehörige Services
|
||||
geladen
|
||||
- Alte Fetch-Struktur (`/redux/api/fromWebService`) vollständig obsolet
|
||||
|
||||
### Fixed
|
||||
@@ -960,7 +985,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
### Changed
|
||||
|
||||
- 🔁 GIS-Datenquellen konsolidiert: Statt 5 werden jetzt nur 4 zentrale Redux-Slices verwendet:
|
||||
- ✅ Beibehalten: `gisStationsMeasurements`, `gisStationsStaticDistrict`, `gisStationsStatusDistrict`, `gisSystemStatic`
|
||||
- ✅ Beibehalten: `gisStationsMeasurements`, `gisStationsStaticDistrict`,
|
||||
`gisStationsStatusDistrict`, `gisSystemStatic`
|
||||
- ❌ Entfernt: `gisStationsStatic` (veraltet / wurde durch `StaticDistrict` ersetzt)
|
||||
|
||||
### Fixed
|
||||
@@ -973,7 +999,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
- 🧼 Thunks, Services und Slices konsistent:
|
||||
- Alle Slices verwenden jetzt zentrale Thunks
|
||||
- Nicht benötigte Dateien (`fetchGisStatusStationsService.js`, `fetchGisStatusStationsThunk.js`, `gisStationsStaticSlice.js`) entfernt
|
||||
- Nicht benötigte Dateien (`fetchGisStatusStationsService.js`, `fetchGisStatusStationsThunk.js`,
|
||||
`gisStationsStaticSlice.js`) entfernt
|
||||
- Redux DevTools zeigen saubere States mit `status: "succeeded"` für alle vier aktiven GIS-Quellen
|
||||
|
||||
---
|
||||
@@ -1052,7 +1079,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
- `/services/database/` für eigene Next.js-APIs (Port 3000)
|
||||
- `/services/utils/` für Hilfsfunktionen (z. B. `fetchWithTimeout`)
|
||||
- Alle Service-Dateien konsistent benannt nach Schema: `fetchXyzService.js`
|
||||
- Beispiel: `fetchGisStationsMeasurementsService.js`, `fetchPoiData.js`, `updateLocationInDatabase.js`
|
||||
- Beispiel: `fetchGisStationsMeasurementsService.js`, `fetchPoiData.js`,
|
||||
`updateLocationInDatabase.js`
|
||||
|
||||
### Motivation
|
||||
|
||||
@@ -1070,7 +1098,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
- `AddPoiModalWindowWrapper.js`
|
||||
- `PoiUpdateModalWrapper.js`
|
||||
- `PoiUpdateModalWindow.js`
|
||||
- Ersetzt durch moderne Komponenten mit direkter Redux-Anbindung (`ShowAddStationPopup`, `PoiUpdateModal`)
|
||||
- Ersetzt durch moderne Komponenten mit direkter Redux-Anbindung (`ShowAddStationPopup`,
|
||||
`PoiUpdateModal`)
|
||||
|
||||
### Cleanup
|
||||
|
||||
@@ -1124,7 +1153,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### Refactor
|
||||
|
||||
- 🔁 Vorbereitung zur Aufteilung von `useLineData.js` und `useMapComponentState.js` in separate Redux-Slices & spezialisierte Hooks
|
||||
- 🔁 Vorbereitung zur Aufteilung von `useLineData.js` und `useMapComponentState.js` in separate
|
||||
Redux-Slices & spezialisierte Hooks
|
||||
- 🟡 Validierte React-Hooks beibehalten (z. B. Marker-Handling & Layer-Logik)
|
||||
|
||||
---
|
||||
@@ -1155,7 +1185,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### Changed
|
||||
|
||||
- Setup-Dateien (`node-v20.12.1-x64.msi`, `nssm.exe`, `ChromeStandaloneSetup64.exe`) aus dem Repository entfernt
|
||||
- Setup-Dateien (`node-v20.12.1-x64.msi`, `nssm.exe`, `ChromeStandaloneSetup64.exe`) aus dem
|
||||
Repository entfernt
|
||||
- Stattdessen Verlinkung in `README.md` zu SharePoint-Ordner für interne Tool-Downloads eingefügt
|
||||
- Projektstruktur aufgeräumt – Installationsdateien blähen Git-Verlauf nicht mehr auf
|
||||
- Hinweis in `README.md` zu Projektorganisation, Tool-Voraussetzungen und Linkstrategie ergänzt
|
||||
@@ -1417,7 +1448,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
- `config.js` angepasst:
|
||||
- Entfernt: `NEXT_PUBLIC_SERVER_URL` aus `.env.local`
|
||||
- Dynamische Berechnung von `serverURL` anhand `window.location` + `NEXT_PUBLIC_API_PORT_MODE`
|
||||
- Zugriff auf Webservices funktioniert jetzt automatisch abhängig von Entwicklungs-/Produktionsumgebung
|
||||
- Zugriff auf Webservices funktioniert jetzt automatisch abhängig von
|
||||
Entwicklungs-/Produktionsumgebung
|
||||
|
||||
### Added
|
||||
|
||||
@@ -1535,7 +1567,8 @@ Selektor für poiLayerVisible wird direkt inline verwendet
|
||||
|
||||
### Changed
|
||||
|
||||
- `idMap` und `idUser` werden nicht mehr aus `.env.local` gelesen, sondern ausschließlich über die URL übergeben (z. B. von TALAS.web).
|
||||
- `idMap` und `idUser` werden nicht mehr aus `.env.local` gelesen, sondern ausschließlich über die
|
||||
URL übergeben (z. B. von TALAS.web).
|
||||
- Entfernt: Fallback-Variablen `NEXT_PUBLIC_DEFAULT_ID_MAP` und `NEXT_PUBLIC_DEFAULT_ID_USER`.
|
||||
- Dokumentation in `docs/redux/api/fromWebService.md` entsprechend angepasst.
|
||||
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
// /components/uiWidgets/mapLayersControlPanel/MapLayersControlPanel.js
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { setSelectedArea } from "../../../redux/slices/selectedAreaSlice";
|
||||
import EditModeToggle from "./EditModeToggle";
|
||||
import { setSelectedArea } from "@/redux/slices/selectedAreaSlice";
|
||||
import EditModeToggle from "@/components/uiWidgets/mapLayersControlPanel/EditModeToggle";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { selectPolylineVisible, setPolylineVisible } from "../../../redux/slices/database/polylines/polylineLayerVisibleSlice";
|
||||
import { selectGisSystemStatic } from "../../../redux/slices/webservice/gisSystemStaticSlice";
|
||||
import { selectGisStationsStaticDistrict } from "../../../redux/slices/webservice/gisStationsStaticDistrictSlice";
|
||||
import { selectMapLayersState, setLayerVisibility } from "../../../redux/slices/mapLayersSlice";
|
||||
import { setVisible } from "../../../redux/slices/database/pois/poiLayerVisibleSlice";
|
||||
import { incrementZoomTrigger } from "../../../redux/slices/zoomTriggerSlice";
|
||||
import {
|
||||
selectPolylineVisible,
|
||||
setPolylineVisible,
|
||||
} from "@/redux/slices/database/polylines/polylineLayerVisibleSlice";
|
||||
import { selectGisSystemStatic } from "@/redux/slices/webservice/gisSystemStaticSlice";
|
||||
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice";
|
||||
import { selectMapLayersState, setLayerVisibility } from "@/redux/slices/mapLayersSlice";
|
||||
import { setVisible } from "@/redux/slices/database/pois/poiLayerVisibleSlice";
|
||||
import { incrementZoomTrigger } from "@/redux/slices/zoomTriggerSlice";
|
||||
|
||||
function MapLayersControlPanel() {
|
||||
const [editMode, setEditMode] = useState(false); // Zustand für editMode
|
||||
const poiVisible = useSelector((state) => state.poiLayerVisible.visible);
|
||||
const setPoiVisible = (value) => dispatch(setVisible(value));
|
||||
const poiVisible = useSelector(state => state.poiLayerVisible.visible);
|
||||
const setPoiVisible = value => dispatch(setVisible(value));
|
||||
const dispatch = useDispatch();
|
||||
const mapLayersVisibility = useSelector(selectMapLayersState);
|
||||
const [stationListing, setStationListing] = useState([]);
|
||||
@@ -23,14 +26,17 @@ function MapLayersControlPanel() {
|
||||
|
||||
const polylineVisible = useSelector(selectPolylineVisible);
|
||||
|
||||
const handlePolylineCheckboxChange = (event) => {
|
||||
const handlePolylineCheckboxChange = event => {
|
||||
const checked = event.target.checked;
|
||||
dispatch(setPolylineVisible(checked));
|
||||
localStorage.setItem("polylineVisible", checked);
|
||||
|
||||
if (checked) {
|
||||
dispatch(setLayerVisibility({ layer: "TALAS", visibility: true }));
|
||||
localStorage.setItem("mapLayersVisibility", JSON.stringify({ ...mapLayersVisibility, TALAS: true }));
|
||||
localStorage.setItem(
|
||||
"mapLayersVisibility",
|
||||
JSON.stringify({ ...mapLayersVisibility, TALAS: true })
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,7 +55,7 @@ function MapLayersControlPanel() {
|
||||
const storedMapLayersVisibility = localStorage.getItem("mapLayersVisibility");
|
||||
if (storedMapLayersVisibility) {
|
||||
const parsedVisibility = JSON.parse(storedMapLayersVisibility);
|
||||
Object.keys(parsedVisibility).forEach((key) => {
|
||||
Object.keys(parsedVisibility).forEach(key => {
|
||||
dispatch(setLayerVisibility({ layer: key, visibility: parsedVisibility[key] }));
|
||||
});
|
||||
}
|
||||
@@ -59,18 +65,20 @@ function MapLayersControlPanel() {
|
||||
setEditMode(storedEditMode === "true");
|
||||
}, [setPoiVisible, dispatch]); // ✅ `setMapLayersVisibility` entfernt
|
||||
|
||||
const handleAreaChange = (event) => {
|
||||
const handleAreaChange = event => {
|
||||
const selectedIndex = event.target.options.selectedIndex;
|
||||
const areaName = event.target.options[selectedIndex].text;
|
||||
dispatch(setSelectedArea(areaName));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const allowedSystems = Array.isArray(GisSystemStatic) ? new Set(GisSystemStatic.filter((system) => system.Allow === 1).map((system) => system.IdSystem)) : new Set();
|
||||
const allowedSystems = Array.isArray(GisSystemStatic)
|
||||
? new Set(GisSystemStatic.filter(system => system.Allow === 1).map(system => system.IdSystem))
|
||||
: new Set();
|
||||
|
||||
const seenNames = new Set();
|
||||
const filteredAreas = GisStationsStaticDistrict?.Points?.length
|
||||
? GisStationsStaticDistrict.Points.filter((item) => {
|
||||
? GisStationsStaticDistrict.Points.filter(item => {
|
||||
const isUnique = !seenNames.has(item.Area_Name) && allowedSystems.has(item.System);
|
||||
if (isUnique) {
|
||||
seenNames.add(item.Area_Name);
|
||||
@@ -88,7 +96,7 @@ function MapLayersControlPanel() {
|
||||
|
||||
const seenSystemNames = new Set();
|
||||
const filteredSystems = Array.isArray(GisSystemStatic)
|
||||
? GisSystemStatic.filter((item) => {
|
||||
? GisSystemStatic.filter(item => {
|
||||
const isUnique = !seenSystemNames.has(item.Name) && item.Allow === 1;
|
||||
if (isUnique) {
|
||||
seenSystemNames.add(item.Name);
|
||||
@@ -111,7 +119,10 @@ function MapLayersControlPanel() {
|
||||
const { checked } = event.target;
|
||||
|
||||
dispatch(setLayerVisibility({ layer: key, visibility: checked }));
|
||||
localStorage.setItem("mapLayersVisibility", JSON.stringify({ ...mapLayersVisibility, [key]: checked }));
|
||||
localStorage.setItem(
|
||||
"mapLayersVisibility",
|
||||
JSON.stringify({ ...mapLayersVisibility, [key]: checked })
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
const event = new Event("visibilityChanged");
|
||||
@@ -119,7 +130,7 @@ function MapLayersControlPanel() {
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const handlePoiCheckboxChange = (event) => {
|
||||
const handlePoiCheckboxChange = event => {
|
||||
const { checked } = event.target;
|
||||
setPoiVisible(checked);
|
||||
localStorage.setItem("poiVisible", checked); // Store POI visibility in localStorage
|
||||
@@ -145,12 +156,15 @@ function MapLayersControlPanel() {
|
||||
}
|
||||
|
||||
if (!GisStationsStaticDistrict.Points || !Array.isArray(GisStationsStaticDistrict.Points)) {
|
||||
console.warn("⚠️ GisStationsStaticDistrict.Points ist nicht vorhanden oder kein Array.", GisStationsStaticDistrict);
|
||||
console.warn(
|
||||
"⚠️ GisStationsStaticDistrict.Points ist nicht vorhanden oder kein Array.",
|
||||
GisStationsStaticDistrict
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const seenNames = new Set();
|
||||
const filteredAreas = GisStationsStaticDistrict.Points.filter((item) => {
|
||||
const filteredAreas = GisStationsStaticDistrict.Points.filter(item => {
|
||||
if (!item.Area_Name) return false; // Sicherstellen, dass Area_Name existiert
|
||||
const isUnique = !seenNames.has(item.Area_Name);
|
||||
if (isUnique) {
|
||||
@@ -164,12 +178,20 @@ function MapLayersControlPanel() {
|
||||
|
||||
//---------------------------
|
||||
return (
|
||||
<div id="mainDataSheet" className="absolute top-3 right-3 w-1/6 min-w-[300px] max-w-[400px] z-10 bg-white p-2 rounded-lg shadow-lg">
|
||||
<div
|
||||
id="mainDataSheet"
|
||||
className="absolute top-3 right-3 w-1/6 min-w-[300px] max-w-[400px] z-10 bg-white p-2 rounded-lg shadow-lg"
|
||||
>
|
||||
<div className="flex flex-col gap-4 p-4">
|
||||
<div className="flex items-center justify-between space-x-2">
|
||||
<select onChange={handleAreaChange} id="stationListing" className="border-solid-1 p-2 rounded ml-1 font-semibold" style={{ minWidth: "150px", maxWidth: "200px" }}>
|
||||
<select
|
||||
onChange={handleAreaChange}
|
||||
id="stationListing"
|
||||
className="border-solid-1 p-2 rounded ml-1 font-semibold"
|
||||
style={{ minWidth: "150px", maxWidth: "200px" }}
|
||||
>
|
||||
<option value="Station wählen">Station wählen</option>
|
||||
{stationListing.map((station) => (
|
||||
{stationListing.map(station => (
|
||||
<option key={station.id} value={station.id}>
|
||||
{station.name}
|
||||
</option>
|
||||
@@ -177,19 +199,24 @@ function MapLayersControlPanel() {
|
||||
</select>
|
||||
<div className="flex items-center space-x-2">
|
||||
<EditModeToggle />
|
||||
<img src="/img/expand-icon.svg" alt="Expand" className="h-6 w-6 cursor-pointer" onClick={handleIconClick} />
|
||||
<img
|
||||
src="/img/expand-icon.svg"
|
||||
alt="Expand"
|
||||
className="h-6 w-6 cursor-pointer"
|
||||
onClick={handleIconClick}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Checkboxen mit Untermenüs */}
|
||||
<div className="flex flex-col gap-2">
|
||||
{systemListing.map((system) => (
|
||||
{systemListing.map(system => (
|
||||
<div key={system.id} className="flex flex-col">
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={mapLayersVisibility[system.key] || false}
|
||||
onChange={(e) => handleCheckboxChange(system.key, e)}
|
||||
onChange={e => handleCheckboxChange(system.key, e)}
|
||||
id={`system-${system.id}`}
|
||||
disabled={editMode} // Checkbox deaktiviert, wenn editMode aktiv ist
|
||||
/>
|
||||
@@ -218,7 +245,12 @@ function MapLayersControlPanel() {
|
||||
))}
|
||||
|
||||
<div className="flex items-center">
|
||||
<input type="checkbox" checked={poiVisible} onChange={handlePoiCheckboxChange} id="poi-checkbox" />
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={poiVisible}
|
||||
onChange={handlePoiCheckboxChange}
|
||||
id="poi-checkbox"
|
||||
/>
|
||||
<label htmlFor="poi-checkbox" className="text-sm ml-2">
|
||||
POIs
|
||||
</label>
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// /config/appVersion
|
||||
export const APP_VERSION = "1.1.230";
|
||||
export const APP_VERSION = "1.1.231";
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from "react";
|
||||
import L from "leaflet";
|
||||
import { createAndSetDevices } from "../utils/devices/createAndSetDevices";
|
||||
import { checkOverlappingMarkers } from "../utils/mapUtils";
|
||||
import plusRoundIcon from "../components/icons/devices/overlapping/PlusRoundIcon";
|
||||
import plusRoundIcon from "@/components/icons/devices/overlapping/PlusRoundIcon";
|
||||
|
||||
/**
|
||||
* Dynamisch GIS-System-Marker erstellen & Sichtbarkeit steuern.
|
||||
@@ -31,14 +31,27 @@ const useDynamicDeviceLayers = (map, GisSystemStatic, mapLayersVisibility, prior
|
||||
createAndSetDevices(
|
||||
IdSystem,
|
||||
newMarkers => {
|
||||
setMarkerStates(prev => ({ ...prev, [key]: newMarkers }));
|
||||
const oldMarkers = markerStates[key];
|
||||
|
||||
// ❌ NICHT direkt zur Karte hinzufügen
|
||||
// Sichtbarkeit folgt im 2. useEffect
|
||||
checkOverlappingMarkers(map, newMarkers, plusRoundIcon, oms);
|
||||
// Entferne alte Marker aus Karte und OMS
|
||||
if (oldMarkers && Array.isArray(oldMarkers)) {
|
||||
oldMarkers.forEach(marker => {
|
||||
if (map.hasLayer(marker)) {
|
||||
map.removeLayer(marker);
|
||||
}
|
||||
if (oms) {
|
||||
oms.removeMarker(marker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Neue Marker setzen
|
||||
setMarkerStates(prev => ({ ...prev, [key]: newMarkers }));
|
||||
},
|
||||
GisSystemStatic,
|
||||
priorityConfig
|
||||
priorityConfig,
|
||||
undefined,
|
||||
oms
|
||||
);
|
||||
});
|
||||
}, [map, GisSystemStatic, priorityConfig]);
|
||||
|
||||
@@ -4,22 +4,22 @@ import { useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
// Redux: POI-Typen
|
||||
import { fetchPoiTypThunk } from "../redux/thunks/database/pois/fetchPoiTypThunk";
|
||||
import { selectPoiTypData, selectPoiTypStatus } from "../redux/slices/database/pois/poiTypSlice";
|
||||
import { fetchPoiTypThunk } from "@/redux/thunks/database/pois/fetchPoiTypThunk";
|
||||
import { selectPoiTypData, selectPoiTypStatus } from "@/redux/slices/database/pois/poiTypSlice";
|
||||
|
||||
// Redux: GIS Geräte
|
||||
import { fetchGisStationsStaticDistrictThunk } from "../redux/thunks/webservice/fetchGisStationsStaticDistrictThunk";
|
||||
import { selectGisStationsStaticDistrict } from "../redux/slices/webservice/gisStationsStaticDistrictSlice";
|
||||
import { fetchGisStationsStaticDistrictThunk } from "@/redux/thunks/webservice/fetchGisStationsStaticDistrictThunk";
|
||||
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice";
|
||||
|
||||
// Redux: priorityConfig
|
||||
import { fetchPriorityConfigThunk } from "../redux/thunks/database/fetchPriorityConfigThunk";
|
||||
import { selectPriorityConfig } from "../redux/slices/database/priorityConfigSlice";
|
||||
import { fetchPriorityConfigThunk } from "@/redux/thunks/database/fetchPriorityConfigThunk";
|
||||
import { selectPriorityConfig } from "@/redux/slices/database/priorityConfigSlice";
|
||||
|
||||
export const useMapComponentState = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
// Redux: Sichtbarkeit des POI-Layers
|
||||
const poiLayerVisible = useSelector((state) => state.poiLayerVisible.visible);
|
||||
const poiLayerVisible = useSelector(state => state.poiLayerVisible.visible);
|
||||
|
||||
// Redux: POI-Typen
|
||||
const poiTypData = useSelector(selectPoiTypData);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// /utils/devices/createAndSetDevices.js
|
||||
import L from "leaflet";
|
||||
import "leaflet.smooth_marker_bouncing";
|
||||
import { store } from "../../redux/store.js";
|
||||
import { setSelectedDevice } from "../../redux/slices/selectedDeviceSlice.js";
|
||||
import { selectGisStationsStaticDistrict } from "../../redux/slices/webservice/gisStationsStaticDistrictSlice.js";
|
||||
import { selectGisStationsStatusDistrict } from "../../redux/slices/webservice/gisStationsStatusDistrictSlice.js";
|
||||
import { selectGisStationsMeasurements } from "../../redux/slices/webservice/gisStationsMeasurementsSlice.js";
|
||||
import { addContextMenuToMarker } from "../../utils/contextMenuUtils";
|
||||
import { store } from "@/redux/store.js";
|
||||
import { setSelectedDevice } from "@/redux/slices/selectedDeviceSlice.js";
|
||||
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice.js";
|
||||
import { selectGisStationsStatusDistrict } from "@/redux/slices/webservice/gisStationsStatusDistrictSlice.js";
|
||||
import { selectGisStationsMeasurements } from "@/redux/slices/webservice/gisStationsMeasurementsSlice.js";
|
||||
import { addContextMenuToMarker } from "@/utils/contextMenuUtils";
|
||||
|
||||
const determinePriority = (iconPath, priorityConfig) => {
|
||||
for (let priority of priorityConfig) {
|
||||
@@ -17,7 +17,14 @@ const determinePriority = (iconPath, priorityConfig) => {
|
||||
return 5;
|
||||
};
|
||||
|
||||
export const createAndSetDevices = async (systemId, setMarkersFunction, GisSystemStatic, priorityConfig, measurements) => {
|
||||
export const createAndSetDevices = async (
|
||||
systemId,
|
||||
setMarkersFunction,
|
||||
GisSystemStatic,
|
||||
priorityConfig,
|
||||
measurements,
|
||||
oms // 🔁 OMS für Spiderfy hinzugefügt
|
||||
) => {
|
||||
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
|
||||
|
||||
try {
|
||||
@@ -28,20 +35,24 @@ export const createAndSetDevices = async (systemId, setMarkersFunction, GisSyste
|
||||
|
||||
if (!staticDistrictData?.Points?.length || !statusDistrictData?.length) return;
|
||||
|
||||
const statisMap = new Map(statusDistrictData.map((s) => [s.IdLD, s]));
|
||||
const statisMap = new Map(statusDistrictData.map(s => [s.IdLD, s]));
|
||||
const measurementsMap = new Map();
|
||||
measurementData?.forEach((m) => {
|
||||
measurementData?.forEach(m => {
|
||||
if (!measurementsMap.has(m.IdLD)) {
|
||||
measurementsMap.set(m.IdLD, m);
|
||||
}
|
||||
});
|
||||
|
||||
const activeStations = staticDistrictData.Points.filter((station) => station.System === systemId && station.Active === 1);
|
||||
const activeStations = staticDistrictData.Points.filter(
|
||||
station => station.System === systemId && station.Active === 1
|
||||
);
|
||||
|
||||
const markersData = activeStations.map((station) => {
|
||||
const markersData = activeStations.map(station => {
|
||||
const statis = statisMap.get(station.IdLD);
|
||||
const messung = measurementsMap.get(station.IdLD);
|
||||
const iconPath = statis ? `img/icons/${statis.Na}-marker-icon-${station.Icon}.png` : `img/icons/marker-icon-${station.Icon}.png`;
|
||||
const iconPath = statis
|
||||
? `img/icons/${statis.Na}-marker-icon-${station.Icon}.png`
|
||||
: `img/icons/marker-icon-${station.Icon}.png`;
|
||||
|
||||
const priority = determinePriority(iconPath, priorityConfig);
|
||||
const zIndexOffset = 100 * (5 - priority);
|
||||
@@ -60,19 +71,23 @@ export const createAndSetDevices = async (systemId, setMarkersFunction, GisSyste
|
||||
idDevice: station.IdLD,
|
||||
});
|
||||
|
||||
// ✅ Popups nur für Statusdaten
|
||||
// ✅ Popup
|
||||
let popupContent = `
|
||||
<div class="bg-white rounded-lg">
|
||||
<span class="text-lg font-semibold text-gray-900">${station.LD_Name}</span>
|
||||
<span class="text-md font-bold text-gray-800">${station.Device}</span><br>
|
||||
<span class="text-gray-800"><strong>${station.Area_Short}</strong> (${station.Area_Name})</span><br>
|
||||
<span class="text-gray-800"><strong>${station.Location_Short}</strong> (${station.Location_Name})</span>
|
||||
<span class="text-gray-800"><strong>${station.Area_Short}</strong> (${
|
||||
station.Area_Name
|
||||
})</span><br>
|
||||
<span class="text-gray-800"><strong>${station.Location_Short}</strong> (${
|
||||
station.Location_Name
|
||||
})</span>
|
||||
<div class="mt-2">
|
||||
${statusDistrictData
|
||||
.filter((status) => status.IdLD === station.IdLD)
|
||||
.filter(status => status.IdLD === station.IdLD)
|
||||
.reverse()
|
||||
.map(
|
||||
(status) => `
|
||||
status => `
|
||||
<div class="flex items-center my-1">
|
||||
<div class="w-2 h-2 mr-2 inline-block rounded-full" style="background-color: ${status.Co};"></div>
|
||||
${status.Me} <span style="color: ${status.Co};">(${status.Na})</span>
|
||||
@@ -81,9 +96,10 @@ export const createAndSetDevices = async (systemId, setMarkersFunction, GisSyste
|
||||
.join("")}
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
marker.bindPopup(popupContent);
|
||||
|
||||
// ✅ Tooltip im GMA-Stil mit Messwerten
|
||||
// ✅ Tooltip (nur für System 11)
|
||||
if (station.System === 11 && messung) {
|
||||
const lt = messung["LT"] ?? "-";
|
||||
const fbt = messung["FBT"] ?? "-";
|
||||
@@ -132,6 +148,11 @@ export const createAndSetDevices = async (systemId, setMarkersFunction, GisSyste
|
||||
|
||||
addContextMenuToMarker(marker);
|
||||
|
||||
// ✅ OverlappingMarkerSpiderfier hinzufügen
|
||||
if (oms) {
|
||||
oms.addMarker(marker);
|
||||
}
|
||||
|
||||
return marker;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user