git commit -m "refactor: Gerätelayer dynamisch über IdSystem initialisiert

BREAKING CHANGE: Sichtbarkeit der Gerätegruppen basiert nun auf 'system-<IdSystem>' statt auf Namen wie 'SMSFunkmodem'. Statische Layer-Konfiguration im Redux-Slice entfernt."
This commit is contained in:
ISA
2025-06-02 09:00:49 +02:00
parent fda7476872
commit be2da8414c
12 changed files with 76 additions and 33 deletions

View File

@@ -4,6 +4,26 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
---
## [1.1.209] 2025-06-02
### Added
- 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`.
### Changed
- 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.
### Removed
- Veraltete statische Layer-Namen (`TALAS`, `SMSFunkmodem`, etc.) aus `mapLayersSlice`.
---
## [1.1.191] 2025-05-27
### 🐞 Fixed

View File

@@ -6,7 +6,7 @@ export const mockGisStationsStaticDistrict = {
IdMap: "12",
Points: [
{
LD_Name: "CPL Ismael",
LD_Name: "CPL Ismail",
IdLD: 50922,
Device: "CPL V3.5 mit 24 Kü",
Link: "cpl.aspx?ver=35&kue=24&id=50922",

View File

@@ -79,7 +79,7 @@ export const mockGisSystemStatic = {
IdSystem: 13,
Name: "Messstellen",
Longname: "Messstellen",
Allow: 0,
Allow: 1,
Icon: 13,
},
{

View File

@@ -15,3 +15,10 @@
- [x] Wird cleanup in `useMapContextMenu` korrekt durchgeführt?
- [x] Test: `Rechtsklick > Station öffnen Tab`
- ✅ Gelöst am 27.05.2025 in Version 1.1.191 (`createAndSetDevices.js`)
### 2. Kontextmenü wird bei Geräten nicht angezeigt
- [ ] Kontextmenü anzeigen
- [ ] Station öffnen (Tab) anzeigen
- [ ] Station öffnen (Tab) Link prüfen
- [ ] SMS Modem in control panel passt nicht zu station static und status

View File

@@ -555,6 +555,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
dispatch(fetchGisSystemStaticThunk());
}
}, [statusSystem, dispatch]);
useEffect(() => {
dispatch(fetchGisSystemStaticThunk());
}, [dispatch]);
useEffect(() => {
dispatch(fetchLocationDevicesThunk());

View File

@@ -101,7 +101,7 @@ function MapLayersControlPanel() {
filteredSystems.map((system, index) => ({
id: index + 1,
name: system.Name, // Verwende den Originalnamen für die Anzeige
key: system.Name.replace(/[\s\-]+/g, ""), // Internen Schlüssel für die MapLayersVisibility-Logik
key: `system-${system.IdSystem}`, // Internen Schlüssel für die MapLayersVisibility-Logik
}))
);
}, [GisStationsStaticDistrict, GisSystemStatic]);

View File

@@ -1,2 +1,2 @@
// /config/appVersion
export const APP_VERSION = "1.1.209";
export const APP_VERSION = "1.1.210";

View File

@@ -0,0 +1,18 @@
# 📡 Architektur: Verbindung GIS-System & GIS-Station
Dieses Diagramm zeigt den Ablauf, wie Geräte (Marker) auf der Karte über die ID (System gegen IdSystem) korrekt geladen und sichtbar gemacht werden.
```mermaid
flowchart TD
A[Stationen aus GIS Stations District mit System ID zum Beispiel 111] --> B[useDynamicDeviceLayers.js]
B --> C[Filter und Gruppierung nach System ID]
C --> D[createAndSetDevices.js erzeugt Marker]
D --> E[MapComponent.js zeigt Marker auf Karte]
subgraph Redux
F[fetchGisSystemStaticService.js liefert Systeme mit IdSystem]
F --> G[fetchGisSystemStaticThunk.js]
G --> H[setInitialLayers mit system-IdSystem]
H --> I[mapLayersSlice.js speichert Sichtbarkeit]
end
I -->|Sichtbarkeit steuert Anzeige| E
```

View File

@@ -22,17 +22,19 @@ const useDynamicDeviceLayers = (map, GisSystemStatic, mapLayersVisibility, prior
if (!map || GisSystemStatic.length === 0) return;
GisSystemStatic.forEach(({ Name, IdSystem }) => {
if (!layerRefs.current[Name]) {
layerRefs.current[Name] = new L.LayerGroup().addTo(map);
const key = `system-${IdSystem}`; // ✅ Einheitlicher Key
if (!layerRefs.current[key]) {
layerRefs.current[key] = new L.LayerGroup().addTo(map);
}
createAndSetDevices(
IdSystem,
(newMarkers) => {
setMarkerStates((prev) => ({ ...prev, [Name]: newMarkers }));
setMarkerStates((prev) => ({ ...prev, [key]: newMarkers }));
newMarkers.forEach((m) => {
layerRefs.current[Name].addLayer(m);
if (oms) oms.addMarker(m); // ✅ Marker bei OMS registrieren
layerRefs.current[key].addLayer(m);
if (oms) oms.addMarker(m);
});
checkOverlappingMarkers(map, newMarkers, plusRoundIcon, oms);
},
@@ -47,8 +49,8 @@ const useDynamicDeviceLayers = (map, GisSystemStatic, mapLayersVisibility, prior
if (!map) return;
const editMode = localStorage.getItem("editMode") === "true";
Object.entries(markerStates).forEach(([systemName, markers]) => {
const isVisible = mapLayersVisibility[systemName];
Object.entries(markerStates).forEach(([key, markers]) => {
const isVisible = mapLayersVisibility[key];
markers.forEach((marker) => {
const hasLayer = map.hasLayer(marker);
if (editMode || !isVisible) {

View File

@@ -1,7 +1,7 @@
// /hooks/useCreateAndSetDevices.js
import { useEffect } from "react";
import { useSelector } from "react-redux";
import { createAndSetDevices } from "../utils/createAndSetDevices";
import { createAndSetDevices } from "../utils/devices/createAndSetDevices";
import { selectGisStationsMeasurements } from "../redux/slices/webservice/gisStationsMeasurementsSlice";
const useCreateAndSetDevices = (systemId, setMarkersFunction, GisSystemStatic, priorityConfig) => {

View File

@@ -1,24 +1,7 @@
// redux/slices/mapLayersSlice.js
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
TALAS: true,
ECI: true,
ULAF: true,
GSMModem: true,
CiscoRouter: true,
WAGO: true,
Siemens: true,
OTDR: true,
WDM: true,
GMA: true,
Messstellen: true,
TALASICL: true,
DAUZ: true,
SMSFunkmodem: true, // ✅ Hier sicherstellen, dass es existiert
TKKomponenten: true, // ✅ Hier sicherstellen, dass es existiert
Sonstige: true,
};
const initialState = {};
const mapLayersSlice = createSlice({
name: "mapLayers",
@@ -36,9 +19,16 @@ const mapLayersSlice = createSlice({
state[layer] = visibility;
}
},
setInitialLayers: (state, action) => {
const systems = action.payload; // Array of GisSystem
systems.forEach((system) => {
const key = `system-${system.IdSystem}`;
state[key] = true; // oder false, je nach Default
});
},
},
});
export const { toggleLayer, setLayerVisibility } = mapLayersSlice.actions;
export const { toggleLayer, setLayerVisibility, setInitialLayers } = mapLayersSlice.actions;
export const selectMapLayersState = (state) => state.mapLayers || initialState;
export default mapLayersSlice.reducer;

View File

@@ -2,10 +2,13 @@
import { createAsyncThunk } from "@reduxjs/toolkit";
import { fetchGisSystemStaticService } from "../../../services/webservice/fetchGisSystemStaticService";
import { setInitialLayers } from "../../slices/mapLayersSlice"; // Importiere die Action Creator
/**
* Redux-Thunk für fetchGisSystemStatic
*/
export const fetchGisSystemStaticThunk = createAsyncThunk("gisSystemStatic/fetch", async () => {
return await fetchGisSystemStaticService();
export const fetchGisSystemStaticThunk = createAsyncThunk("gisSystemStatic/fetch", async (_, { dispatch }) => {
const systems = await fetchGisSystemStaticService();
dispatch(setInitialLayers(systems)); // ✅ jetzt funktioniert!
return systems;
});