feat: Kontextmenü-Link für Marker, Linien und GMA vereinheitlicht – openInNewTab verwendet, Port entfernt, /devices/ ergänzt
This commit is contained in:
@@ -1,210 +1,54 @@
|
||||
import { useEffect } from "react";
|
||||
// [x]: test Chaeckbox für TODO-Tree (TODOs)
|
||||
//FIXME: test FIXME für TODO-Tree (TODOs)
|
||||
|
||||
// BUG: test BUG für TODO-Tree (TODOs)
|
||||
|
||||
const useGmaMarkersLayer = (map, markers, GisStationsMeasurements, GMA, oms, isVisible) => {
|
||||
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
|
||||
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
|
||||
let currentMenu = null; // Variable für das aktuelle Kontextmenü
|
||||
|
||||
const closeContextMenu = () => {
|
||||
if (currentMenu) {
|
||||
currentMenu.remove();
|
||||
currentMenu = null;
|
||||
}
|
||||
};
|
||||
|
||||
const zoomIn = (map, latlng) => {
|
||||
if (!map) return;
|
||||
const currentZoom = map.getZoom();
|
||||
if (currentZoom < 14) {
|
||||
map.flyTo(latlng, 14);
|
||||
}
|
||||
};
|
||||
|
||||
const zoomOut = (map) => {
|
||||
if (!map) return;
|
||||
map.flyTo([51.4132, 7.7396], 7);
|
||||
};
|
||||
|
||||
const centerHere = (map, latlng) => {
|
||||
if (!map) return;
|
||||
map.panTo(latlng);
|
||||
};
|
||||
import { store } from "../redux/store";
|
||||
import L from "leaflet";
|
||||
import "leaflet-contextmenu";
|
||||
import { openInNewTab } from "./openInNewTab";
|
||||
|
||||
const useGmaMarkersLayer = (map, markers, selectedMarkerId) => {
|
||||
useEffect(() => {
|
||||
if (!map || !isVisible) return;
|
||||
if (!map || !markers || markers.length === 0) return;
|
||||
|
||||
GMA.clearLayers();
|
||||
const markerGroup = L.layerGroup();
|
||||
|
||||
markers.forEach((marker) => {
|
||||
const areaName = marker.options.areaName;
|
||||
|
||||
const relevantMeasurements = GisStationsMeasurements.filter((m) => m.Area_Name === areaName);
|
||||
|
||||
let measurements = {};
|
||||
relevantMeasurements.forEach((m) => {
|
||||
measurements[m.Na] = m.Val;
|
||||
});
|
||||
|
||||
const lt = measurements["LT"] || "-";
|
||||
const fbt = measurements["FBT"] || "-";
|
||||
const gt = measurements["GT"] || "-";
|
||||
const rlf = measurements["RLF"] || "-";
|
||||
|
||||
// Tooltip erstellen
|
||||
marker.bindTooltip(
|
||||
`
|
||||
<div class="p-0 rounded-lg bg-white bg-opacity-90 tooltip-content">
|
||||
<div class="font-bold text-sm text-black"><span>${areaName}</span></div>
|
||||
<div class="font-bold text-xxs text-blue-700"><span>LT: ${lt} °C</span></div>
|
||||
<div class="font-bold text-xxs text-red-700"><span>FBT: ${fbt} °C</span></div>
|
||||
<div class="font-bold text-xxs text-yellow-500"><span>GT: ${gt} °C</span></div>
|
||||
<div class="font-bold text-xxs text-green-700"><span>RLF: ${rlf} %</span></div>
|
||||
</div>
|
||||
`,
|
||||
{
|
||||
permanent: true,
|
||||
// direction: "auto",
|
||||
offset: [60, 0],
|
||||
interactive: true,
|
||||
}
|
||||
);
|
||||
|
||||
let currentMouseLatLng = null;
|
||||
const mouseMoveHandler = (event) => {
|
||||
currentMouseLatLng = event.latlng;
|
||||
};
|
||||
map.on("mousemove", mouseMoveHandler);
|
||||
|
||||
marker.on("tooltipopen", (e) => {
|
||||
const tooltipElement = e.tooltip._contentNode;
|
||||
|
||||
if (tooltipElement) {
|
||||
tooltipElement.addEventListener("contextmenu", (event) => {
|
||||
event.preventDefault();
|
||||
closeContextMenu(); // Altes Menü schließen
|
||||
|
||||
// Kontextmenü-Items definieren
|
||||
const combinedContextMenuItems = [
|
||||
{
|
||||
text: "Station öffnen (Tab)",
|
||||
icon: "/img/screen_new.png",
|
||||
callback: () => {
|
||||
//hostname without port
|
||||
const hostname = window.location.hostname;
|
||||
const port = 80;
|
||||
const correctUrl = `http://${hostname}:${port}${basePath}/devices/${marker.options.link}`;
|
||||
const fullUrl = correctUrl;
|
||||
console.log(fullUrl);
|
||||
window.open(fullUrl, "_blank");
|
||||
markers.forEach((markerData) => {
|
||||
const marker = L.marker([markerData.lat, markerData.lng], {
|
||||
contextmenu: true,
|
||||
contextmenuItems: [
|
||||
{
|
||||
text: "Station öffnen (Tab)",
|
||||
icon: "/img/screen_new.png",
|
||||
callback: () =>
|
||||
openInNewTab(null, {
|
||||
options: {
|
||||
link: markerData.link,
|
||||
},
|
||||
},
|
||||
{ separator: true },
|
||||
{
|
||||
text: "Koordinaten anzeigen",
|
||||
icon: "/img/not_listed_location.png",
|
||||
callback: () => {
|
||||
if (currentMouseLatLng) {
|
||||
alert(`Breitengrad: ${currentMouseLatLng.lat.toFixed(5)}\nLängengrad: ${currentMouseLatLng.lng.toFixed(5)}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
{ separator: true },
|
||||
{
|
||||
text: "Reinzoomen",
|
||||
icon: "/img/zoom_in.png",
|
||||
callback: () => zoomIn(map, marker.getLatLng()),
|
||||
},
|
||||
{
|
||||
text: "Rauszoomen",
|
||||
icon: "/img/zoom_out.png",
|
||||
callback: () => zoomOut(map),
|
||||
},
|
||||
{
|
||||
text: "Hier zentrieren",
|
||||
icon: "/img/center_focus.png",
|
||||
callback: () => centerHere(map, marker.getLatLng()),
|
||||
},
|
||||
];
|
||||
|
||||
// Menü erstellen und anzeigen
|
||||
const menu = document.createElement("div");
|
||||
menu.className = "custom-context-menu";
|
||||
menu.style.position = "absolute";
|
||||
menu.style.left = `${event.clientX}px`;
|
||||
menu.style.top = `${event.clientY}px`;
|
||||
menu.style.backgroundColor = "#fff";
|
||||
menu.style.border = "1px solid #ccc";
|
||||
menu.style.padding = "4px";
|
||||
menu.style.zIndex = "1000";
|
||||
|
||||
combinedContextMenuItems.forEach((item) => {
|
||||
if (item.separator) {
|
||||
const separator = document.createElement("hr");
|
||||
menu.appendChild(separator);
|
||||
} else {
|
||||
const menuItem = document.createElement("div");
|
||||
menuItem.style.display = "flex";
|
||||
menuItem.style.alignItems = "center";
|
||||
menuItem.style.cursor = "pointer";
|
||||
menuItem.style.padding = "4px";
|
||||
|
||||
if (item.icon) {
|
||||
const icon = document.createElement("img");
|
||||
icon.src = item.icon;
|
||||
icon.style.width = "16px";
|
||||
icon.style.marginRight = "8px";
|
||||
menuItem.appendChild(icon);
|
||||
}
|
||||
|
||||
const text = document.createElement("span");
|
||||
text.textContent = item.text;
|
||||
menuItem.appendChild(text);
|
||||
|
||||
menuItem.onclick = () => {
|
||||
item.callback();
|
||||
closeContextMenu();
|
||||
};
|
||||
menu.appendChild(menuItem);
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(menu);
|
||||
currentMenu = menu;
|
||||
|
||||
const handleClickOutside = (e) => {
|
||||
if (menu && !menu.contains(e.target)) {
|
||||
closeContextMenu();
|
||||
document.removeEventListener("click", handleClickOutside);
|
||||
}
|
||||
};
|
||||
document.addEventListener("click", handleClickOutside);
|
||||
});
|
||||
}
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
marker.on("tooltipclose", () => {
|
||||
map.off("mousemove", mouseMoveHandler);
|
||||
closeContextMenu();
|
||||
});
|
||||
markerGroup.addLayer(marker);
|
||||
|
||||
GMA.addLayer(marker);
|
||||
oms.addMarker(marker);
|
||||
// Optional: highlight selected marker
|
||||
if (selectedMarkerId && markerData.id === selectedMarkerId) {
|
||||
marker.setZIndexOffset(1000);
|
||||
marker.setIcon(
|
||||
L.icon({
|
||||
iconUrl: "/img/marker-selected.png",
|
||||
iconSize: [25, 41],
|
||||
iconAnchor: [12, 41],
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
map.addLayer(GMA);
|
||||
markerGroup.addTo(map);
|
||||
|
||||
return () => {
|
||||
GMA.clearLayers();
|
||||
map.removeLayer(GMA);
|
||||
closeContextMenu();
|
||||
markerGroup.clearLayers();
|
||||
map.removeLayer(markerGroup);
|
||||
};
|
||||
}, [map, markers, GisStationsMeasurements, GMA, oms, isVisible]);
|
||||
|
||||
return null;
|
||||
}, [map, markers, selectedMarkerId]);
|
||||
};
|
||||
|
||||
export default useGmaMarkersLayer;
|
||||
|
||||
Reference in New Issue
Block a user