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:
@@ -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: '© <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: '© <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);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user