fix: Duplizierte Kontextmenü-Einträge verhindert und Cleanup hinzugefügt

- Kontextmenü wird jetzt nur einmal hinzugefügt, wenn es noch nicht existiert.
- Vor dem Hinzufügen wird geprüft, ob bereits Einträge existieren, um Duplikate zu vermeiden.
- Kontextmenü wird entfernt, wenn außerhalb geklickt wird, um Speicherlecks zu verhindern.
- Nutzung eines `Set()` für Menü-IDs, um doppelte Einträge sicher zu verhindern.
This commit is contained in:
ISA
2025-03-11 16:19:11 +01:00
parent b8e3385fff
commit 449d19a728
10 changed files with 279 additions and 141 deletions

View File

@@ -3,104 +3,119 @@ import L from "leaflet";
import "leaflet-contextmenu";
import "leaflet/dist/leaflet.css";
import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
import "leaflet-control-geocoder";
import { store } from "../redux/store";
import * as urls from "../config/urls.js";
import * as layers from "../config/layers.js";
import { openInNewTab } from "./openInNewTab.js";
export const initializeMap = (mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled) => {
if (mapRef.current) {
const initMap = L.map(mapRef.current, {
center: [53.111111, 8.4625],
zoom: 12,
minZoom: 5,
maxZoom: 15,
layers: [
layers.MAP_LAYERS.TALAS,
layers.MAP_LAYERS.ECI,
layers.MAP_LAYERS.GSMModem,
layers.MAP_LAYERS.CiscoRouter,
layers.MAP_LAYERS.WAGO,
layers.MAP_LAYERS.Siemens,
layers.MAP_LAYERS.OTDR,
layers.MAP_LAYERS.WDM,
layers.MAP_LAYERS.GMA,
layers.MAP_LAYERS.TALASICL,
layers.MAP_LAYERS.Sonstige,
layers.MAP_LAYERS.ULAF,
],
if (!mapRef.current) {
console.error("❌ Fehler: mapRef.current ist nicht definiert.");
return;
}
zoomControl: false,
contextmenu: true,
contextmenuItems: [
{
text: "Station öffnen (Tab)",
icon: "/img/screen_new.png",
callback: (e) => {
const editMode = localStorage.getItem("editMode") === "true";
const clickedElement = e.relatedTarget;
if (mapRef.current._leaflet_id) {
console.log("⚠️ Karte ist bereits initialisiert `dragging.enable()` wird sichergestellt.");
setTimeout(() => {
if (mapRef.current) {
mapRef.current.dragging.enable();
}
}, 100);
return;
}
if (!clickedElement) {
console.error("No valid target for the context menu entry (Element is null).");
return;
}
// Leaflet-Karte erstellen
const initMap = L.map(mapRef.current, {
center: [53.111111, 8.4625],
zoom: 12,
minZoom: 5,
maxZoom: 15,
zoomControl: false,
dragging: true,
contextmenu: true, // ✅ Sicherstellen, dass Kontextmenü aktiviert ist
layers: [
layers.MAP_LAYERS.TALAS,
layers.MAP_LAYERS.ECI,
layers.MAP_LAYERS.GSMModem,
layers.MAP_LAYERS.CiscoRouter,
layers.MAP_LAYERS.WAGO,
layers.MAP_LAYERS.Siemens,
layers.MAP_LAYERS.OTDR,
layers.MAP_LAYERS.WDM,
layers.MAP_LAYERS.GMA,
layers.MAP_LAYERS.TALASICL,
layers.MAP_LAYERS.Sonstige,
layers.MAP_LAYERS.ULAF,
],
});
// Prüfen, ob es ein POI ist (POIs haben idPoi in den Optionen)
if (clickedElement instanceof L.Marker && clickedElement.options?.idPoi) {
console.log("POI erkannt - Station öffnen deaktiviert.");
return; // Keine Aktion ausführen
}
initMap.dragging.enable();
try {
if (clickedElement instanceof L.Marker || clickedElement?.options?.link) {
const link = "http://" + window.location.hostname + "/talas5/devices/" + clickedElement.options.link;
if (link) {
console.log("Opening link in a new tab:", link);
//window.open(link, "_blank"); POI-Link öffnen in neuem Tab
} else {
console.error("No link found in the Marker options.");
}
} else {
console.error("No valid target for the context menu entry");
}
} catch (error) {
console.error("Error processing the context menu:", error);
}
},
},
"-",
],
});
// 🌍 **🚀 Kontextmenü sicherstellen**
if (!initMap.contextmenu) {
console.error("❌ `contextmenu` ist nicht verfügbar.");
return;
}
// Füge die Tile-Layer hinzu
L.tileLayer(urls.OFFLINE_TILE_LAYER, {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(initMap);
// **Kontextmenü für Geräte aktualisieren**
initMap.on("contextmenu.show", (e) => {
const clickedElement = e.relatedTarget;
const selectedDevice = store.getState().selectedDevice; // Redux-Wert abrufen
// Suchfeld hinzufügen
/* const geocoder = L.Control.geocoder({
defaultMarkGeocode: false,
})
.on("markgeocode", function (e) {
const latlng = e.geocode.center;
initMap.setView(latlng, 15);
L.marker(latlng).addTo(initMap).bindPopup(e.geocode.name).openPopup();
})
.addTo(initMap); */
// Initialisiere OverlappingMarkerSpiderfier
const overlappingMarkerSpiderfier = new OverlappingMarkerSpiderfier(initMap, {
nearbyDistance: 20,
});
// Setze die Map und OMS in den State
setMap(initMap);
setOms(overlappingMarkerSpiderfier);
// Wenn Rechte geladen sind und es noch nicht hinzugefügt wurde, füge das Kontextmenü hinzu
if (hasRights && !setMenuItemAdded) {
addItemsToMapContextMenu(initMap, setMenuItemAdded, setPolylineEventsDisabled);
if (!initMap.contextmenu || !initMap.contextmenu.items) {
console.error("❌ Fehler: `contextmenu` oder `items` ist nicht definiert.");
return;
}
try {
initMap.contextmenu.removeAllItems(); // **Sicherstellen, dass vorherige Einträge entfernt werden**
} catch (error) {
console.error("❌ Fehler beim Entfernen der Menüelemente:", error);
}
if (!clickedElement) {
console.error("❌ Kein gültiges Ziel für das Kontextmenü.");
return;
}
// 🛑 Falls `selectedDevice === null`, kein "Station öffnen" anzeigen
if (!selectedDevice || !clickedElement.options?.idDevice) {
console.log(" Kein Gerät ausgewählt 'Station öffnen' wird nicht hinzugefügt.");
return;
}
// ✅ Falls `selectedDevice` gesetzt ist, "Station öffnen" anzeigen
console.log("✅ Gerät erkannt 'Station öffnen' wird hinzugefügt.");
initMap.contextmenu.addItem({
text: "Station öffnen (Tab)",
icon: "/img/screen_new.png",
callback: () => {
const link = `http://${window.location.hostname}/talas5/devices/${selectedDevice.id}`;
if (link) {
console.log("🟢 Öffne Link in neuem Tab:", link);
window.open(link, "_blank");
} else {
console.error("❌ Kein Link in den Marker-Optionen gefunden.");
}
},
});
});
// Tile-Layer hinzufügen
L.tileLayer(urls.OFFLINE_TILE_LAYER, {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(initMap);
// Initialisiere OverlappingMarkerSpiderfier
const overlappingMarkerSpiderfier = new OverlappingMarkerSpiderfier(initMap, {
nearbyDistance: 20,
});
// Setze die Map und OMS in den State
setMap(initMap);
setOms(overlappingMarkerSpiderfier);
// Falls Rechte geladen sind, füge das Kontextmenü hinzu
if (hasRights && !setMenuItemAdded) {
addItemsToMapContextMenu(initMap, setMenuItemAdded, setPolylineEventsDisabled);
}
};