diff --git a/.env.local b/.env.local index a6abb14d5..ffea95242 100644 --- a/.env.local +++ b/.env.local @@ -9,5 +9,10 @@ DB_PORT=3306 # Public Settings (Client braucht IP/Domain) NEXT_PUBLIC_SERVER_URL="http://10.10.0.70" # oder evtl. später https://nodemap.firma.de NEXT_PUBLIC_ENABLE_GEOCODER=true -NEXT_PUBLIC_USE_MOCK_API=true +NEXT_PUBLIC_USE_MOCK_API=false NEXT_PUBLIC_DEBUG_LOG=true + +# für Polylines/kabelstecken -> in Konextmenü "Station öffnen" " +NEXT_PUBLIC_BASE_URL=http://10.10.0.70/talas5/devices/ +NEXT_PUBLIC_API_BASE_URL=http://10.10.0.70/talas5/ClientData/WebServiceMap.asmx +NEXT_PUBLIC_API_PORT_3000=http://10.10.0.70:3000 diff --git a/components/AddPOIModal.js b/components/AddPOIModal.js new file mode 100644 index 000000000..23f747e26 --- /dev/null +++ b/components/AddPOIModal.js @@ -0,0 +1,185 @@ +// components/ShowAddStationPopup.js +import React, { useState, useEffect, use } from "react"; +import ReactDOM from "react-dom"; +import { useRecoilValue, useRecoilState, useSetRecoilState } from "recoil"; +import { readPoiMarkersStore } from "../redux/slices/readPoiMarkersStoreSlice.js"; +import { poiReadFromDbTriggerAtom } from "../redux/slices/poiReadFromDbTriggerSlice.js"; +import { selectGisStationsStatic } from "../redux/slices/webService/gisStationsStaticSlice"; +import { useDispatch, useSelector } from "react-redux"; +import { fetchPoiTypes } from "../redux/slices/db/poiTypesSlice"; + +const ShowAddStationPopup = ({ onClose, map, latlng }) => { + const dispatch = useDispatch(); + + const poiTypData = useSelector((state) => state.poiTypes.data); + + const [name, setName] = useState(""); + const [poiTypeId, setPoiTypeId] = useState(""); // Initialize as string + const [poiTypeName, setPoiTypeName] = useState(""); // Initialize as string + + const [latitude] = useState(latlng.lat.toFixed(5)); + const [longitude] = useState(latlng.lng.toFixed(5)); + const setLoadData = useSetRecoilState(readPoiMarkersStore); + const setTrigger = useSetRecoilState(poiReadFromDbTriggerAtom); + const [deviceName, setDeviceName] = useState(""); + //----------------------------------------------------- + useEffect(() => { + const fetchpoiTypData = async () => { + try { + const response = await fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"); + const data = await response.json(); + setpoiTypData(data); + + if (data && data.length > 0) { + console.log("POI-Typen geladen:", data); + setPoiTypeId(data[0].idPoiTyp); // Setzt den ersten Typ + setPoiTypeName(data[0].name); + } + } catch (error) { + console.error("Fehler beim Abrufen der poiTyp Daten:", error); + } + }; + + fetchpoiTypData(); + }, []); + + useEffect(() => { + if (poiTypData.length > 0 && !poiTypeId) { + setPoiTypeId(poiTypData[0].idPoiTyp); + } + }, [poiTypData]); + useEffect(() => { + console.log("Aktueller POI Type:", poiTypeId); + }, [poiTypeId]); + + //------------------------------------------------------------------------------------------ + const gisStationsStatic = useSelector(selectGisStationsStatic); + const locationDeviceData = gisStationsStatic?.Points ?? []; + + console.log("gisStationsStatic aus AddPOIModal:", gisStationsStatic); + + useEffect(() => { + if (locationDeviceData?.length > 0) { + console.log("🎯 Gerätedaten erfolgreich geladen:", locationDeviceData); + setDeviceName((prev) => prev || locationDeviceData[0]?.LD_Name || ""); + } + }, [locationDeviceData]); + + //------------------------------------------------------------------------------------------ + //-----------------handleSubmit------------------- + const handleSubmit = async (event) => { + event.preventDefault(); + const formData = { + name, + poiTypeId: Number(poiTypeId), // Umwandlung in eine Zahl + latitude, + longitude, + idLD: locationDeviceData.find((device) => device.LD_Name === deviceName)?.IdLD, + }; + + const response = await fetch("/api/talas_v5_DB/pois/addLocation", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(formData), + }); + + if (response.ok) { + setTrigger((trigger) => { + console.log("Aktueller Trigger-Wert:", trigger); // Vorheriger Wert + const newTrigger = trigger + 1; + console.log("Neuer Trigger-Wert:", newTrigger); // Aktualisierter Wert + onClose(); + return newTrigger; + }); + } else { + console.error("Fehler beim Hinzufügen des POI"); + } + + if (map && typeof map.closePopup === "function") { + map.closePopup(); + } + //Seite neu laden + window.location.reload(); + }; + //----------------- + // POI-Typen aus Redux laden, wenn die Komponente gemountet wird + useEffect(() => { + dispatch(fetchPoiTypes()); + }, [dispatch]); + + //--------------------- + + return ( +
+
e.stopPropagation()}> + {/* Schließen-Button */} + + + {/* Modal-Inhalt */} +
+
+ + setName(e.target.value)} placeholder="Name der Station" className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" /> +
+ +
+ + +
+
+ + +
+ +
+ Lat: {latitude} + Lng: {longitude} +
+ + +
+
+
+ ); +}; + +export default ShowAddStationPopup; diff --git a/components/AddPOIOnPolyline.js b/components/AddPOIOnPolyline.js new file mode 100644 index 000000000..904333c8f --- /dev/null +++ b/components/AddPOIOnPolyline.js @@ -0,0 +1,61 @@ +import React, { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { closeAddPoiOnPolylineModal } from "../redux/slices/addPoiOnPolylineSlice"; + +const AddPOIOnPolyline = () => { + const dispatch = useDispatch(); + const { isOpen, latlng } = useSelector((state) => state.addPoiOnPolyline); + + const [name, setName] = useState(""); + const [latitude, setLatitude] = useState(""); + const [longitude, setLongitude] = useState(""); + + useEffect(() => { + if (latlng) { + setLatitude(latlng.lat.toFixed(5)); + setLongitude(latlng.lng.toFixed(5)); + } + }, [latlng]); + + if (!isOpen) return null; + + const handleSubmit = async (event) => { + event.preventDefault(); + + const formData = { name, latitude, longitude }; + console.log("Neuer POI auf Polyline:", formData); + + dispatch(closeAddPoiOnPolylineModal()); // Schließt das Modal nach dem Speichern + }; + + return ( +
dispatch(closeAddPoiOnPolylineModal())}> +
e.stopPropagation()}> +

POI auf Polyline hinzufügen

+ +
+
+ + setName(e.target.value)} className="border p-2 w-full" required /> +
+ +
+ + +
+ +
+ + +
+ + +
+
+
+ ); +}; + +export default AddPOIOnPolyline; diff --git a/components/DataSheet.js b/components/DataSheet.js index 9d5c2f81b..b00a21eb0 100644 --- a/components/DataSheet.js +++ b/components/DataSheet.js @@ -1,8 +1,8 @@ // /componentss/DataSheet.js import React, { useEffect, useState } from "react"; import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; -import { gisStationsStaticDistrictState } from "../redux/slices/gisStationsStaticDistrictSlice"; -import { gisSystemStaticState } from "../redux/slices/gisSystemStaticSlice"; +import { gisStationsStaticDistrictState } from "../redux/slices/webService/gisStationsStaticDistrictSlice"; +import { gisSystemStaticState } from "../redux/slices/webService/gisSystemStaticSlice.js"; import { mapLayersState } from "../redux/slices/mapLayersSlice"; import { selectedAreaState } from "../redux/slices/selectedAreaSlice"; import { zoomTriggerState } from "../redux/slices/zoomTriggerSlice.js"; @@ -10,8 +10,12 @@ import { poiLayerVisibleState } from "../redux/slices/poiLayerVisibleSlice"; import EditModeToggle from "./EditModeToggle"; import { polylineLayerVisibleState } from "../redux/slices/polylineLayerVisibleSlice"; // Import für Polyline-Visibility import { useSelector, useDispatch } from "react-redux"; -import { selectGisStationsStaticDistrict } from "../redux/slices/gisStationsStaticDistrictSlice"; import { selectPolylineVisible, setPolylineVisible } from "../redux/slices/polylineLayerVisibleSlice"; +import { selectGisSystemStatic } from "../redux/slices/webService/gisSystemStaticSlice"; +import { useInitGisStationsStatic } from "../components/mainComponent/hooks/webServices/useInitGisStationsStatic"; + +import { fetchGisStationsStatic, selectGisStationsStatic } from "../redux/slices/webService/gisStationsStaticSlice"; +import { selectGisStationsStaticDistrict } from "../redux/slices/webService/gisStationsStaticDistrictSlice"; function DataSheet() { const [editMode, setEditMode] = useState(false); // Zustand für editMode @@ -20,9 +24,10 @@ function DataSheet() { const [mapLayersVisibility, setMapLayersVisibility] = useRecoilState(mapLayersState); const [stationListing, setStationListing] = useState([]); const [systemListing, setSystemListing] = useState([]); - //const GisStationsStaticDistrict = useRecoilValue(gisStationsStaticDistrictState); - const GisStationsStaticDistrict = useSelector(selectGisStationsStaticDistrict); - const GisSystemStatic = useRecoilValue(gisSystemStaticState); + const GisStationsStaticDistrict = useSelector(selectGisStationsStaticDistrict) || []; + const GisSystemStatic = useSelector(selectGisSystemStatic) || []; + const GisStationsStatic = useSelector(selectGisStationsStatic) || []; //Area-Name/Bereiche dropdownmenu + const setZoomTrigger = useSetRecoilState(zoomTriggerState); const dispatch = useDispatch(); const polylineVisible = useSelector(selectPolylineVisible); @@ -73,16 +78,18 @@ function DataSheet() { }; useEffect(() => { - const allowedSystems = new Set(GisSystemStatic.filter((system) => system.Allow === 1).map((system) => system.IdSystem)); + 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.filter((item) => { - const isUnique = !seenNames.has(item.Area_Name) && allowedSystems.has(item.System); - if (isUnique) { - seenNames.add(item.Area_Name); - } - return isUnique; - }); + const filteredAreas = Array.isArray(GisStationsStaticDistrict) + ? GisStationsStaticDistrict.filter((item) => { + const isUnique = !seenNames.has(item.Area_Name) && allowedSystems.has(item.System); + if (isUnique) { + seenNames.add(item.Area_Name); + } + return isUnique; + }) + : []; setStationListing( filteredAreas.map((area, index) => ({ @@ -92,13 +99,15 @@ function DataSheet() { ); const seenSystemNames = new Set(); - const filteredSystems = GisSystemStatic.filter((item) => { - const isUnique = !seenSystemNames.has(item.Name) && item.Allow === 1; - if (isUnique) { - seenSystemNames.add(item.Name); - } - return isUnique; - }); + const filteredSystems = Array.isArray(GisSystemStatic) + ? GisSystemStatic.filter((item) => { + const isUnique = !seenSystemNames.has(item.Name) && item.Allow === 1; + if (isUnique) { + seenSystemNames.add(item.Name); + } + return isUnique; + }) + : []; setSystemListing( filteredSystems.map((system, index) => ({ @@ -150,6 +159,49 @@ function DataSheet() { localStorage.setItem("standorteVisible", checked); }; //------------------------------ + useEffect(() => { + // console.log("GisSystemStatic aus Redux:", GisSystemStatic); // ✅ Debugging: Ist es ein Array? + }, [GisSystemStatic]); + //----------------------------- + useInitGisStationsStatic(); + //--------------------------- + useEffect(() => { + //console.log("🔍 GisStationsStatic Inhalt:", GisStationsStatic); + + if (!GisStationsStatic) { + console.warn("⚠️ GisStationsStatic ist `null` oder nicht geladen."); + return; + } + + if (typeof GisStationsStatic !== "object") { + console.warn("⚠️ GisStationsStatic ist kein Objekt:", GisStationsStatic); + return; + } + + if (!GisStationsStatic.Points || !Array.isArray(GisStationsStatic.Points)) { + //console.warn("⚠️ GisStationsStatic.Points ist nicht vorhanden oder kein Array.", GisStationsStatic); + return; + } + + const seenNames = new Set(); + const filteredAreas = GisStationsStatic.Points.filter((item) => { + if (!item.Area_Name) return false; // Sicherstellen, dass Area_Name existiert + const isUnique = !seenNames.has(item.Area_Name); + if (isUnique) { + seenNames.add(item.Area_Name); + } + return isUnique; + }); + + setStationListing( + filteredAreas.map((area, index) => ({ + id: area.IdArea || index + 1, + name: area.Area_Name || "Unbekannt", + })) + ); + + // console.log("📌 stationListing aktualisiert:", filteredAreas); + }, [GisStationsStatic]); //--------------------------- return ( diff --git a/components/PoiUpdateModal.js b/components/PoiUpdateModal.js index d9811ab53..93e07c287 100644 --- a/components/PoiUpdateModal.js +++ b/components/PoiUpdateModal.js @@ -1,11 +1,15 @@ -// pages/api/poiUpdateModal.js -// +// /components/PoiUpdateModal.js import React, { useState, useEffect } from "react"; import { useRecoilValue } from "recoil"; import { selectedPoiState } from "../redux/slices/selectedPoiSlice"; import { currentPoiState } from "../redux/slices/currentPoiSlice"; +import { fetchLocationDevicesFromDB } from "../redux/slices/db/locationDevicesFromDBSlice"; +import { useDispatch, useSelector } from "react-redux"; const PoiUpdateModal = ({ onClose, poiData }) => { + const dispatch = useDispatch(); + const devices = useSelector((state) => state.locationDevicesFromDB.devices); + const currentPoi = useRecoilValue(currentPoiState); const selectedPoi = useRecoilValue(selectedPoiState); const [poiId, setPoiId] = useState(poiData ? poiData.idPoi : ""); @@ -19,6 +23,10 @@ const PoiUpdateModal = ({ onClose, poiData }) => { const [description, setDescription] = useState(poiData ? poiData.description : ""); + useEffect(() => { + dispatch(fetchLocationDevicesFromDB()); + }, [dispatch]); + // Log the initial POI data useEffect(() => { if (poiData) { @@ -117,28 +125,6 @@ const PoiUpdateModal = ({ onClose, poiData }) => { fetchPoiTypData(); }, [selectedPoi]); - // Fetch device data um den Gerät Namen in den dropdown menu anzuzeigen also erstmal die Liste der Geräte abrufen - useEffect(() => { - const fetchData = async () => { - try { - // const response = await fetch("/api/talas_v5/location_device"); //"/api/talas_v5_DB/locationDevice/location_device" - const response = await fetch("/api/talas_v5_DB/locationDevice/locationDevices"); - const data = await response.json(); - //console.log("Standort- und Gerätedaten:", data); - setLocationDeviceData(data); - console.log("Standort- und Gerätedaten poiData:", poiData); - if (poiData && poiData.idLD) { - const selectedDevice = data.find((device) => device.id === poiData.idLD); - setDeviceName(selectedDevice ? selectedDevice.id : data[0].id); // Hier wird die ID als initialer Zustand gesetzt - console.log("Selected Device:", selectedDevice); - console.log("Selected devciceName:", deviceName); - } - } catch (error) { - console.error("Fehler beim Abrufen der Standort- und Gerätedaten:", error); - } - }; - fetchData(); - }, []); //-------------------------------------------------------------------------------------------- // Fetch device name basierend auf der Geräte-ID diff --git a/components/ShowAddStationPopup.js b/components/ShowAddStationPopup.js deleted file mode 100644 index 7b770e0ec..000000000 --- a/components/ShowAddStationPopup.js +++ /dev/null @@ -1,171 +0,0 @@ -// components/ShowAddStationPopup.js -import React, { useState, useEffect, use } from "react"; -import ReactDOM from "react-dom"; -import { useRecoilValue, useRecoilState, useSetRecoilState } from "recoil"; -import { readPoiMarkersStore } from "../redux/slices/readPoiMarkersStoreSlice.js"; -import { poiReadFromDbTriggerAtom } from "../redux/slices/poiReadFromDbTriggerSlice"; - -const ShowAddStationPopup = ({ onClose, map, latlng }) => { - const [poiTypData, setpoiTypData] = useState(); // Recoil State verwenden - const [name, setName] = useState(""); - const [poiTypeId, setPoiTypeId] = useState(""); // Initialize as string - const [poiTypeName, setPoiTypeName] = useState(""); // Initialize as string - const [latitude] = useState(latlng.lat.toFixed(5)); - const [longitude] = useState(latlng.lng.toFixed(5)); - const setLoadData = useSetRecoilState(readPoiMarkersStore); - const setTrigger = useSetRecoilState(poiReadFromDbTriggerAtom); - const [locationDeviceData, setLocationDeviceData] = useState([]); - const [deviceName, setDeviceName] = useState(""); - - useEffect(() => { - const fetchpoiTypData = async () => { - try { - const response = await fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"); - const data = await response.json(); - setpoiTypData(data); - if (data && data.length > 0) { - setPoiTypeId(data[0].idPoiTyp); // Set initial poiTypeId to the id of the first poiType - setPoiTypeName(data[1].name); // Set initial poiTypeName to the name of the first poiType - console.log("Initial poiTypeId set in ShowAddStationPopup.js :", data[0].idPoiTyp); - } - } catch (error) { - console.error("Fehler beim Abrufen der poiTyp Daten:", error); - } - }; - - fetchpoiTypData(); - }, []); - - //--------------------------------------------------------------------------------------- - /* useEffect(() => { - // Funktion zum Abrufen der Daten von der API -> DB talas_v5.location_device - const fetchData = async () => { - try { - const response = await fetch("/api/talas_v5/location_device"); // Pfad zu Ihrem API-Endpunkt - const data = await response.json(); - setLocationDeviceData(data); // Setzt den Zustand mit den abgerufenen Daten - console.log("Abgerufene Standort- und Gerätedaten:", data); - } catch (error) { - console.error( - "Fehler beim Abrufen der Standort- und Gerätedaten:", - error - ); - } - }; - - fetchData(); - }, []); // Leerarray als Dependency, um den Effekt nur beim Laden der Komponente auszuführen */ - - //------------------------------------------------------------------------------------------ - useEffect(() => { - // Funktion zum Abrufen der Daten von der API -> DB talas_v5.location_device - const fetchData = async () => { - try { - const response = await fetch("/api/talas5/location_device"); - const data = await response.json(); - setLocationDeviceData(data); - if (data.length > 0) { - setDeviceName(data[0].name); // Setzen des anfänglichen Gerätenamens - } - console.log("Abgerufene Standort- und Gerätedaten:", data); - } catch (error) { - console.error("Fehler beim Abrufen der Standort- und Gerätedaten:", error); - } - }; - - fetchData(); - }, []); - - //------------------------------------------------------------------------------------------ - //-----------------handleSubmit------------------- - const handleSubmit = async (event) => { - event.preventDefault(); - const formData = { - name, - poiTypeId, - latitude, - longitude, - idLD: locationDeviceData.find((device) => device.name === deviceName).idLD, - }; - - const response = await fetch("/api/talas_v5_DB/pois/addLocation", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(formData), - }); - - if (response.ok) { - setTrigger((trigger) => { - console.log("Aktueller Trigger-Wert:", trigger); // Vorheriger Wert - const newTrigger = trigger + 1; - console.log("Neuer Trigger-Wert:", newTrigger); // Aktualisierter Wert - onClose(); - return newTrigger; - }); - } else { - console.error("Fehler beim Hinzufügen des POI"); - } - - if (map && typeof map.closePopup === "function") { - map.closePopup(); - } - }; - //-----------------handleSubmit------------------- - - return ( -
-
- - setName(e.target.value)} placeholder="Name der Station" className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" /> -
- - {/* {locationDeviceData.----------------------------------------------*/} -
- - -
- {/* {locationDeviceData.----------------------------------------------*/} -
- - -
-
-
- -
-
- -
-
- - -
- ); -}; - -export default ShowAddStationPopup; diff --git a/components/TestScript.js b/components/TestScript.js index c34b9f7dc..4a193d892 100644 --- a/components/TestScript.js +++ b/components/TestScript.js @@ -1,6 +1,6 @@ // components/TestScript.js import { useEffect } from "react"; -import setupPolylinesCode from "!!raw-loader!../utils/setupPolylines.js"; // Lädt die gesamte setupPolylines.js als Text +import setupPolylinesCode from "!!raw-loader!../utils/polylines/setupPolylines.js"; // Lädt die gesamte setupPolylines.js als Text export default function TestScript() { useEffect(() => { diff --git a/components/MapComponent.js b/components/mainComponent/MapComponent.js similarity index 76% rename from components/MapComponent.js rename to components/mainComponent/MapComponent.js index 64509ff23..ada4bacc0 100644 --- a/components/MapComponent.js +++ b/components/mainComponent/MapComponent.js @@ -1,77 +1,98 @@ -// components/MapComponent.js +// components/mainComponent/MapComponent.js import React, { useEffect, useRef, useState, useCallback } from "react"; import L from "leaflet"; import "leaflet/dist/leaflet.css"; import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; import "leaflet-contextmenu"; -import * as config from "../config/config.js"; +import * as config from "../../config/config.js"; import "leaflet.smooth_marker_bouncing"; import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; //sieht deaktiviert aber ist das nicht so und wird benötigt import "react-toastify/dist/ReactToastify.css"; -import DataSheet from "./DataSheet.js"; +import DataSheet from "../DataSheet.js"; import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; -import AddPoiModalWindow from "./pois/AddPoiModalWindow.js"; +import AddPoiModalWindow from "../pois/AddPoiModalWindow.js"; import { InformationCircleIcon } from "@heroicons/react/20/solid"; -import PoiUpdateModal from "./pois/PoiUpdateModal.js"; +import PoiUpdateModal from "../pois/PoiUpdateModal.js"; import { ToastContainer, toast } from "react-toastify"; -import plusRoundIcon from "./PlusRoundIcon.js"; -import { createAndSetDevices } from "../utils/createAndSetDevices.js"; -import { restoreMapSettings, checkOverlappingMarkers } from "../utils/mapUtils.js"; -import { APP_VERSION } from "../config/appVersion"; -import * as layers from "../config/layers.js"; -import { initializeMap } from "../utils/initializeMap.js"; -import addItemsToMapContextMenu from "./useMapContextMenu.js"; -import useGmaMarkersLayer from "../hooks/layers/useGmaMarkersLayer.js"; // Import the custom hook -import useSmsfunkmodemMarkersLayer from "../hooks/layers/useSmsfunkmodemMarkersLayer.js"; -import useBereicheMarkersLayer from "../hooks/layers/useBereicheMarkersLayer.js"; -import { setupPolylines } from "../utils/setupPolylines.js"; -import { setupPOIs } from "../utils/setupPOIs.js"; -import VersionInfoModal from "./VersionInfoModal.js"; -import useDrawLines from "../hooks/layers/useDrawLines"; -import useFetchPoiData from "../hooks/useFetchPoiData"; -import usePoiTypData from "../hooks/usePoiTypData"; -import useLayerVisibility from "../hooks/useLayerVisibility"; -import useLineData from "../hooks/useLineData.js"; +import plusRoundIcon from "../PlusRoundIcon.js"; +import { createAndSetDevices } from "../../utils/createAndSetDevices.js"; +import { restoreMapSettings, checkOverlappingMarkers } from "../../utils/mapUtils.js"; +import { APP_VERSION } from "../../config/appVersion.js"; +import * as layers from "../../config/layers.js"; +import { initializeMap } from "../../utils/initializeMap.js"; +import addItemsToMapContextMenu from "../useMapContextMenu.js"; +import useGmaMarkersLayer from "../../hooks/layers/useGmaMarkersLayer.js"; // Import the custom hook +import useSmsfunkmodemMarkersLayer from "../../hooks/layers/useSmsfunkmodemMarkersLayer.js"; +import useBereicheMarkersLayer from "../../hooks/layers/useBereicheMarkersLayer.js"; +import { setupPolylines } from "../../utils/polylines/setupPolylines.js"; +import { setupPOIs } from "../../utils/setupPOIs.js"; +import VersionInfoModal from "../VersionInfoModal.js"; +import useDrawLines from "../../hooks/layers/useDrawLines.js"; +import useFetchPoiData from "../../hooks/useFetchPoiData.js"; +import usePoiTypData from "../../hooks/usePoiTypData.js"; +import useLayerVisibility from "../../hooks/useLayerVisibility.js"; +import useLineData from "../../hooks/useLineData.js"; //import { useCreateAndSetDevices } from "../hooks/useCreateAndSetDevices"; -import { useMapComponentState } from "../hooks/useMapComponentState"; -import { disablePolylineEvents, enablePolylineEvents } from "../utils/setupPolylines"; -import { updateLocation } from "../utils/updateBereichUtil"; -import { initGeocoderFeature } from "../components/features/GeocoderFeature"; +import { useMapComponentState } from "../../hooks/useMapComponentState.js"; +import { updateLocation } from "../../utils/updateBereichUtil.js"; +import { initGeocoderFeature } from "../features/GeocoderFeature.js"; //-------------------------------------------- //import { currentPoiState } from "../redux/slices/currentPoiSlice.js"; -import { selectGisStationsStaticDistrict, setGisStationsStaticDistrict } from "../redux/slices/gisStationsStaticDistrictSlice"; -import { mapIdState, userIdState } from "../redux/slices/urlParameterSlice.js"; -import { poiLayerVisibleState } from "../redux/slices/poiLayerVisibleSlice.js"; -import { selectedPoiState } from "../redux/slices/selectedPoiSlice.js"; -import { poiReadFromDbTriggerAtom } from "../redux/slices/poiReadFromDbTriggerSlice"; -import { gisStationsStaticDistrictState } from "../redux/slices/gisStationsStaticDistrictSlice"; -import { gisSystemStaticState } from "../redux/slices/gisSystemStaticSlice"; -import { mapLayersState } from "../redux/slices/mapLayersSlice"; -import { selectedAreaState } from "../redux/slices/selectedAreaSlice"; -import { zoomTriggerState } from "../redux/slices/zoomTriggerSlice.js"; -import { polylineEventsDisabledState } from "../redux/slices/polylineEventsDisabledSlice"; -import { polylineLayerVisibleState } from "../redux/slices/polylineLayerVisibleSlice"; + +import { mapIdState, userIdState } from "../../redux/slices/urlParameterSlice.js"; +import { poiLayerVisibleState } from "../../redux/slices/poiLayerVisibleSlice.js"; +import { selectedPoiState } from "../../redux/slices/selectedPoiSlice.js"; +import { poiReadFromDbTriggerAtom } from "../../redux/slices/poiReadFromDbTriggerSlice.js"; +import { gisSystemStaticState } from "../../redux/slices/webService/gisSystemStaticSlice.js"; +import { mapLayersState } from "../../redux/slices/mapLayersSlice.js"; +import { selectedAreaState } from "../../redux/slices/selectedAreaSlice.js"; +import { zoomTriggerState } from "../../redux/slices/zoomTriggerSlice.js"; +import { polylineEventsDisabledState } from "../../redux/slices/polylineEventsDisabledSlice.js"; +import { polylineLayerVisibleState } from "../../redux/slices/polylineLayerVisibleSlice.js"; //-------------------------------------------- import { useSelector, useDispatch } from "react-redux"; -import { selectCurrentPoi, setCurrentPoi, clearCurrentPoi } from "../redux/slices/currentPoiSlice"; -import CoordinateInput from "./CoordinateInput"; -import CoordinateModal from "./CoordinateModal"; -import CoordinatePopup from "./CoordinatePopup"; +import { selectCurrentPoi, setCurrentPoi, clearCurrentPoi } from "../../redux/slices/currentPoiSlice.js"; +import CoordinateInput from "../CoordinateInput.js"; +import CoordinateModal from "../CoordinateModal.js"; +import CoordinatePopup from "../CoordinatePopup.js"; //------------------------Daten aus API-------------------- -import { fetchUserRights } from "../services/api/fetchUserRights.js"; -import { fetchPoiData } from "../services/api/fetchPoiData.js"; -import { fetchGisStationsStaticDistrict } from "../services/api/fetchGisStationsStaticDistrict.js"; +import { fetchUserRights } from "../../services/api/fetchUserRights.js"; +import { fetchPoiData } from "../../services/api/fetchPoiData.js"; +import { fetchGisStationsStaticDistrict } from "../../services/api/fetchGisStationsStaticDistrict.js"; -import { fetchGisStationsStatusDistrict } from "../services/api/fetchGisStationsStatusDistrict.js"; +import { fetchGisStationsStatusDistrict } from "../../services/api/fetchGisStationsStatusDistrict.js"; -import { fetchGisStationsMeasurements } from "../services/api/fetchGisStationsMeasurements.js"; -import { fetchGisSystemStatic } from "../services/api/fetchGisSystemStatic.js"; -import { usePolylineTooltipLayer } from "../hooks/usePolylineTooltipLayer"; -import { selectPolylineVisible, setPolylineVisible } from "../redux/slices/polylineLayerVisibleSlice"; +import { fetchGisStationsMeasurements } from "../../services/api/fetchGisStationsMeasurements.js"; +import { fetchGisSystemStatic } from "../../services/api/fetchGisSystemStatic.js"; +import { usePolylineTooltipLayer } from "../../hooks/usePolylineTooltipLayer.js"; +import { selectPolylineVisible, setPolylineVisible } from "../../redux/slices/polylineLayerVisibleSlice.js"; +import { useInitLocationDevices } from "./hooks/webServices/useInitLocationDevices"; +import { useInitGisStationsStaticDistrict } from "./hooks/webServices/useInitGisStationsStaticDistrict"; +import { selectGisStationsStaticDistrict } from "../../redux/slices/webService/gisStationsStaticDistrictSlice"; +import { useInitGisStationsStatusDistrict } from "./hooks/webServices/useInitGisStationsStatusDistrict"; +import { useInitGisStationsMeasurements } from "./hooks/webServices/useInitGisStationsMeasurements"; +import { useInitGisSystemStatic } from "./hooks/webServices/useInitGisSystemStatic"; +import { selectGisSystemStatic, setGisSystemStatic } from "../../redux/slices/webService/gisSystemStaticSlice"; +import ShowAddStationPopup from "../AddPOIModal.js"; +import { useInitGisStationsStatic } from "../mainComponent/hooks/webServices/useInitGisStationsStatic"; +import { closeAddPoiModal } from "../../redux/slices/addPoiOnPolylineSlice.js"; +import AddPOIOnPolyline from "../AddPOIOnPolyline"; +import { enablePolylineEvents, disablePolylineEvents } from "../../utils/polylines/eventHandlers"; +import { updateCountdown, closePolylineContextMenu, forceCloseContextMenu } from "../../redux/slices/polylineContextMenuSlice"; +//-------------------MapComponent.js hooks-------------------- +import useInitializeMap from "./hooks/useInitializeMap"; +import useLoadUserRights from "./hooks/useLoadUserRights"; const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const dispatch = useDispatch(); + const countdown = useSelector((state) => state.polylineContextMenu.countdown); + const countdownActive = useSelector((state) => state.polylineContextMenu.countdownActive); + const isPolylineContextMenuOpen = useSelector((state) => state.polylineContextMenu.isOpen); + + const contextMenuState = useSelector((state) => state.polylineContextMenu); + + const polylinePosition = contextMenuState.position ? L.latLng(contextMenuState.position.lat, contextMenuState.position.lng) : null; const currentPoi = useSelector(selectCurrentPoi); //const setCurrentPoi = useSetRecoilState(currentPoiState); const polylineVisible = useSelector(selectPolylineVisible); @@ -96,6 +117,8 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const coordinates = `${e.latlng.lat.toFixed(5)}, ${e.latlng.lng.toFixed(5)}`; setCurrentCoordinates(coordinates); setIsPopupOpen(true); + setPopupCoordinates(e.latlng); + setPopupVisible(true); }; const closePopup = () => setIsPopupOpen(false); @@ -110,7 +133,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const setSelectedPoi = useSetRecoilState(selectedPoiState); const [showPoiUpdateModal, setShowPoiUpdateModal] = useState(false); const [currentPoiData, setCurrentPoiData] = useState(null); - const [showVersionInfoModal, setShowVersionInfoModal] = useState(false); const zoomTrigger = useRecoilValue(zoomTriggerState); const [gisSystemStaticLoaded, setGisSystemStaticLoaded] = useState(false); @@ -121,11 +143,10 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte const [map, setMap] = useState(null); // Zustand der Karteninstanz const [oms, setOms] = useState(null); // State für OMS-Instanz - //const [GisStationsStaticDistrict, setGisStationsStaticDistrict] = useRecoilState(gisStationsStaticDistrictState); const GisStationsStaticDistrict = useSelector(selectGisStationsStaticDistrict); const [GisStationsStatusDistrict, setGisStationsStatusDistrict] = useState([]); // Zustand für Statusdaten const [GisStationsMeasurements, setGisStationsMeasurements] = useState([]); // Zustand für Messdaten - const [GisSystemStatic, setGisSystemStatic] = useRecoilState(gisSystemStaticState); // Zustand für Systemdaten + const GisSystemStatic = useSelector(selectGisSystemStatic); // Konstanten für die URLs const mapGisStationsStaticDistrictUrl = config.mapGisStationsStaticDistrictUrl; const mapGisStationsStatusDistrictUrl = config.mapGisStationsStatusDistrictUrl; @@ -133,7 +154,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const mapGisSystemStaticUrl = config.mapGisSystemStaticUrl; const webserviceGisLinesStatusUrl = config.webserviceGisLinesStatusUrl; //console.log("priorityConfig in MapComponent1: ", priorityConfig); - + //----------------------------------------- const [gmaMarkers, setGmaMarkers] = useState([]); //--------------------station.System === 11 alle sind untetschiedlich Nummern const [talasMarkers, setTalasMarkers] = useState([]); const [eciMarkers, setEciMarkers] = useState([]); @@ -150,7 +171,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const [ulafMarkers, setUlafMarkers] = useState([]); const [sonstigeMarkers, setSonstigeMarkers] = useState([]); const [tkComponentsMarkers, setTkComponentsMarkers] = useState([]); - + //-------------------------------------------- const [lineStatusData, setLineStatusData] = useState([]); const [linesData, setLinesData] = useState([]); const mapLayersVisibility = useRecoilValue(mapLayersState); @@ -160,34 +181,27 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const { lineColors, tooltipContents } = useLineData(webserviceGisLinesStatusUrl, setLineStatusData); const [polylines, setPolylines] = useState([]); const [markers, setMarkers] = useState([]); - const [newPoint, setNewPoint] = useState(null); const [newCoords, setNewCoords] = useState(null); const [tempMarker, setTempMarker] = useState(null); - - const [popupCoordinates, setPopupCoordinates] = useState({ - lat: 52.52, - lng: 13.405, - }); - + const [showPoiModal, setShowPoiModal] = useState(false); + const [showCoordinatesModal, setShowCoordinatesModal] = useState(false); + const [popupCoordinates, setPopupCoordinates] = useState(null); + const [popupVisible, setPopupVisible] = useState(false); const handleAddStation = (stationData) => { setAddPoiModalWindowState(false); closePopup(); // Schließt das Popup nach dem Hinzufügen }; - const openVersionInfoModal = () => { setShowVersionInfoModal(true); }; - const closeVersionInfoModal = () => { setShowVersionInfoModal(false); }; - const [currentZoom, setCurrentZoom] = useState(() => { const storedZoom = localStorage.getItem("mapZoom"); return storedZoom ? parseInt(storedZoom, 10) : 12; }); - const [currentCenter, setCurrentCenter] = useState(() => { const storedCenter = localStorage.getItem("mapCenter"); try { @@ -198,75 +212,52 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } }); const [polylineEventsDisabled, setPolylineEventsDisabled] = useRecoilState(polylineEventsDisabledState); // Recoil State - + const allMarkers = [ + ...talasMarkers, + ...eciMarkers, + ...lteModemMarkers, + ...ciscoRouterMarkers, + ...wagoMarkers, + ...siemensMarkers, + ...otdrMarkers, + ...wdmMarkers, + ...gmaMarkers, + ...messstellenMarkers, + ...talasiclMarkers, + ...dauzMarkers, + ...smsfunkmodemMarkers, + ...sonstigeMarkers, + ...tkComponentsMarkers, + ...ulafMarkers, + ]; + const useMock = process.env.NEXT_PUBLIC_USE_MOCK_API === "true"; + //-------------------------------------------- + const gmaLayerRef = useRef(null); + const talasLayerRef = useRef(null); + const eciMarkersLayerRef = useRef(null); + const lteModemMarkersLayerRef = useRef(null); + const ciscoRouterMarkersLayerRef = useRef(null); + const wagoMarkersLayerRef = useRef(null); + const siemensMarkersLayerRef = useRef(null); + const otdrMarkersLayerRef = useRef(null); + const wdmMarkersLayerRef = useRef(null); + const messstellenMarkersLayerRef = useRef(null); + const talasiclMarkersLayerRef = useRef(null); + const dauzMarkersLayerRef = useRef(null); + const smsfunkmodemMarkersLayerRef = useRef(null); + const ulafMarkersLayerRef = useRef(null); + const sonstigeMarkersLayerRef = useRef(null); + const tkComponentsMarkersRef = useRef(null); //--------------------------------------------------------------- - - /* useEffect(() => { - fetchGisStatusStations(12, 484); // Beispielaufruf mit idMap = 10 und idUser = 484 - }, []); */ - useEffect(() => { const params = new URL(window.location.href).searchParams; setMapId(params.get("m")); setUserId(params.get("u")); }, [setMapId, setUserId]); - - /* useEffect(() => { - if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded && isRightsLoaded) { - //console.log("Überprüfung der Berechtigung vor addItemsToMapContextMenu: ", hasRights); - addItemsToMapContextMenu(hasRights); - } - }, [ - map, - poiLayerRef, - isPoiTypLoaded, - menuItemAdded, // Hinzufügen zu den Abhängigkeiten, um den Effekt korrekt zu steuern - hasRights, // Sicherstellen, dass hasRights berücksichtigt wird - isRightsLoaded, // Überprüfung, ob die Rechte geladen sind - ]); */ - - useEffect(() => { - const fetchAndSetUserRights = async () => { - const rights = await fetchUserRights(); - setUserRights(rights); - setIsRightsLoaded(true); - - // Sicherstellen, dass `rights` ein Array ist, bevor `.includes()` aufgerufen wird - setHasRights(localStorage.getItem("editMode") && Array.isArray(rights) && rights.includes(56)); - }; - - fetchAndSetUserRights(); - }, []); - - useGmaMarkersLayer( - map, - gmaMarkers, - GisStationsMeasurements, - layers.MAP_LAYERS.GMA, - oms, - mapLayersVisibility.GMA // Übergebe die Sichtbarkeitsbedingung als Parameter - ); - - /* useSmsfunkmodemMarkersLayer( - map, - oms, - GisSystemStatic, - priorityConfig, - mapLayersVisibility.SMSFunkmodem // Sichtbarkeitsstatus aus dem State - ); */ - - const useMock = process.env.NEXT_PUBLIC_USE_MOCK_API === "true"; + //--------------------------------------------------------------- useEffect(() => { const fetchWebServiceMap = async () => { try { - let stationsStaticUrl = useMock ? "/mockData/gisStationsStaticDistrictMock.json" : mapGisStationsStaticDistrictUrl; - - let stationsStatusUrl = useMock ? "/mockData/gisStationsStatusDistrictMock.json" : mapGisStationsStatusDistrictUrl; - - let stationsMeasurementsUrl = useMock ? "/mockData/gisStationsMeasurementsMock.json" : mapGisStationsMeasurementsUrl; - - let systemStaticUrl = useMock ? "/mockData/gisSystemStaticMock.json" : mapGisSystemStaticUrl; - // Zähler für externe API-Aufrufe in localStorage speichern let requestCount = localStorage.getItem("fetchWebServiceMap") || 0; requestCount = parseInt(requestCount, 10); @@ -280,8 +271,8 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { // Fetch GIS Stations Static District /* await fetchGisStationsStaticDistrict(mapGisStationsStaticDistrictUrl, dispatch, fetchOptions); - requestCount++; // Zähler erhöhen - localStorage.setItem("fetchWebServiceMap", requestCount); */ + requestCount++; // Zähler erhöhen + localStorage.setItem("fetchWebServiceMap", requestCount); */ //console.log(`fetchWebServiceMap in MapComponent wurde ${requestCount} Mal aufgerufen.`); // Fetch GIS Stations Status District @@ -308,7 +299,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { fetchWebServiceMap(); }, [dispatch, mapGisStationsStaticDistrictUrl]); - //-------------------------------------------------------- useEffect(() => { const endpoint = "/api/talas_v5_DB/gisLines/readGisLines"; @@ -373,17 +363,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { fetchPoiData(); }, []); //-------------------------------------------- - - /* useEffect(() => { - if (map) { - const dbLayer = new L.LayerGroup().addTo(map); // Define dbLayer here - - return () => { - dbLayer.remove(); - }; - } - }, [map]); */ - //-------------------------------------------- // POIs auf die Karte zeichnen useEffect(() => { if (map && !poiLayerRef.current) { @@ -414,28 +393,8 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { if (gisSystemStaticLoaded && map) { } }, [gisSystemStaticLoaded, map, GisSystemStatic, priorityConfig]); - - //useCreateAndSetDevices(1, talasMarkers, GisSystemStatic, priorityConfig); - - useLayerVisibility(map, talasMarkers, mapLayersVisibility, "TALAS", oms); - useLayerVisibility(map, eciMarkers, mapLayersVisibility, "ECI", oms); - useLayerVisibility(map, lteModemMarkers, mapLayersVisibility, "LTEModem", oms); - useLayerVisibility(map, ciscoRouterMarkers, mapLayersVisibility, "CiscoRouter", oms); - useLayerVisibility(map, lteModemMarkers, mapLayersVisibility, "LTEModem", oms); - - useLayerVisibility(map, wagoMarkers, mapLayersVisibility, "WAGO", oms); - useLayerVisibility(map, siemensMarkers, mapLayersVisibility, "Siemens", oms); - useLayerVisibility(map, otdrMarkers, mapLayersVisibility, "OTDR", oms); - useLayerVisibility(map, wdmMarkers, mapLayersVisibility, "WDM", oms); - useLayerVisibility(map, gmaMarkers, mapLayersVisibility, "GMA", oms); - useLayerVisibility(map, sonstigeMarkers, mapLayersVisibility, "Sonstige", oms); - useLayerVisibility(map, tkComponentsMarkers, mapLayersVisibility, "TKKomponenten", oms); - useLayerVisibility(map, talasiclMarkers, mapLayersVisibility, "TALASICL", oms); - useLayerVisibility(map, dauzMarkers, mapLayersVisibility, "DAUZ", oms); - useLayerVisibility(map, smsfunkmodemMarkers, mapLayersVisibility, "SMSModem", oms); - useLayerVisibility(map, messstellenMarkers, mapLayersVisibility, "Messstellen", oms); - useLayerVisibility(map, ulafMarkers, mapLayersVisibility, "ULAF", oms); - + //-------------------------------------------- + //-------------------------------------------- useEffect(() => { if (map) { var x = 51.41321407879154; @@ -450,25 +409,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } }, [map, zoomTrigger]); //-------------------------------------------- - const allMarkers = [ - ...talasMarkers, - ...eciMarkers, - ...lteModemMarkers, - ...ciscoRouterMarkers, - ...wagoMarkers, - ...siemensMarkers, - ...otdrMarkers, - ...wdmMarkers, - ...gmaMarkers, - ...messstellenMarkers, - ...talasiclMarkers, - ...dauzMarkers, - ...smsfunkmodemMarkers, - ...sonstigeMarkers, - ...tkComponentsMarkers, - ...ulafMarkers, - ]; - + //-------------------------------------------- useEffect(() => { if (map) { // Sammle alle Marker in einer einzigen Liste @@ -515,6 +456,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { mapLayersVisibility, // Neu: Abhängigkeit für Sichtbarkeitsstatus ]); + //-------------------------------------------- //-------------------------------------------- useEffect(() => { const fetchData = async () => { @@ -550,7 +492,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { fetchData(); }, []); //-------------------------------------------- - + //----------------------------------------------------------------- //Tooltip an mouse position anzeigen für die Linien useEffect(() => { if (!map) return; @@ -619,15 +561,16 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }, [map, linePositions, lineColors, tooltipContents, newPoint, newCoords, tempMarker, polylineVisible]); //-------------------------------------------- - + //-------------------------------------------- useEffect(() => { if (map) { restoreMapSettings(map); } }, [map]); - + //-------------------------------------------- useEffect(() => { if (map) { + console.log("map in MapComponent: ", map); const handleMapMoveEnd = (event) => { const newCenter = map.getCenter(); const newZoom = map.getZoom(); @@ -649,22 +592,33 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } }, [map]); //-------------------------------------------- - + //-------------------------------------------- + // Bereich in DataSheet ->dropdownmenu useEffect(() => { + //console.log("🔍 GisStationsStaticDistrict Inhalt:", GisStationsStaticDistrict); + + // Sicherstellen, dass `Points` existiert und ein Array ist + const points = GisStationsStaticDistrict?.Points; + if (selectedArea && map) { - const station = GisStationsStaticDistrict.find((s) => s.Area_Name === selectedArea); + const station = points.find((s) => s.Area_Name === selectedArea); + if (station) { + console.log("📌 Gefundene Station:", station); map.flyTo([station.X, station.Y], 14); + } else { + console.warn("⚠️ Keine passende Station für die Area gefunden:", selectedArea); } } }, [selectedArea, map, GisStationsStaticDistrict]); + //------------------------------------- useEffect(() => { if (zoomTrigger && map) { map.flyTo([51.41321407879154, 7.739617925303934], 7); } }, [zoomTrigger, map]); - + //-------------------------------------------- useEffect(() => { if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded && isRightsLoaded) { addItemsToMapContextMenu(map, menuItemAdded, setMenuItemAdded, hasRights, setShowPopup, setPopupCoordinates); @@ -689,11 +643,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { fetchPriorityConfig(); }, []); //-------------------------------------------- - useEffect(() => { - if (mapRef.current && !map) { - initializeMap(mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled); - } - }, [mapRef, map, hasRights, setPolylineEventsDisabled]); + //-------------------------------------------- useEffect(() => { if (map) { @@ -704,6 +654,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } } }, [map, polylineEventsDisabled]); + //-------------------------------------------- useEffect(() => { if (map) { console.log("6- Karteninstanz (map) wurde jetzt erfolgreich initialisiert"); @@ -758,31 +709,47 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { // Setze ein Intervall, um die Daten alle 5 Sekunden zu aktualisieren /* const intervalId = setInterval(() => { - updateGmaData(); - }, 5000); - - // Cleanup-Funktion, um das Intervall zu entfernen, wenn die Komponente entladen wird - return () => clearInterval(intervalId); */ + updateGmaData(); + }, 5000); + + // Cleanup-Funktion, um das Intervall zu entfernen, wenn die Komponente entladen wird + return () => clearInterval(intervalId); */ }, [map, gmaMarkers, layers.MAP_LAYERS.GMA, oms, mapGisStationsMeasurementsUrl]); //--------------------------------- + //--------------hokks------------------------------------------- + useLoadUserRights(setUserRights, setIsRightsLoaded, setHasRights); + useGmaMarkersLayer( + map, + gmaMarkers, + GisStationsMeasurements, + layers.MAP_LAYERS.GMA, + oms, + mapLayersVisibility.GMA // Übergebe die Sichtbarkeitsbedingung als Parameter + ); + //-------------------------------------------- + //useCreateAndSetDevices(1, talasMarkers, GisSystemStatic, priorityConfig); + useLayerVisibility(map, talasMarkers, mapLayersVisibility, "TALAS", oms); + useLayerVisibility(map, eciMarkers, mapLayersVisibility, "ECI", oms); + useLayerVisibility(map, lteModemMarkers, mapLayersVisibility, "LTEModem", oms); + useLayerVisibility(map, ciscoRouterMarkers, mapLayersVisibility, "CiscoRouter", oms); + useLayerVisibility(map, lteModemMarkers, mapLayersVisibility, "LTEModem", oms); + useLayerVisibility(map, wagoMarkers, mapLayersVisibility, "WAGO", oms); + useLayerVisibility(map, siemensMarkers, mapLayersVisibility, "Siemens", oms); + useLayerVisibility(map, otdrMarkers, mapLayersVisibility, "OTDR", oms); + useLayerVisibility(map, wdmMarkers, mapLayersVisibility, "WDM", oms); + useLayerVisibility(map, gmaMarkers, mapLayersVisibility, "GMA", oms); + useLayerVisibility(map, sonstigeMarkers, mapLayersVisibility, "Sonstige", oms); + useLayerVisibility(map, tkComponentsMarkers, mapLayersVisibility, "TKKomponenten", oms); + useLayerVisibility(map, talasiclMarkers, mapLayersVisibility, "TALASICL", oms); + useLayerVisibility(map, dauzMarkers, mapLayersVisibility, "DAUZ", oms); + useLayerVisibility(map, smsfunkmodemMarkers, mapLayersVisibility, "SMSModem", oms); + useLayerVisibility(map, messstellenMarkers, mapLayersVisibility, "Messstellen", oms); + useLayerVisibility(map, ulafMarkers, mapLayersVisibility, "ULAF", oms); + //-------------------------------------------- + + useInitializeMap(map, mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled); - const gmaLayerRef = useRef(null); - const talasLayerRef = useRef(null); - const eciMarkersLayerRef = useRef(null); - const lteModemMarkersLayerRef = useRef(null); - const ciscoRouterMarkersLayerRef = useRef(null); - const wagoMarkersLayerRef = useRef(null); - const siemensMarkersLayerRef = useRef(null); - const otdrMarkersLayerRef = useRef(null); - const wdmMarkersLayerRef = useRef(null); - const messstellenMarkersLayerRef = useRef(null); - const talasiclMarkersLayerRef = useRef(null); - const dauzMarkersLayerRef = useRef(null); - const smsfunkmodemMarkersLayerRef = useRef(null); - const ulafMarkersLayerRef = useRef(null); - const sonstigeMarkersLayerRef = useRef(null); - const tkComponentsMarkersRef = useRef(null); useEffect(() => { if (!gisSystemStaticLoaded || !map) return; // Sicherstellen, dass die Karte und Daten geladen sind @@ -846,7 +813,19 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { // Setze ein Intervall für regelmäßige Updates const intervalId = setInterval(() => { updateAllMarkers(); - }, 20000); // 20 Sekunden + + if (map) { + // console.log("🔥 Automatischer Klick-Event ausgelöst, um Spiderfy zu aktualisieren."); + map.fire("click"); + } + if (isPolylineContextMenuOpen) { + dispatch(closePolylineContextMenu()); // Schließe das Kontextmenü, bevor das nächste Update passiert + } + if (map) { + // console.log("🔥 nochmal klick."); + map.fire("click"); + } + }, 20000); // Aufräumen bei Komponentenentladung return () => { @@ -935,13 +914,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { //-------------------------------------------- const fetchGisStationsStaticDistrict = async (idMap, idUser, dispatch) => { try { - let stationsStaticUrl = useMock ? "/mockData/gisStationsStaticDistrictMock.json" : mapGisStationsStaticDistrictUrl; - - let stationsStatusUrl = useMock ? "/mockData/gisStationsStatusDistrictMock.json" : mapGisStationsStatusDistrictUrl; - - let stationsMeasurementsUrl = useMock ? "/mockData/gisStationsMeasurementsMock.json" : mapGisStationsMeasurementsUrl; - - let systemStaticUrl = useMock ? "/mockData/gisSystemStaticMock.json" : mapGisSystemStaticUrl; // API-Endpunkt mit Query-Parametern aufrufen const response = await fetch(`/api/gisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`); @@ -954,7 +926,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { // Ergebnis im Dispatch speichern oder State aktualisieren dispatch({ type: "SET_GIS_STATIONS", payload: data }); - console.log("Daten erfolgreich geladen:", data); + //console.log("Daten erfolgreich geladen:", data); return data; // Optional: Rückgabe der Daten } catch (error) { console.error("Fehler beim Laden der GIS-Daten:", error); @@ -997,12 +969,20 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } }, [map, menuItemAdded, hasRights]); */ //-------------------------------------------- - useEffect(() => { if (map && !menuItemAdded) { - addItemsToMapContextMenu(map, menuItemAdded, setMenuItemAdded, openPopupWithCoordinates); + addItemsToMapContextMenu( + map, + menuItemAdded, + setMenuItemAdded, + setShowCoordinatesModal, + setShowPoiModal, + setPopupCoordinates, + openPopupWithCoordinates // Diese Funktion wird jetzt übergeben! + ); } }, [map, menuItemAdded]); + //-------------------------------------------- // Beim ersten Client-Render den Wert aus localStorage laden useEffect(() => { @@ -1011,9 +991,76 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }, [dispatch]); //---------------------------------------------- + // speichere location devices in redux store + useInitLocationDevices(); + useInitGisStationsStaticDistrict(); + useInitGisStationsStatusDistrict(); + useInitGisStationsMeasurements(); + useInitGisSystemStatic(); + useInitGisStationsStatic(); + + //-------------------------------------- + useEffect(() => { + if (isPolylineContextMenuOpen && countdownActive) { + //console.log("🔄 Starte Redux-Countdown für Kontextmenü!"); + + const interval = setInterval(() => { + dispatch(updateCountdown()); + + // console.log(`⏳ Redux Countdown: ${countdown} Sekunden`); + + if (countdown <= 2) { + console.log("🚀 Kontextmenü wird wegen Countdown < 2 geschlossen."); + dispatch(closePolylineContextMenu()); + + if (window.map?.contextmenu) { + window.map.contextmenu.hide(); + } + + clearInterval(interval); + } + }, 1000); + + return () => { + clearInterval(interval); + }; + } + }, [isPolylineContextMenuOpen, countdown, countdownActive, dispatch, window.map]); + //---------------------------------- + useEffect(() => { + if (map) { + window.map = map; + console.log("✅ window.map wurde gesetzt:", window.map); + } + }, [map]); + + //--------------------------------------- + useEffect(() => { + window.onerror = function (message, source, lineno, colno, error) { + if (message.includes("Cannot read properties of null (reading 'contextmenu')")) { + console.warn("⚠️ Fehler mit `contextmenu` erkannt - Neuladen der Seite."); + setTimeout(() => { + window.location.reload(); + }, 0); // **Seite nach Sekunde neu laden** + return true; // **Fehler unterdrücken, damit React ihn nicht anzeigt** + } + }; + + return () => { + window.onerror = null; // **Fehlerbehandlung entfernen, wenn Komponente unmounted wird** + }; + }, []); + + //--------------------------------------------- return ( <> + {useSelector((state) => state.addPoiOnPolyline.isOpen) && } + {/* Zeigt das Koordinaten-Modal, wenn `showCoordinatesModal` true ist */} + {showCoordinatesModal && setShowCoordinatesModal(false)} />} + + {/* Zeigt das POI-Modal, wenn `showPoiModal` true ist */} + {showPoiModal && setShowPoiModal(false)} />}
{showPoiUpdateModal && setShowPoiUpdateModal(false)} poiData={currentPoiData} onSubmit={() => {}} latlng={popupCoordinates} />}
diff --git a/components/mainComponent/hooks/useInitializeMap.js b/components/mainComponent/hooks/useInitializeMap.js new file mode 100644 index 000000000..21114e3d2 --- /dev/null +++ b/components/mainComponent/hooks/useInitializeMap.js @@ -0,0 +1,13 @@ +// /components/mainComponent/hooks/useInitializeMap.js +import { useEffect } from "react"; +import { initializeMap } from "../../../utils/initializeMap"; + +const useInitializeMap = (map, mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled) => { + useEffect(() => { + if (mapRef.current && !map) { + initializeMap(mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled); + } + }, [mapRef, map, hasRights, setPolylineEventsDisabled]); +}; + +export default useInitializeMap; diff --git a/components/mainComponent/hooks/useLoadUserRights.js b/components/mainComponent/hooks/useLoadUserRights.js new file mode 100644 index 000000000..fa3688085 --- /dev/null +++ b/components/mainComponent/hooks/useLoadUserRights.js @@ -0,0 +1,20 @@ +// /components/mainComponent/hooks/useLoadUserRights.js +import { useEffect } from "react"; +import { fetchUserRights } from "../../../services/api/fetchUserRights"; + +const useLoadUserRights = (setUserRights, setIsRightsLoaded, setHasRights) => { + useEffect(() => { + const fetchAndSetUserRights = async () => { + const rights = await fetchUserRights(); + setUserRights(rights); + setIsRightsLoaded(true); + + // Sicherstellen, dass `rights` ein Array ist, bevor `.includes()` aufgerufen wird + setHasRights(localStorage.getItem("editMode") && Array.isArray(rights) && rights.includes(56)); + }; + + fetchAndSetUserRights(); + }, []); +}; + +export default useLoadUserRights; diff --git a/components/mainComponent/hooks/webServices/useAutoRefreshLocationDevices.js b/components/mainComponent/hooks/webServices/useAutoRefreshLocationDevices.js new file mode 100644 index 000000000..5d0e146a0 --- /dev/null +++ b/components/mainComponent/hooks/webServices/useAutoRefreshLocationDevices.js @@ -0,0 +1,38 @@ +// components/mainComponent/hooks/useAutoRefreshLocationDevices.js +/* + Das ist erstmal nur so da, falls es gebraucht wird +Diese datei ist zum automatischen aktualisieren der LocationDevices gedacht +jeder 20 Sekunden wird die Funktion fetchLocationDevicesFromDB() aufgerufen +Daten werden dann in der Redux State gespeichert +*/ + +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { fetchLocationDevicesFromDB } from "../../../../redux/slices/db/locationDevicesFromDBSlice"; + +export const useAutoRefreshLocationDevices = (interval = 20000) => { + // alle 20 Sekunden + const dispatch = useDispatch(); + + useEffect(() => { + const fetchData = () => { + dispatch(fetchLocationDevicesFromDB()); + }; + + fetchData(); // Sofort beim Start holen + + const intervalId = setInterval(fetchData, interval); + + return () => clearInterval(intervalId); // Cleanup beim Unmount + }, [dispatch, interval]); +}; + +/* +In MapComponent.js einbinden +import { useAutoRefreshLocationDevices } from "./hooks/useAutoRefreshLocationDevices"; + +const MapComponent = () => { + useAutoRefreshLocationDevices(); + + +*/ diff --git a/components/mainComponent/hooks/webServices/useInitGisStationsMeasurements.js b/components/mainComponent/hooks/webServices/useInitGisStationsMeasurements.js new file mode 100644 index 000000000..2db27df07 --- /dev/null +++ b/components/mainComponent/hooks/webServices/useInitGisStationsMeasurements.js @@ -0,0 +1,12 @@ +// /components/mainComponent/hooks/useInitGisStationsMeasurements.js +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { fetchGisStationsMeasurementsFromWebService } from "../../../../redux/slices/webService/gisStationsMeasurementsSlice"; + +export const useInitGisStationsMeasurements = () => { + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(fetchGisStationsMeasurementsFromWebService()); + }, [dispatch]); +}; diff --git a/components/mainComponent/hooks/webServices/useInitGisStationsStatic.js b/components/mainComponent/hooks/webServices/useInitGisStationsStatic.js new file mode 100644 index 000000000..7c4596e45 --- /dev/null +++ b/components/mainComponent/hooks/webServices/useInitGisStationsStatic.js @@ -0,0 +1,21 @@ +// /components/mainComponent/hooks/useInitGisStationsStatic.js +//Bereiche/Area-Name Dropdownmenu für Datasheet wird hier initialisiert und in der Komponente verwendet +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { fetchGisStationsStatic, selectGisStationsStatic } from "../../../../redux/slices/webService/gisStationsStaticSlice"; + +export const useInitGisStationsStatic = () => { + const dispatch = useDispatch(); + const gisStationsStatic = useSelector(selectGisStationsStatic); + + useEffect(() => { + // console.log("🔍 useInitGisStationsStatic - Aktueller Wert:", gisStationsStatic); + + if (!gisStationsStatic || gisStationsStatic === null) { + //console.log("🚀 Starte fetchGisStationsStatic..."); + dispatch(fetchGisStationsStatic()); + } + }, [gisStationsStatic, dispatch]); + + return gisStationsStatic; +}; diff --git a/components/mainComponent/hooks/webServices/useInitGisStationsStaticDistrict.js b/components/mainComponent/hooks/webServices/useInitGisStationsStaticDistrict.js new file mode 100644 index 000000000..74d70c736 --- /dev/null +++ b/components/mainComponent/hooks/webServices/useInitGisStationsStaticDistrict.js @@ -0,0 +1,12 @@ +// /components/mainComponent/hooks/useInitGisStationsStaticDistrict.js +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { fetchGisStationsStaticDistrictFromWebService } from "../../../../redux/slices/webService/gisStationsStaticDistrictSlice"; + +export const useInitGisStationsStaticDistrict = () => { + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(fetchGisStationsStaticDistrictFromWebService()); + }, [dispatch]); +}; diff --git a/components/mainComponent/hooks/webServices/useInitGisStationsStatusDistrict.js b/components/mainComponent/hooks/webServices/useInitGisStationsStatusDistrict.js new file mode 100644 index 000000000..147b1fa31 --- /dev/null +++ b/components/mainComponent/hooks/webServices/useInitGisStationsStatusDistrict.js @@ -0,0 +1,12 @@ +// /componets/mainComponent/hooks/useInitGisStationsStatusDistrict.js +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { fetchGisStationsStatusDistrictFromWebService } from "../../../../redux/slices/webService/gisStationsStatusDistrictSlice"; + +export const useInitGisStationsStatusDistrict = () => { + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(fetchGisStationsStatusDistrictFromWebService()); + }, [dispatch]); +}; diff --git a/components/mainComponent/hooks/webServices/useInitGisSystemStatic.js b/components/mainComponent/hooks/webServices/useInitGisSystemStatic.js new file mode 100644 index 000000000..b7a58a3e4 --- /dev/null +++ b/components/mainComponent/hooks/webServices/useInitGisSystemStatic.js @@ -0,0 +1,12 @@ +// /components/mainComponent/hooks/useInitGisStationsMeasurements.js +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { fetchGisSystemStaticFromWebService } from "../../../../redux/slices/webService/gisSystemStaticSlice"; + +export const useInitGisSystemStatic = () => { + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(fetchGisSystemStaticFromWebService()); + }, [dispatch]); +}; diff --git a/components/mainComponent/hooks/webServices/useInitLocationDevices.js b/components/mainComponent/hooks/webServices/useInitLocationDevices.js new file mode 100644 index 000000000..49708264f --- /dev/null +++ b/components/mainComponent/hooks/webServices/useInitLocationDevices.js @@ -0,0 +1,12 @@ +// /components/mainComponent/hooks/useInitLocationDevices.js +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { fetchLocationDevicesFromDB } from "../../../../redux/slices/db/locationDevicesFromDBSlice"; + +export const useInitLocationDevices = () => { + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(fetchLocationDevicesFromDB()); + }, [dispatch]); +}; diff --git a/components/pois/PoiUpdateModal.js b/components/pois/PoiUpdateModal.js index 87979cdda..f0ae47c89 100644 --- a/components/pois/PoiUpdateModal.js +++ b/components/pois/PoiUpdateModal.js @@ -5,9 +5,14 @@ import { useRecoilState } from "recoil"; import { selectedPoiState } from "../../redux/slices/selectedPoiSlice"; import { currentPoiState } from "../../redux/slices/currentPoiSlice"; import { mapLayersState } from "../../redux/slices/mapLayersSlice"; +import { selectCurrentPoi } from "../../redux/slices/currentPoiSlice"; +import { fetchLocationDevicesFromDB } from "../../redux/slices/db/locationDevicesFromDBSlice"; +import { useSelector, useDispatch } from "react-redux"; const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => { - const currentPoi = useRecoilState(currentPoiState); + const dispatch = useDispatch(); + + const currentPoi = useSelector(selectCurrentPoi); const selectedPoi = useRecoilState(selectedPoiState); const [mapLayersVisibility] = useRecoilState(mapLayersState); @@ -41,6 +46,12 @@ const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => { Basisgerät: 200, }; + const devices = useSelector((state) => state.locationDevicesFromDB.devices); + + useEffect(() => { + dispatch(fetchLocationDevicesFromDB()); + }, [dispatch]); + useEffect(() => { if (poiData) { setPoiId(poiData.idPoi); @@ -84,23 +95,10 @@ const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => { // Fetch location devices and pre-select the current device useEffect(() => { - const fetchLocationDevices = async () => { - try { - const response = await fetch("/api/talas5/location_device"); - const data = await response.json(); - setLocationDeviceData(data); - filterDevices(data); - - if (poiData && poiData.idLD) { - const selectedDevice = data.find((device) => device.idLD === poiData.idLD); - setDeviceName(selectedDevice ? { value: selectedDevice.name, label: selectedDevice.name } : null); - } - } catch (error) { - console.error("Fehler beim Abrufen der Standort- und Gerätedaten:", error); - } - }; - fetchLocationDevices(); - }, [poiData]); + if (devices.length > 0) { + filterDevices(devices); // <-- Filter direkt die Redux-Devices + } + }, [devices]); // Funktion zum Filtern der Geräte basierend auf den aktiven Systemen (Layern) const filterDevices = (devices) => { @@ -168,15 +166,25 @@ const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => { }; // Erstelle Optionen für react-select - const poiTypeOptions = poiTypData.map((poiTyp) => ({ - value: poiTyp.idPoiTyp, - label: poiTyp.name, - })); + const poiTypeOptions = Array.isArray(poiTypData) + ? poiTypData.map((poiTyp) => ({ + value: poiTyp.idPoiTyp, + label: poiTyp.name, + })) + : []; // Falls kein Array, dann leeres Array zurückgeben - const deviceOptions = filteredDevices.map((device) => ({ - value: device.name, - label: device.name, + const deviceOptions = devices.map((device) => ({ + value: device.idLD, // idLD ist die eindeutige ID des Geräts + label: device.name, // name ist der Anzeigename im Dropdown })); + useEffect(() => { + if (poiData && devices.length > 0) { + const selectedDevice = devices.find((device) => device.idLD === poiData.idLD); + if (selectedDevice) { + setDeviceName({ value: selectedDevice.idLD, label: selectedDevice.name }); + } + } + }, [poiData, devices]); // Custom styles for react-select const customStyles = { diff --git a/components/pois/PoiUpdateModalWrapper.js b/components/pois/PoiUpdateModalWrapper.js index 4916c9cd6..7a2273b6e 100644 --- a/components/pois/PoiUpdateModalWrapper.js +++ b/components/pois/PoiUpdateModalWrapper.js @@ -1,26 +1,17 @@ // components/pois/PoiUpdateModalWrapper.js -import React, { useState } from "react"; -import PoiUpdateModal from "./PoiUpdateModal"; -import { useRecoilValue, useSetRecoilState } from "recoil"; -import { currentPoiState, selectedPoiState } from "../../redux/slices/currentPoiSlice"; -import { poiReadFromDbTriggerAtom } from "../../redux/slices/poiReadFromDbTriggerSlice"; +import { useDispatch } from "react-redux"; +import { setCurrentPoi } from "../../redux/slices/currentPoiSlice"; -const PoiUpdateModalWrapper = ({ show, onClose, latlng }) => { - const setSelectedPoi = useSetRecoilState(selectedPoiState); - const setCurrentPoi = useSetRecoilState(currentPoiState); - const currentPoi = useRecoilValue(currentPoiState); - const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom); +const PoiUpdateModalWrapper = ({ show, onClose, latlng, poiData }) => { + const dispatch = useDispatch(); - return ( - show && ( - {}} // Add your submit logic here - latlng={latlng} - /> - ) - ); + useEffect(() => { + if (show && poiData) { + dispatch(setCurrentPoi(poiData)); + } + }, [show, poiData, dispatch]); + + const currentPoi = useSelector(selectCurrentPoi); // Direkt aus Redux holen + + return show && {}} latlng={latlng} />; }; - -export default PoiUpdateModalWrapper; diff --git a/components/useMapContextMenu.js b/components/useMapContextMenu.js index f39996a5a..8f60c18fd 100644 --- a/components/useMapContextMenu.js +++ b/components/useMapContextMenu.js @@ -3,7 +3,20 @@ import { toast } from "react-toastify"; import { zoomIn, zoomOut, centerHere } from "../utils/zoomAndCenterUtils"; // components/useMapContextMenu.js -const addItemsToMapContextMenu = (map, menuItemAdded, setMenuItemAdded, openPopupWithCoordinates) => { +const addItemsToMapContextMenu = ( + map, + menuItemAdded, + setMenuItemAdded, + setShowCoordinatesModal, + setShowPoiModal, + setPopupCoordinates, + openPopupWithCoordinates // Hier wird die Funktion als Parameter hinzugefügt +) => { + const openPoiModal = (e) => { + setShowCoordinatesModal(false); // ✅ Jetzt verfügbar, weil als Parameter übergeben + setPopupCoordinates(e.latlng); + setShowPoiModal(true); + }; if (!menuItemAdded && map && map.contextmenu) { map.contextmenu.addItem({ text: "Koordinaten anzeigen", @@ -17,7 +30,15 @@ const addItemsToMapContextMenu = (map, menuItemAdded, setMenuItemAdded, openPopu text: "Reinzoomen", icon: "img/zoom_in.png", callback: (e) => { - map.setZoom(map.getZoom() + 1); + const currentZoom = map.getZoom(); + const newZoom = Math.min(15, currentZoom + 3); // Stellt sicher, dass max. 15 erreicht wird + const zoomDifference = Math.abs(newZoom - currentZoom); // Anzahl der Zoom-Stufen + const duration = zoomDifference * 0.5; // Pro Stufe 0.5 Sekunden + + map.flyTo(map.getCenter(), newZoom, { + animate: true, + duration: duration, + }); }, }); @@ -25,7 +46,15 @@ const addItemsToMapContextMenu = (map, menuItemAdded, setMenuItemAdded, openPopu text: "Rauszoomen", icon: "img/zoom_out.png", callback: () => { - map.setZoom(map.getZoom() - 1); + const currentZoom = map.getZoom(); + const newZoom = Math.max(6, currentZoom - 3); // Stellt sicher, dass min. 6 erreicht wird + const zoomDifference = Math.abs(newZoom - currentZoom); // Anzahl der Zoom-Stufen + const duration = zoomDifference * 0.5; // Pro Stufe 0.5 Sekunden + + map.flyTo(map.getCenter(), newZoom, { + animate: true, + duration: duration, + }); }, }); @@ -39,6 +68,19 @@ const addItemsToMapContextMenu = (map, menuItemAdded, setMenuItemAdded, openPopu setMenuItemAdded(true); } + if (!menuItemAdded && map && map.contextmenu) { + const editMode = localStorage.getItem("editMode") === "true"; + if (editMode) { + console.log("editMode localStorage:", localStorage.getItem("editMode")); + console.log("editMode:", editMode); + + map.contextmenu.addItem({ + text: "POI hinzufügen", + icon: "/img/add_station.png", + callback: openPoiModal, // Jetzt mit Zugriff auf `setShowPoiModal` + }); + } + } }; export default addItemsToMapContextMenu; diff --git a/config/appVersion.js b/config/appVersion.js index c185c7a8c..874bfaaf7 100644 --- a/config/appVersion.js +++ b/config/appVersion.js @@ -1,2 +1,2 @@ // /config/appVersion -export const APP_VERSION = "1.1.18"; +export const APP_VERSION = "1.1.49"; diff --git a/hooks/useMapComponentState.js b/hooks/useMapComponentState.js index 043239c51..3baf0df0b 100644 --- a/hooks/useMapComponentState.js +++ b/hooks/useMapComponentState.js @@ -1,12 +1,13 @@ // hooks/useMapComponentState.js +// POI -> Kontextmenü -> POI bearbeiten -> Dropdown Geräteauswahl import { useState, useEffect } from "react"; -import usePoiTypData from "./usePoiTypData"; import { useRecoilValue } from "recoil"; import { poiLayerVisibleState } from "../redux/slices/poiLayerVisibleSlice"; import { isMockMode } from "../config/config"; export const useMapComponentState = () => { - const { poiTypData, isPoiTypLoaded } = usePoiTypData("/api/talas_v5_DB/poiTyp/readPoiTyp"); + const [poiTypData, setPoiTypData] = useState([]); + const [isPoiTypLoaded, setIsPoiTypLoaded] = useState(false); const [deviceName, setDeviceName] = useState(""); const [locationDeviceData, setLocationDeviceData] = useState([]); const [priorityConfig, setPriorityConfig] = useState([]); @@ -14,29 +15,72 @@ export const useMapComponentState = () => { const poiLayerVisible = useRecoilValue(poiLayerVisibleState); useEffect(() => { - const fetchDeviceData = async () => { + const fetchPoiTypData = async () => { if (isMockMode()) { - console.log("⚠️ Mock-API: Gerätedaten geladen"); + console.log("⚠️ Mock-API: POI Typen geladen (Mock)"); - const mockData = [{ name: "Mock-Gerät 1" }, { name: "Mock-Gerät 2" }]; - setLocationDeviceData(mockData); - setDeviceName(mockData[0].name); + const mockData = [ + { idPoiTyp: 1, name: "Mock Zähleranschlusskasten", icon: 4, onlySystemTyp: 0 }, + { idPoiTyp: 2, name: "Mock Geräteschrank", icon: 2, onlySystemTyp: 0 }, + { idPoiTyp: 4, name: "Mock Parkplatz", icon: 3, onlySystemTyp: 0 }, + { idPoiTyp: 6, name: "Mock Zufahrt", icon: 4, onlySystemTyp: 0 }, + { idPoiTyp: 20, name: "Mock Zählgerät", icon: 5, onlySystemTyp: 110 }, + { idPoiTyp: 21, name: "Mock Messschleife", icon: 6, onlySystemTyp: 110 }, + { idPoiTyp: 25, name: "Mock Sonstige", icon: 0, onlySystemTyp: 0 }, + { idPoiTyp: 33, name: "Mock Autobahnauffahrt", icon: 4, onlySystemTyp: null }, + ]; + + setPoiTypData(mockData); + setIsPoiTypLoaded(true); return; } try { - const response = await fetch("/api/talas5/location_device"); + const response = await fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"); const data = await response.json(); - setLocationDeviceData(data); + setPoiTypData(data); + setIsPoiTypLoaded(true); + } catch (error) { + console.error("❌ Fehler beim Abrufen der POI-Typen:", error); + setPoiTypData([]); + setIsPoiTypLoaded(true); + } + }; - if (data.length > 0) { - setDeviceName(data[0].name); + const fetchDeviceData = async () => { + try { + const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL; + + // URL-Parameter aus der aktuellen Browser-URL holen + const params = new URLSearchParams(window.location.search); + const idMap = params.get("idMap") || "12"; // Fallback auf "12" falls nicht gesetzt + + const url = `${apiBaseUrl}/GisStationsStatic?idMap=${idMap}`; + + //console.log("📡 API Request URL:", url); + + const response = await fetch(url); + + //console.log("📡 API Response Status:", response.status); + // console.log("📡 API Response Headers:", response.headers.get("content-type")); + + const text = await response.text(); + //console.log("📡 API Response Text:", text); + + // JSON manuell parsen, falls die API keinen JSON-Header sendet + const data = JSON.parse(text); + + setLocationDeviceData(data.Points || []); + + if (data.Points && data.Points.length > 0) { + setDeviceName(data.Points[0].LD_Name); } } catch (error) { console.error("❌ Fehler beim Abrufen der Gerätedaten:", error); } }; + fetchPoiTypData(); fetchDeviceData(); }, []); diff --git a/hooks/usePolylineTooltipLayer.js b/hooks/usePolylineTooltipLayer.js index a0913a086..b30e6ca07 100644 --- a/hooks/usePolylineTooltipLayer.js +++ b/hooks/usePolylineTooltipLayer.js @@ -1,24 +1,10 @@ // hooks/usePolylineTooltipLayer.js import { useEffect } from "react"; import L from "leaflet"; -import { setupPolylines } from "../utils/setupPolylines"; +import { setupPolylines } from "../utils/polylines/setupPolylines"; - //Tooltip an mouse position anzeigen für die Linien -export const usePolylineTooltipLayer = ( - map, - markers, - polylines, - setMarkers, - setPolylines, - linePositions, - lineColors, - tooltipContents, - setNewCoords, - tempMarker, - polylineVisible, - newPoint, - newCoords -) => { +//Tooltip an mouse position anzeigen für die Linien +export const usePolylineTooltipLayer = (map, markers, polylines, setMarkers, setPolylines, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, polylineVisible, newPoint, newCoords) => { useEffect(() => { if (!map) return; @@ -81,4 +67,4 @@ export const usePolylineTooltipLayer = ( setMarkers(newMarkers); setPolylines(newPolylines); }, [map, linePositions, lineColors, tooltipContents, newPoint, newCoords, tempMarker, polylineVisible]); -}; \ No newline at end of file +}; diff --git a/lib/OverlappingMarkerSpiderfier.js b/lib/OverlappingMarkerSpiderfier.js index 0e1747459..5093ae240 100644 --- a/lib/OverlappingMarkerSpiderfier.js +++ b/lib/OverlappingMarkerSpiderfier.js @@ -67,38 +67,57 @@ export class OverlappingMarkerSpiderfier { return distance < this.nearbyDistance && marker !== m; }); } - + //--------------------------------------------------------------------------------------------- spiderfy(markers) { const centerPt = this.map.latLngToLayerPoint(markers[0].getLatLng()); + markers.forEach((marker, i) => { const angle = this.circleStartAngle + (i * 2 * Math.PI) / markers.length; const legLength = this.circleFootSeparation * (2 + i / markers.length); - const newPt = L.point( - centerPt.x + legLength * Math.cos(angle), - centerPt.y + legLength * Math.sin(angle) - ); + const newPt = L.point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle)); const newLatLng = this.map.layerPointToLatLng(newPt); if (!marker._oms) { - marker._oms = {}; // Stellt sicher, dass _oms ein Objekt ist + marker._oms = {}; } - // Speichert die aktuelle Position, bevor sie verändert wird marker._oms.usualPosition = marker.getLatLng(); - marker._oms.spidered = true; // Markiert, dass der Marker gespiderfied ist + marker._oms.spidered = true; + + // Zeichne eine Linie zwischen ursprünglicher und neuer Position + const leg = L.polyline([marker._oms.usualPosition, newLatLng], { + color: this.legColors.usual, + weight: this.legWeight, + }).addTo(this.map); + + marker._oms.leg = leg; // Speichert die Linie im Marker-Objekt marker.setLatLng(newLatLng); marker.setZIndexOffset(1000); }); } + + //--------------------------------------------------------------------------------------------- unspiderfy() { this.markers.forEach((marker) => { if (marker._oms && marker._oms.spidered) { - // Setzt den Marker nur dann zurück, wenn er gespiderfied war + // Falls eine Linie existiert, entferne sie aus der Karte + if (marker._oms.leg) { + this.map.removeLayer(marker._oms.leg); + marker._oms.leg = null; + } + marker.setLatLng(marker._oms.usualPosition); marker.setZIndexOffset(0); - marker._oms.spidered = false; // Setzt zurück, dass der Marker nicht mehr gespiderfied ist + marker._oms.spidered = false; } }); + // 🔥 Künstliches Click-Event auslösen, um die UI zu aktualisieren + setTimeout(() => { + this.map.fire("click"); + console.log("Click-Event ausgelöst in OverlappingMarkerspiderfier.js in unspiderfy "); + }, 10); // Kurze Verzögerung, um sicherzustellen, dass die UI neu gerendert wird } + + //--------------------------------------------------------------------------------------------- } diff --git a/pages/index.js b/pages/index.js index 35513d35d..c47f9627f 100644 --- a/pages/index.js +++ b/pages/index.js @@ -5,7 +5,7 @@ import { useRecoilState, useRecoilValue } from "recoil"; import { readPoiMarkersStore } from "../redux/slices/readPoiMarkersStoreSlice.js"; import { poiReadFromDbTriggerAtom } from "../redux/slices/poiReadFromDbTriggerSlice"; -const MapComponentWithNoSSR = dynamic(() => import("../components/MapComponent"), { ssr: false }); +const MapComponentWithNoSSR = dynamic(() => import("../components/mainComponent/MapComponent"), { ssr: false }); const TestScriptWithNoSSR = dynamic(() => import("../components/TestScript"), { ssr: false }); export default function Home() { diff --git a/public/mockData/GisLinesStatusMock.json b/public/mockData/GisLinesStatusMock.json deleted file mode 100644 index f9f8df92b..000000000 --- a/public/mockData/GisLinesStatusMock.json +++ /dev/null @@ -1,1447 +0,0 @@ -{ - "Name": "Liste aller Statis der Linien", - "Zeitstempel": "2025-03-07T08:07:44.0452566+01:00", - "IdMap": "12", - "Statis": [ - { - "IdLD": 50922, - "Modul": 8, - "DpName": "KUE08_Messwertalarm", - "ModulName": "Test8", - "ModulTyp": "Kü705-FO", - "Message": "KÜG 08: Überspannung gehend", - "Level": 3, - "PrioColor": "#FFFF00", - "PrioName": "minor", - "Value": "False" - }, - { - "IdLD": 50922, - "Modul": 1, - "DpName": "KUE01_Aderbruch", - "ModulName": "Test1", - "ModulTyp": "Kü705-FO", - "Message": "KÜG 01: Aderbruch kommend", - "Level": 1, - "PrioColor": "#FF0000", - "PrioName": "critical", - "Value": "?" - }, - { - "IdLD": 50922, - "Modul": 2, - "DpName": "KUE02_Aderbruch", - "ModulName": "Kue 2", - "ModulTyp": "Kü705-FO", - "Message": "KÜG 02: Aderbruch kommend", - "Level": 1, - "PrioColor": "#FF0000", - "PrioName": "critical", - "Value": "?" - }, - { - "IdLD": 50922, - "Modul": 3, - "DpName": "KUE03_Aderbruch", - "ModulName": "Kue 3", - "ModulTyp": "Kü705-FO", - "Message": "KÜG 03: Aderbruch kommend", - "Level": 1, - "PrioColor": "#FF0000", - "PrioName": "critical", - "Value": "?" - }, - { - "IdLD": 50000, - "Modul": 4, - "DpName": "KUE04_Messwert", - "ModulName": "?", - "ModulTyp": "nicht vorhanden", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "1.36 MOhm" - }, - { - "IdLD": 50000, - "Modul": 5, - "DpName": "KUE05_Messwert", - "ModulName": "?", - "ModulTyp": "nicht vorhanden", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10 MOhm" - }, - { - "IdLD": 50000, - "Modul": 6, - "DpName": "KUE06_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50000, - "Modul": 7, - "DpName": "KUE07_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10 MOhm" - }, - { - "IdLD": 50000, - "Modul": 8, - "DpName": "KUE08_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "516.72 MOhm" - }, - { - "IdLD": 50000, - "Modul": 13, - "DpName": "KUE13_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "8 MOhm" - }, - { - "IdLD": 50000, - "Modul": 1, - "DpName": "KUE01_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 2, - "DpName": "KUE02_Schleifenwert", - "ModulName": "L3", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 3, - "DpName": "KUE03_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 4, - "DpName": "KUE04_Schleifenwert", - "ModulName": "?", - "ModulTyp": "nicht vorhanden", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50000, - "Modul": 5, - "DpName": "KUE05_Schleifenwert", - "ModulName": "?", - "ModulTyp": "nicht vorhanden", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "2.78 kOhm" - }, - { - "IdLD": 50000, - "Modul": 6, - "DpName": "KUE06_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50000, - "Modul": 7, - "DpName": "KUE07_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "2.76 kOhm" - }, - { - "IdLD": 50000, - "Modul": 8, - "DpName": "KUE08_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50000, - "Modul": 9, - "DpName": "KUE09_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 10, - "DpName": "KUE10_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 11, - "DpName": "KUE11_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 12, - "DpName": "KUE12_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 13, - "DpName": "KUE13_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50000, - "Modul": 14, - "DpName": "KUE14_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 15, - "DpName": "KUE15_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 16, - "DpName": "KUE16_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 17, - "DpName": "KUE17_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 18, - "DpName": "KUE18_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 19, - "DpName": "KUE19_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 20, - "DpName": "KUE20_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 21, - "DpName": "KUE21_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 22, - "DpName": "KUE22_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 23, - "DpName": "KUE23_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50000, - "Modul": 24, - "DpName": "KUE24_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 1, - "DpName": "KUE01_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 2, - "DpName": "KUE02_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 3, - "DpName": "KUE03_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 4, - "DpName": "KUE04_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 5, - "DpName": "KUE05_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 6, - "DpName": "KUE06_Schleifenwert", - "ModulName": "?", - "ModulTyp": "KÜSS V2", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 7, - "DpName": "KUE07_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 8, - "DpName": "KUE08_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 9, - "DpName": "KUE09_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 10, - "DpName": "KUE10_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 11, - "DpName": "KUE11_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 12, - "DpName": "KUE12_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 13, - "DpName": "KUE13_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 14, - "DpName": "KUE14_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 15, - "DpName": "KUE15_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 16, - "DpName": "KUE16_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 17, - "DpName": "KUE17_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 18, - "DpName": "KUE18_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 19, - "DpName": "KUE19_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 20, - "DpName": "KUE20_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 21, - "DpName": "KUE21_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 22, - "DpName": "KUE22_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 23, - "DpName": "KUE23_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50001, - "Modul": 24, - "DpName": "KUE24_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50011, - "Modul": 2, - "DpName": "KUE02_Messwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "200 MOhm" - }, - { - "IdLD": 50011, - "Modul": 3, - "DpName": "KUE03_Messwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "200 MOhm" - }, - { - "IdLD": 50011, - "Modul": 4, - "DpName": "KUE04_Messwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "200 MOhm" - }, - { - "IdLD": 50011, - "Modul": 5, - "DpName": "KUE05_Messwert", - "ModulName": "?", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "200 MOhm" - }, - { - "IdLD": 50011, - "Modul": 6, - "DpName": "KUE06_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50011, - "Modul": 1, - "DpName": "KUE01_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50011, - "Modul": 2, - "DpName": "KUE02_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "5.53 kOhm" - }, - { - "IdLD": 50011, - "Modul": 3, - "DpName": "KUE03_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.2 kOhm" - }, - { - "IdLD": 50011, - "Modul": 4, - "DpName": "KUE04_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "6.09 kOhm" - }, - { - "IdLD": 50011, - "Modul": 5, - "DpName": "KUE05_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "22.37 kOhm" - }, - { - "IdLD": 50011, - "Modul": 6, - "DpName": "KUE06_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50011, - "Modul": 19, - "DpName": "KUE19_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.21 kOhm" - }, - { - "IdLD": 50063, - "Modul": 4, - "DpName": "KUE04_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10 MOhm" - }, - { - "IdLD": 50063, - "Modul": 12, - "DpName": "KUE12_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10 MOhm" - }, - { - "IdLD": 50063, - "Modul": 13, - "DpName": "KUE13_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10 MOhm" - }, - { - "IdLD": 50063, - "Modul": 14, - "DpName": "KUE14_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10 MOhm" - }, - { - "IdLD": 50063, - "Modul": 23, - "DpName": "KUE23_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10 MOhm" - }, - { - "IdLD": 50063, - "Modul": 24, - "DpName": "KUE24_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10 MOhm" - }, - { - "IdLD": 50063, - "Modul": 1, - "DpName": "KUE01_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50063, - "Modul": 2, - "DpName": "KUE02_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50063, - "Modul": 4, - "DpName": "KUE04_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50063, - "Modul": 5, - "DpName": "KUE05_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50066, - "Modul": 1, - "DpName": "KUE01_Messwert", - "ModulName": "K1", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "11 MOhm" - }, - { - "IdLD": 50066, - "Modul": 3, - "DpName": "KUE03_Messwert", - "ModulName": "K4", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "200 MOhm" - }, - { - "IdLD": 50066, - "Modul": 4, - "DpName": "KUE04_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "200 MOhm" - }, - { - "IdLD": 50066, - "Modul": 6, - "DpName": "KUE06_Messwert", - "ModulName": "?", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50066, - "Modul": 7, - "DpName": "KUE07_Messwert", - "ModulName": "?", - "ModulTyp": "KÜSS V2", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "10.5 MOhm" - }, - { - "IdLD": 50066, - "Modul": 8, - "DpName": "KUE08_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50066, - "Modul": 9, - "DpName": "KUE09_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "200 MOhm" - }, - { - "IdLD": 50066, - "Modul": 14, - "DpName": "KUE14_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "200 MOhm" - }, - { - "IdLD": 50066, - "Modul": 21, - "DpName": "KUE21_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "2.67 MOhm" - }, - { - "IdLD": 50066, - "Modul": 22, - "DpName": "KUE22_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "2.71 MOhm" - }, - { - "IdLD": 50066, - "Modul": 24, - "DpName": "KUE24_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "2.95 MOhm" - }, - { - "IdLD": 50066, - "Modul": 1, - "DpName": "KUE01_Schleifenwert", - "ModulName": "K1", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "2.33 kOhm" - }, - { - "IdLD": 50066, - "Modul": 2, - "DpName": "KUE02_Schleifenwert", - "ModulName": "K2", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "4.01 kOhm" - }, - { - "IdLD": 50066, - "Modul": 3, - "DpName": "KUE03_Schleifenwert", - "ModulName": "K4", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "49.10 kOhm" - }, - { - "IdLD": 50066, - "Modul": 4, - "DpName": "KUE04_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50066, - "Modul": 5, - "DpName": "KUE05_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "5.72 kOhm" - }, - { - "IdLD": 50066, - "Modul": 6, - "DpName": "KUE06_Schleifenwert", - "ModulName": "?", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50066, - "Modul": 7, - "DpName": "KUE07_Schleifenwert", - "ModulName": "?", - "ModulTyp": "KÜSS V2", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "2.74 kOhm" - }, - { - "IdLD": 50066, - "Modul": 8, - "DpName": "KUE08_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50066, - "Modul": 14, - "DpName": "KUE14_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "5.69 kOhm" - }, - { - "IdLD": 50922, - "Modul": 5, - "DpName": "KUE05_Messwert", - "ModulName": "Kue 5", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50922, - "Modul": 6, - "DpName": "KUE06_Messwert", - "ModulName": "Kue 6", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50922, - "Modul": 7, - "DpName": "KUE07_Messwert", - "ModulName": "KUESS 7", - "ModulTyp": "KÜSS V2", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50922, - "Modul": 8, - "DpName": "KUE08_Messwert", - "ModulName": "Test8", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50922, - "Modul": 14, - "DpName": "KUE14_Messwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 MOhm" - }, - { - "IdLD": 50922, - "Modul": 1, - "DpName": "KUE01_Schleifenwert", - "ModulName": "Test1", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 2, - "DpName": "KUE02_Schleifenwert", - "ModulName": "Kue 2", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "64.01 kOhm" - }, - { - "IdLD": 50922, - "Modul": 3, - "DpName": "KUE03_Schleifenwert", - "ModulName": "Kue 3", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "64.01 kOhm" - }, - { - "IdLD": 50922, - "Modul": 4, - "DpName": "KUE04_Schleifenwert", - "ModulName": "Kue 4", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "64.01 kOhm" - }, - { - "IdLD": 50922, - "Modul": 5, - "DpName": "KUE05_Schleifenwert", - "ModulName": "Kue 5", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 6, - "DpName": "KUE06_Schleifenwert", - "ModulName": "Kue 6", - "ModulTyp": "Kü605µC", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 7, - "DpName": "KUE07_Schleifenwert", - "ModulName": "KUESS 7", - "ModulTyp": "KÜSS V2", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 8, - "DpName": "KUE08_Schleifenwert", - "ModulName": "Test8", - "ModulTyp": "Kü705-FO", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0.25 kOhm" - }, - { - "IdLD": 50922, - "Modul": 9, - "DpName": "KUE09_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 10, - "DpName": "KUE10_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 11, - "DpName": "KUE11_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 12, - "DpName": "KUE12_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 13, - "DpName": "KUE13_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 14, - "DpName": "KUE14_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - }, - { - "IdLD": 50922, - "Modul": 15, - "DpName": "KUE15_Schleifenwert", - "ModulName": "?", - "ModulTyp": "?", - "Message": "?", - "Level": -1, - "PrioColor": "#ffffff", - "PrioName": "?", - "Value": "0 kOhm" - } - ] -} diff --git a/public/mockData/deviceNameByIdMock.json b/public/mockData/deviceNameByIdMock.json deleted file mode 100644 index da5957ed0..000000000 --- a/public/mockData/deviceNameByIdMock.json +++ /dev/null @@ -1 +0,0 @@ -{ "50922": "CPL Ismael" } diff --git a/public/mockData/gisStationsMeasurementsMock.json b/public/mockData/gisStationsMeasurementsMock.json deleted file mode 100644 index a8cb6a815..000000000 --- a/public/mockData/gisStationsMeasurementsMock.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "Name": "Liste aller Messungen der Geraete", - "Zeitstempel": "2025-03-05T12:23:16.0756875+01:00", - "IdMap": "12", - "Statis": [ - { - "IdLD": 50951, - "IdL": 24101, - "IdDP": 3, - "Na": "FBT", - "Val": "5", - "Unit": "°C", - "Gr": "GMA", - "Area_Name": "Rastede" - } - ] -} diff --git a/public/mockData/gisStationsStaticDistrictMock.json b/public/mockData/gisStationsStaticDistrictMock.json deleted file mode 100644 index 3442a0084..000000000 --- a/public/mockData/gisStationsStaticDistrictMock.json +++ /dev/null @@ -1,381 +0,0 @@ -{ - "Name": "Liste aller Geraete einer bestimmten Karte", - "Zeitstempel": "2025-03-05T14:55:10.1184475+01:00", - "IdMap": "12", - "Points": [ - { - "LD_Name": "CPL Ismael", - "IdLD": 50922, - "Device": "CPL V3.5 mit 24 Kü", - "Link": "cpl.aspx?ver=35&kue=24&id=50922", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 20, - "System": 1, - "Active": 1 - }, - { - "LD_Name": "LTEModem", - "IdLD": 50950, - "Device": "LTE Modem LR77", - "Link": "lr77.aspx?ver=1&id=50950", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 12, - "System": 5, - "Active": 1 - }, - { - "LD_Name": "GMA ISA", - "IdLD": 50951, - "Device": "Glättemeldeanlage", - "Link": "gma.aspx?ver=1&id=50951", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 1, - "System": 11, - "Active": 1 - }, - { - "LD_Name": "Cisco Router 1841 ISA", - "IdLD": 50953, - "Device": "Cisco 1841", - "Link": "cisco1841.aspx?ver=1&id=50953", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 21, - "System": 6, - "Active": 1 - }, - { - "LD_Name": "Cisco Router 1921 ISA", - "IdLD": 50954, - "Device": "Cisco 1921", - "Link": "cisco1921.aspx?ver=1&id=50954", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 21, - "System": 6, - "Active": 1 - }, - { - "LD_Name": "Cisco Router 8200 ISA", - "IdLD": 50955, - "Device": "Cisco 8200", - "Link": "cisco8200.aspx?ver=1&id=50955", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 21, - "System": 6, - "Active": 1 - }, - { - "LD_Name": "Dauerzählstelle DZ ISA", - "IdLD": 50956, - "Device": "Dauerzählstelle DZ", - "Link": "dauz.aspx?ver=1&id=50956", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 14, - "System": 110, - "Active": 1 - }, - { - "LD_Name": "ECI Gerät ISA", - "IdLD": 50957, - "Device": "ECI", - "Link": "eci.aspx?ver=1&id=50957", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 17, - "System": 2, - "Active": 1 - }, - { - "LD_Name": "LTE-Modem LR77", - "IdLD": 50958, - "Device": "LTE Modem LR77", - "Link": "lr77.aspx?ver=1&id=50958", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 12, - "System": 5, - "Active": 1 - }, - { - "LD_Name": "Glasfaserüberwachung OTU ISA", - "IdLD": 50959, - "Device": "OTU", - "Link": "otu.aspx?ver=1&id=50959", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 24, - "System": 9, - "Active": 1 - }, - { - "LD_Name": "Siemens Notrufsystem ISA", - "IdLD": 50960, - "Device": "Notruf Server NRS 2000", - "Link": "nrs_server.aspx?ver=1&id=50960", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 19, - "System": 8, - "Active": 1 - }, - { - "LD_Name": "SMS-Modem ISA", - "IdLD": 50961, - "Device": "SMS Funkmodem", - "Link": "sms_modem.aspx?ver=1&id=50961", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 12, - "System": 111, - "Active": 1 - }, - { - "LD_Name": "Basisgerät Sonstige ISA", - "IdLD": 50962, - "Device": "Basisgerät", - "Link": "basis.aspx?ver=1&id=50962", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 31, - "System": 200, - "Active": 0 - }, - { - "LD_Name": "Talasmeldestation ISA", - "IdLD": 50963, - "Device": "CPL V3.5 mit 16 Kü", - "Link": "cpl.aspx?ver=35&kue=16&id=50963", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 20, - "System": 1, - "Active": 1 - }, - { - "LD_Name": "TALAS ICL M4 Meldestation ISA", - "IdLD": 50964, - "Device": "ICL", - "Link": "icl.aspx?ver=1&id=50964", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 23, - "System": 100, - "Active": 1 - }, - { - "LD_Name": "TALAS ICL M2 Meldestation ISA", - "IdLD": 50965, - "Device": "ICL", - "Link": "icl.aspx?ver=1&id=50965", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 23, - "System": 100, - "Active": 1 - }, - { - "LD_Name": "TALAS ICL M3 Meldestation ISA", - "IdLD": 50966, - "Device": "ICL", - "Link": "icl.aspx?ver=1&id=50966", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 23, - "System": 100, - "Active": 1 - }, - { - "LD_Name": "TALAS ICL M1 Meldestation ISA", - "IdLD": 50967, - "Device": "ICL", - "Link": "icl.aspx?ver=1&id=50967", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 23, - "System": 100, - "Active": 1 - }, - { - "LD_Name": "TL-Komponente-Router ISA", - "IdLD": 50968, - "Device": "TK-Router", - "Link": "tk_router.aspx?ver=1&id=50968", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 14, - "System": 30, - "Active": 1 - }, - { - "LD_Name": "TK-Anlage Alcatel OXO ISA", - "IdLD": 50969, - "Device": "TK-Anlage Alcatel OXO", - "Link": "tk_oxo.aspx?ver=1&id=50969", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 14, - "System": 30, - "Active": 1 - }, - { - "LD_Name": "WAGO Klemmen 16 ISA", - "IdLD": 50971, - "Device": "WAGO 16 DE", - "Link": "wago.aspx?ver=1&DE=16&id=50971", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 9, - "System": 7, - "Active": 1 - }, - { - "LD_Name": "WAGO Klemmen 32 ISA", - "IdLD": 50972, - "Device": "WAGO 32 DE", - "Link": "wago.aspx?ver=1&DE=32&id=50972", - "Location_Name": "Littwin", - "Location_Short": "LTW", - "IdLocation": 24101, - "Area_Name": "Rastede", - "Area_Short": "", - "IdArea": 20998, - "X": 53.246112, - "Y": 8.162241, - "Icon": 9, - "System": 7, - "Active": 1 - } - ] -} diff --git a/public/mockData/gisStationsStatusDistrictMock.json b/public/mockData/gisStationsStatusDistrictMock.json deleted file mode 100644 index 7dd3a73ac..000000000 --- a/public/mockData/gisStationsStatusDistrictMock.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "Name": "Liste aller Statis der Geraete", - "Zeitstempel": "2025-03-05T14:56:54.4913452+01:00", - "IdMap": "12", - "Statis": [ - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 01 test5", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 05 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 17 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 31 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 32 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Station offline", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "minor", - "Le": 3, - "Co": "#FFFF00", - "Me": "Eingang DE 02 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "minor", - "Le": 3, - "Co": "#FFFF00", - "Me": "KÜG 08: Überspannung gehend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "major", - "Le": 2, - "Co": "#FF9900", - "Me": "Eingang DE 03 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "critical", - "Le": 1, - "Co": "#FF0000", - "Me": "KÜG 01: Aderbruch kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "critical", - "Le": 1, - "Co": "#FF0000", - "Me": "KÜG 02: Aderbruch kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "critical", - "Le": 1, - "Co": "#FF0000", - "Me": "KÜG 03: Aderbruch kommend", - "Feld": 4, - "Icon": 0 - } - ] -} diff --git a/public/mockData/gisStationsStatusMock.json b/public/mockData/gisStationsStatusMock.json deleted file mode 100644 index ed81065c3..000000000 --- a/public/mockData/gisStationsStatusMock.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "Name": "Liste aller Statis der Geraete", - "Zeitstempel": "2025-03-05T15:04:09.206634+01:00", - "IdMap": "12", - "Statis": [ - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 01 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 05 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 17 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 31 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Eingang DE 32 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "system", - "Le": 4, - "Co": "#FF00FF", - "Me": "Station offline", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "minor", - "Le": 3, - "Co": "#FFFF00", - "Me": "Eingang DE 02 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "minor", - "Le": 3, - "Co": "#FFFF00", - "Me": "KÜG 08: Überspannung gehend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "major", - "Le": 2, - "Co": "#FF9900", - "Me": "Eingang DE 03 kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "critical", - "Le": 1, - "Co": "#FF0000", - "Me": "KÜG 01: Aderbruch kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "critical", - "Le": 1, - "Co": "#FF0000", - "Me": "KÜG 02: Aderbruch kommend", - "Feld": 4, - "Icon": 0 - }, - { - "IdLD": 50922, - "Na": "critical", - "Le": 1, - "Co": "#FF0000", - "Me": "KÜG 03: Aderbruch kommend", - "Feld": 4, - "Icon": 0 - } - ] -} diff --git a/public/mockData/gisSystemStaticMock.json b/public/mockData/gisSystemStaticMock.json deleted file mode 100644 index 3ae5800e2..000000000 --- a/public/mockData/gisSystemStaticMock.json +++ /dev/null @@ -1,268 +0,0 @@ -{ - "Name": "Liste aller angezeigten Systeme", - "Zeitstempel": "2025-03-05T15:04:55.2507517+01:00", - "IdMap": "12", - "Systems": [ - { - "IdSystem": 1, - "Name": "TALAS", - "Longname": "Talas Meldestationen", - "Allow": 1, - "Icon": 1 - }, - { - "IdSystem": 2, - "Name": "ECI", - "Longname": "ECI Geräte", - "Allow": 1, - "Icon": 2 - }, - { - "IdSystem": 3, - "Name": "ULAF", - "Longname": "ULAF Geräte", - "Allow": 0, - "Icon": 3 - }, - { - "IdSystem": 5, - "Name": "LTE Modem", - "Longname": "LR77 GSM Modems", - "Allow": 1, - "Icon": 5 - }, - { - "IdSystem": 6, - "Name": "Cisco Router", - "Longname": "Cisco Router", - "Allow": 1, - "Icon": 6 - }, - { - "IdSystem": 7, - "Name": "WAGO", - "Longname": "WAGO I/O Systeme", - "Allow": 1, - "Icon": 7 - }, - { - "IdSystem": 8, - "Name": "Siemens", - "Longname": "Siemens Notrufsysteme", - "Allow": 1, - "Icon": 8 - }, - { - "IdSystem": 9, - "Name": "OTDR", - "Longname": "Glasfaserüberwachung OTU", - "Allow": 1, - "Icon": 9 - }, - { - "IdSystem": 10, - "Name": "WDM", - "Longname": " Wavelength Division Multiplexing", - "Allow": 1, - "Icon": 10 - }, - { - "IdSystem": 11, - "Name": "GMA", - "Longname": "Glättemeldeanlagen", - "Allow": 1, - "Icon": 11 - }, - { - "IdSystem": 13, - "Name": "Messstellen", - "Longname": "Messstellen", - "Allow": 0, - "Icon": 13 - }, - { - "IdSystem": 30, - "Name": "TK-Komponenten", - "Longname": "TK-Komponenten", - "Allow": 1, - "Icon": 30 - }, - { - "IdSystem": 100, - "Name": "TALAS ICL", - "Longname": "Talas ICL Unterstationen", - "Allow": 1, - "Icon": 100 - }, - { - "IdSystem": 110, - "Name": "DAUZ", - "Longname": "Dauerzählstellen", - "Allow": 1, - "Icon": 110 - }, - { - "IdSystem": 111, - "Name": "SMS Modem", - "Longname": "SMS Modem", - "Allow": 1, - "Icon": 111 - }, - { - "IdSystem": 200, - "Name": "Sonstige", - "Longname": "Sonstige", - "Allow": 1, - "Icon": 200 - } - ], - "Rights": [ - { - "IdRight": 1 - }, - { - "IdRight": 2 - }, - { - "IdRight": 3 - }, - { - "IdRight": 5 - }, - { - "IdRight": 6 - }, - { - "IdRight": 7 - }, - { - "IdRight": 8 - }, - { - "IdRight": 10 - }, - { - "IdRight": 11 - }, - { - "IdRight": 12 - }, - { - "IdRight": 20 - }, - { - "IdRight": 22 - }, - { - "IdRight": 23 - }, - { - "IdRight": 25 - }, - { - "IdRight": 30 - }, - { - "IdRight": 40 - }, - { - "IdRight": 41 - }, - { - "IdRight": 42 - }, - { - "IdRight": 43 - }, - { - "IdRight": 44 - }, - { - "IdRight": 45 - }, - { - "IdRight": 46 - }, - { - "IdRight": 47 - }, - { - "IdRight": 48 - }, - { - "IdRight": 49 - }, - { - "IdRight": 50 - }, - { - "IdRight": 51 - }, - { - "IdRight": 52 - }, - { - "IdRight": 55 - }, - { - "IdRight": 56 - }, - { - "IdRight": 60 - }, - { - "IdRight": 61 - }, - { - "IdRight": 62 - }, - { - "IdRight": 63 - }, - { - "IdRight": 64 - }, - { - "IdRight": 65 - }, - { - "IdRight": 68 - }, - { - "IdRight": 69 - }, - { - "IdRight": 70 - }, - { - "IdRight": 71 - }, - { - "IdRight": 72 - }, - { - "IdRight": 73 - }, - { - "IdRight": 79 - }, - { - "IdRight": 80 - }, - { - "IdRight": 90 - }, - { - "IdRight": 93 - }, - { - "IdRight": 94 - }, - { - "IdRight": 95 - }, - { - "IdRight": 96 - } - ] -} diff --git a/redux/api/fromDB/fetchLocationDevices.js b/redux/api/fromDB/fetchLocationDevices.js new file mode 100644 index 000000000..53595dbdb --- /dev/null +++ b/redux/api/fromDB/fetchLocationDevices.js @@ -0,0 +1,8 @@ +// /redux/api/fromDB/fetchLocationDevices.js +export const fetchLocationDevices = async () => { + const response = await fetch("/api/talas_v5_DB/locationDevice/locationDevices"); + if (!response.ok) { + throw new Error("Geräteliste konnte nicht geladen werden"); + } + return await response.json(); +}; diff --git a/public/mockData/poiDataMock.json b/redux/api/fromDB/poiTypLoader.js similarity index 100% rename from public/mockData/poiDataMock.json rename to redux/api/fromDB/poiTypLoader.js diff --git a/redux/api/fromWebService/fetchGisStationsMeasurements.js b/redux/api/fromWebService/fetchGisStationsMeasurements.js new file mode 100644 index 000000000..8cae2a5cc --- /dev/null +++ b/redux/api/fromWebService/fetchGisStationsMeasurements.js @@ -0,0 +1,22 @@ +// /redux/api/fromWebService/fetchGisStationsMeasurements.js +// http://192.168.10.33/talas5/ClientData/WebServiceMap.asmx/GisStationsMeasurements?idMap=12&idUser=484 + +const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL; + +export const fetchGisStationsMeasurements = async () => { + const params = new URLSearchParams(window.location.search); + const idMap = params.get("idMap") || process.env.NEXT_PUBLIC_DEFAULT_ID_MAP || "12"; + const idUser = params.get("idUser") || process.env.NEXT_PUBLIC_DEFAULT_ID_USER || "484"; + + //console.log("🔍 fetchGisStationsMeasurements - URL:", `${apiBaseUrl}/GisStationsMeasurements?idMap=${idMap}&idUser=${idUser}`); + + const response = await fetch(`${apiBaseUrl}/GisStationsMeasurements?idMap=${idMap}&idUser=${idUser}`); + + if (!response.ok) { + throw new Error("GisStationsMeasurements konnte nicht geladen werden"); + } + + const data = await response.json(); + //console.log("✅ fetchGisStationsMeasurements - Daten:", data); + return data; +}; diff --git a/redux/api/fromWebService/fetchGisStationsStatic.js b/redux/api/fromWebService/fetchGisStationsStatic.js new file mode 100644 index 000000000..09786a338 --- /dev/null +++ b/redux/api/fromWebService/fetchGisStationsStatic.js @@ -0,0 +1,25 @@ +// /redux/api/fromWebService/fetchGisStationsStatic.js +// z.B. http://192.168.10.33/talas5/ClientData/WebServiceMap.asmx/GisStationsStatic?idMap=12 +const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL; + +export const fetchGisStationsStatic = async () => { + try { + const response = await fetch(`${apiBaseUrl}/GisStationsStatic?idMap=12`); + + //console.log("📡 API Response Status:", response.status); + //console.log("📡 API Response Headers:", response.headers.get("content-type")); + + const text = await response.text(); + console.log("📡 API Response Text von fetch:", text); + console.log("📡 API Response response von fetch:", response); + + if (!response.ok || !response.headers.get("content-type")?.includes("application/json")) { + throw new Error("❌ Fehler: Antwort ist kein gültiges JSON"); + } + + return JSON.parse(text); + } catch (error) { + console.error("❌ Fehler beim Abrufen der GIS Stations Static:", error); + return null; + } +}; diff --git a/redux/api/fromWebService/fetchGisStationsStaticDistrict.js b/redux/api/fromWebService/fetchGisStationsStaticDistrict.js new file mode 100644 index 000000000..3f8d79ed3 --- /dev/null +++ b/redux/api/fromWebService/fetchGisStationsStaticDistrict.js @@ -0,0 +1,22 @@ +// /redux/api/fromWebService/fetchGisStationsStaticDistrict.js +// http://192.168.10.33/talas5/ClientData/WebServiceMap.asmx/GisStationsStaticDistrict?idMap=12&idUser=484 + +const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL; + +export const fetchGisStationsStaticDistrict = async () => { + const params = new URLSearchParams(window.location.search); + const idMap = params.get("idMap") || process.env.NEXT_PUBLIC_DEFAULT_ID_MAP || "12"; + const idUser = params.get("idUser") || process.env.NEXT_PUBLIC_DEFAULT_ID_USER || "484"; + + // console.log("🔍 fetchGisStationsStaticDistrict - URL:", `${apiBaseUrl}/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`); + + const response = await fetch(`${apiBaseUrl}/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`); + + if (!response.ok) { + throw new Error("GisStationsStaticDistrict konnte nicht geladen werden"); + } + + const data = await response.json(); + // console.log("✅ fetchGisStationsStaticDistrict - Daten:", data); + return data; +}; diff --git a/redux/api/fromWebService/fetchGisStationsStatusDistrict.js b/redux/api/fromWebService/fetchGisStationsStatusDistrict.js new file mode 100644 index 000000000..34faa1959 --- /dev/null +++ b/redux/api/fromWebService/fetchGisStationsStatusDistrict.js @@ -0,0 +1,22 @@ +// /redux/api/fromWebService/fetchGisStationsStatusDistrict.js +// http://192.168.10.33/talas5/ClientData/WebServiceMap.asmx/GisStationsStatusDistrict?idMap=12&idUser=484 + +const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL; + +export const fetchGisStationsStatusDistrict = async () => { + const params = new URLSearchParams(window.location.search); + const idMap = params.get("idMap") || process.env.NEXT_PUBLIC_DEFAULT_ID_MAP || "12"; + const idUser = params.get("idUser") || process.env.NEXT_PUBLIC_DEFAULT_ID_USER || "484"; + + //console.log("🔍 fetchGisStationsStatusDistrict - URL:", `${apiBaseUrl}/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`); + + const response = await fetch(`${apiBaseUrl}/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`); + + if (!response.ok) { + throw new Error("GisStationsStatusDistrict konnte nicht geladen werden"); + } + + const data = await response.json(); + //console.log("✅ fetchGisStationsStatusDistrict - Daten:", data); + return data; +}; diff --git a/redux/api/fromWebService/fetchGisSystemStatic.js b/redux/api/fromWebService/fetchGisSystemStatic.js new file mode 100644 index 000000000..4e22f5c4f --- /dev/null +++ b/redux/api/fromWebService/fetchGisSystemStatic.js @@ -0,0 +1,18 @@ +// /redux/api/fromWebService/fetchGisSystemStatic.js +// http://192.168.10.33/talas5/ClientData/WebServiceMap.asmx/GisSystemStatic?idMap=12&idUser=484 + +const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL; + +export async function fetchGisSystemStatic() { + const params = new URLSearchParams(window.location.search); + const idMap = params.get("idMap") || process.env.NEXT_PUBLIC_DEFAULT_ID_MAP || "12"; + const idUser = params.get("idUser") || process.env.NEXT_PUBLIC_DEFAULT_ID_USER || "484"; + + //console.log("🔍 fetchGisSystemStatic - URL:", `${apiBaseUrl}/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`); + + const response = await fetch(`${apiBaseUrl}/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`); + const data = await response.json(); + + //console.log("✅ fetchGisSystemStatic - Daten:", data); + return data; +} diff --git a/public/mockData/userRightsMock.json b/redux/api/fromWebService/userSessionLoader.js similarity index 100% rename from public/mockData/userRightsMock.json rename to redux/api/fromWebService/userSessionLoader.js diff --git a/redux/slices/addPoiOnPolylineSlice.js b/redux/slices/addPoiOnPolylineSlice.js new file mode 100644 index 000000000..567ce9bb0 --- /dev/null +++ b/redux/slices/addPoiOnPolylineSlice.js @@ -0,0 +1,24 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const initialState = { + isOpen: false, + latlng: null, +}; + +const addPoiOnPolylineSlice = createSlice({ + name: "addPoiOnPolyline", + initialState, + reducers: { + openAddPoiOnPolylineModal: (state, action) => { + state.isOpen = true; + state.latlng = action.payload; + }, + closeAddPoiOnPolylineModal: (state) => { + state.isOpen = false; + state.latlng = null; + }, + }, +}); + +export const { openAddPoiOnPolylineModal, closeAddPoiOnPolylineModal } = addPoiOnPolylineSlice.actions; +export default addPoiOnPolylineSlice.reducer; diff --git a/redux/slices/db/locationDevicesFromDBSlice.js b/redux/slices/db/locationDevicesFromDBSlice.js new file mode 100644 index 000000000..bc36b7b70 --- /dev/null +++ b/redux/slices/db/locationDevicesFromDBSlice.js @@ -0,0 +1,33 @@ +// /redux/slices/db/locationDevicesFromDBSlice.js +import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; +import { fetchLocationDevices } from "../../api/fromDB/fetchLocationDevices"; + +export const fetchLocationDevicesFromDB = createAsyncThunk("locationDevicesFromDB/fetchLocationDevicesFromDB", async () => { + return fetchLocationDevices(); +}); + +const locationDevicesFromDBSlice = createSlice({ + name: "locationDevicesFromDB", + initialState: { + devices: [], + status: "idle", + error: null, + }, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchLocationDevicesFromDB.pending, (state) => { + state.status = "loading"; + }) + .addCase(fetchLocationDevicesFromDB.fulfilled, (state, action) => { + state.status = "succeeded"; + state.devices = action.payload; // <-- Hier landen die Daten + }) + .addCase(fetchLocationDevicesFromDB.rejected, (state, action) => { + state.status = "failed"; + state.error = action.error.message; + }); + }, +}); + +export default locationDevicesFromDBSlice.reducer; diff --git a/redux/slices/db/poiTypesSlice.js b/redux/slices/db/poiTypesSlice.js new file mode 100644 index 000000000..b4bb7cb9b --- /dev/null +++ b/redux/slices/db/poiTypesSlice.js @@ -0,0 +1,30 @@ +// /redux/slices/db/poiTypesSlice.js +import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; + +// API-Abruf für POI-Typen +export const fetchPoiTypes = createAsyncThunk("poiTypes/fetchPoiTypes", async () => { + const API_BASE_URL = process.env.NEXT_PUBLIC_API_PORT_3000; + const response = await fetch(`${API_BASE_URL}/api/talas_v5_DB/poiTyp/readPoiTyp`); + return await response.json(); +}); + +const poiTypesSlice = createSlice({ + name: "poiTypes", + initialState: { data: [], status: "idle" }, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchPoiTypes.pending, (state) => { + state.status = "loading"; + }) + .addCase(fetchPoiTypes.fulfilled, (state, action) => { + state.data = action.payload; + state.status = "succeeded"; + }) + .addCase(fetchPoiTypes.rejected, (state) => { + state.status = "failed"; + }); + }, +}); + +export default poiTypesSlice.reducer; diff --git a/redux/slices/gisStationsStaticDistrictSlice.js b/redux/slices/gisStationsStaticDistrictSlice.js deleted file mode 100644 index 793160377..000000000 --- a/redux/slices/gisStationsStaticDistrictSlice.js +++ /dev/null @@ -1,23 +0,0 @@ -// /redux/slices/gisStationsStaticDistrictSlice.js -import { createSlice } from "@reduxjs/toolkit"; - -const initialState = []; - -const gisStationsStaticDistrictSlice = createSlice({ - name: "gisStationsStaticDistrict", - initialState, - reducers: { - setGisStationsStaticDistrict: (state, action) => { - return action.payload; - }, - clearGisStationsStaticDistrict: () => { - return []; - }, - }, -}); - -export const { setGisStationsStaticDistrict, clearGisStationsStaticDistrict } = gisStationsStaticDistrictSlice.actions; - -export const selectGisStationsStaticDistrict = (state) => state.gisStationsStaticDistrict; - -export default gisStationsStaticDistrictSlice.reducer; diff --git a/redux/slices/gisSystemStaticSlice.js b/redux/slices/gisSystemStaticSlice.js deleted file mode 100644 index ad4fb3774..000000000 --- a/redux/slices/gisSystemStaticSlice.js +++ /dev/null @@ -1,7 +0,0 @@ -// /redux/slices/gisSystemStaticSlice.js -import { atom } from "recoil"; - -export const gisSystemStaticState = atom({ - key: "gisSystemStatic", // Eindeutiger Schlüssel (innerhalb des Projekts) - default: [], // Standardwert (Anfangszustand) -}); diff --git a/redux/slices/polylineContextMenuSlice.js b/redux/slices/polylineContextMenuSlice.js new file mode 100644 index 000000000..9735f7088 --- /dev/null +++ b/redux/slices/polylineContextMenuSlice.js @@ -0,0 +1,56 @@ +// redux/slices/polylineContextMenuSlice.js +import { createSlice } from "@reduxjs/toolkit"; + +const initialState = { + isOpen: false, + position: null, + forceClose: false, + timerStart: null, + countdown: 20, + countdownActive: false, // **Neu: Redux merkt, ob der Timer aktiv ist** +}; + +const polylineContextMenuSlice = createSlice({ + name: "polylineContextMenu", + initialState, + reducers: { + openPolylineContextMenu: (state, action) => { + state.isOpen = true; + state.position = { lat: action.payload.position.lat, lng: action.payload.position.lng }; + state.forceClose = false; + state.timerStart = Date.now(); + state.countdown = 20; + state.countdownActive = true; // **Timer aktiv setzen** + }, + closePolylineContextMenu: (state) => { + state.isOpen = false; + state.position = null; + state.timerStart = null; + state.countdown = 0; + state.countdownActive = false; // **Timer stoppen** + }, + updateCountdown: (state) => { + if (state.timerStart && state.countdownActive) { + const elapsedTime = (Date.now() - state.timerStart) / 1000; + state.countdown = Math.max(20 - elapsedTime, 0); + + if (state.countdown <= 2) { + state.isOpen = false; + state.position = null; + state.countdownActive = false; + } + } + }, + forceCloseContextMenu: (state) => { + state.isOpen = false; + state.position = null; + state.forceClose = true; + state.timerStart = null; + state.countdown = 0; + state.countdownActive = false; + }, + }, +}); + +export const { openPolylineContextMenu, closePolylineContextMenu, updateCountdown, forceCloseContextMenu } = polylineContextMenuSlice.actions; +export default polylineContextMenuSlice.reducer; diff --git a/redux/slices/webService/gisStationsMeasurementsSlice.js b/redux/slices/webService/gisStationsMeasurementsSlice.js new file mode 100644 index 000000000..d72c4036d --- /dev/null +++ b/redux/slices/webService/gisStationsMeasurementsSlice.js @@ -0,0 +1,35 @@ +// /redux/slices/webService/gisStationsMeasurementsSlice.js +import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; +import { fetchGisStationsMeasurements } from "../../api/fromWebService/fetchGisStationsMeasurements"; + +export const fetchGisStationsMeasurementsFromWebService = createAsyncThunk("gisStationsMeasurements/fetchGisStationsMeasurementsFromWebService", async () => { + return fetchGisStationsMeasurements(); +}); + +const gisStationsMeasurementsSlice = createSlice({ + name: "gisStationsMeasurements", + initialState: { + data: [], + status: "idle", + error: null, + }, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchGisStationsMeasurementsFromWebService.pending, (state) => { + state.status = "loading"; + }) + .addCase(fetchGisStationsMeasurementsFromWebService.fulfilled, (state, action) => { + state.status = "succeeded"; + state.data = action.payload; + }) + .addCase(fetchGisStationsMeasurementsFromWebService.rejected, (state, action) => { + state.status = "failed"; + state.error = action.error.message; + }); + }, +}); + +export const selectGisStationsMeasurements = (state) => state.gisStationsMeasurements.data; + +export default gisStationsMeasurementsSlice.reducer; diff --git a/redux/slices/webService/gisStationsStaticDistrictSlice.js b/redux/slices/webService/gisStationsStaticDistrictSlice.js new file mode 100644 index 000000000..7c7780cd6 --- /dev/null +++ b/redux/slices/webService/gisStationsStaticDistrictSlice.js @@ -0,0 +1,35 @@ +// /redux/slices/webService/gisStationsStaticDistrictSlice.js +import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; +import { fetchGisStationsStaticDistrict } from "../../api/fromWebService/fetchGisStationsStaticDistrict"; + +export const fetchGisStationsStaticDistrictFromWebService = createAsyncThunk("gisStationsStaticDistrict/fetchGisStationsStaticDistrictFromWebService", async () => { + return fetchGisStationsStaticDistrict(); +}); + +const gisStationsStaticDistrictSlice = createSlice({ + name: "gisStationsStaticDistrict", + initialState: { + data: [], + status: "idle", + error: null, + }, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchGisStationsStaticDistrictFromWebService.pending, (state) => { + state.status = "loading"; + }) + .addCase(fetchGisStationsStaticDistrictFromWebService.fulfilled, (state, action) => { + state.status = "succeeded"; + state.data = action.payload; + }) + .addCase(fetchGisStationsStaticDistrictFromWebService.rejected, (state, action) => { + state.status = "failed"; + state.error = action.error.message; + }); + }, +}); + +export const selectGisStationsStaticDistrict = (state) => state.gisStationsStaticDistrict.data; + +export default gisStationsStaticDistrictSlice.reducer; diff --git a/redux/slices/webService/gisStationsStaticSlice.js b/redux/slices/webService/gisStationsStaticSlice.js new file mode 100644 index 000000000..918c22a4c --- /dev/null +++ b/redux/slices/webService/gisStationsStaticSlice.js @@ -0,0 +1,58 @@ +// /redux/api/fromDB/fetchLocationDevices.js +// das ist für Datasheet dropdownmenu Bereiche/Area-Name +import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; + +// API-Fetch-Funktion für GIS Stations Static mit dynamischem URL-Parameter +export const fetchGisStationsStatic = createAsyncThunk("gisStationsStatic/fetchGisStationsStatic", async (_, { rejectWithValue }) => { + try { + const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL; + + // URL-Parameter aus der aktuellen Browser-URL holen + const params = new URLSearchParams(window.location.search); + const idMap = params.get("idMap") || "12"; // Standardwert "12", falls `idMap` nicht existiert + + const url = `${apiBaseUrl}/GisStationsStatic?idMap=${idMap}`; + console.log("📡 API Request URL:", url); + + const response = await fetch(url); + + if (!response.ok) { + throw new Error("GisStationsStatic konnte nicht geladen werden"); + } + + const data = await response.json(); + return data; + } catch (error) { + return rejectWithValue(error.message); + } +}); + +// Redux-Slice +const gisStationsStaticSlice = createSlice({ + name: "gisStationsStatic", + initialState: { + data: null, + status: "idle", + error: null, + }, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchGisStationsStatic.pending, (state) => { + state.status = "loading"; + }) + .addCase(fetchGisStationsStatic.fulfilled, (state, action) => { + state.status = "succeeded"; + state.data = action.payload; + }) + .addCase(fetchGisStationsStatic.rejected, (state, action) => { + state.status = "failed"; + state.error = action.payload; + }); + }, +}); + +// Selector-Funktion +export const selectGisStationsStatic = (state) => state.gisStationsStatic.data; + +export default gisStationsStaticSlice.reducer; diff --git a/redux/slices/webService/gisStationsStatusDistrictSlice.js b/redux/slices/webService/gisStationsStatusDistrictSlice.js new file mode 100644 index 000000000..ce926a9d4 --- /dev/null +++ b/redux/slices/webService/gisStationsStatusDistrictSlice.js @@ -0,0 +1,35 @@ +// /redux/slices/webService/gisStationsStatusDistrictSlice.js +import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; +import { fetchGisStationsStatusDistrict } from "../../api/fromWebService/fetchGisStationsStatusDistrict"; + +export const fetchGisStationsStatusDistrictFromWebService = createAsyncThunk("gisStationsStatusDistrict/fetchGisStationsStatusDistrictFromWebService", async () => { + return fetchGisStationsStatusDistrict(); +}); + +const gisStationsStatusDistrictSlice = createSlice({ + name: "gisStationsStatusDistrict", + initialState: { + data: [], + status: "idle", + error: null, + }, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchGisStationsStatusDistrictFromWebService.pending, (state) => { + state.status = "loading"; + }) + .addCase(fetchGisStationsStatusDistrictFromWebService.fulfilled, (state, action) => { + state.status = "succeeded"; + state.data = action.payload; + }) + .addCase(fetchGisStationsStatusDistrictFromWebService.rejected, (state, action) => { + state.status = "failed"; + state.error = action.error.message; + }); + }, +}); + +export const selectGisStationsStatusDistrict = (state) => state.gisStationsStatusDistrict.data; + +export default gisStationsStatusDistrictSlice.reducer; diff --git a/redux/slices/webService/gisSystemStaticSlice.js b/redux/slices/webService/gisSystemStaticSlice.js new file mode 100644 index 000000000..5f82b93dc --- /dev/null +++ b/redux/slices/webService/gisSystemStaticSlice.js @@ -0,0 +1,32 @@ +// /redux/slices/webService/gisSystemStaticSlice.js +import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; +import { fetchGisSystemStatic } from "../../api/fromWebService/fetchGisSystemStatic"; + +export const fetchGisSystemStaticFromWebService = createAsyncThunk("gisSystemStatic/fetchGisSystemStaticFromWebService", async () => { + const response = await fetchGisSystemStatic(); + return response.Systems || []; // ✅ Hier sicherstellen, dass nur `Systems` gespeichert wird +}); + +const gisSystemStaticSlice = createSlice({ + name: "gisSystemStatic", + initialState: { + data: [], // ✅ Immer ein Array setzen + status: "idle", + error: null, + }, + reducers: { + setGisSystemStatic: (state, action) => { + state.data = action.payload.Systems || []; // ✅ Falls `Systems` fehlt, leeres Array setzen + }, + }, + extraReducers: (builder) => { + builder.addCase(fetchGisSystemStaticFromWebService.fulfilled, (state, action) => { + state.status = "succeeded"; + state.data = action.payload; // ✅ Jetzt sollte `data` direkt das `Systems`-Array enthalten + }); + }, +}); + +export const { setGisSystemStatic } = gisSystemStaticSlice.actions; +export default gisSystemStaticSlice.reducer; +export const selectGisSystemStatic = (state) => state.gisSystemStatic.data || []; diff --git a/redux/store.js b/redux/store.js index 7c4c501b5..03ffc2838 100644 --- a/redux/store.js +++ b/redux/store.js @@ -1,14 +1,31 @@ +// /redux/store.js import { configureStore } from "@reduxjs/toolkit"; import lineVisibilityReducer from "./slices/lineVisibilitySlice"; import currentPoiReducer from "./slices/currentPoiSlice"; -import gisStationsStaticDistrictReducer from "./slices/gisStationsStaticDistrictSlice"; import polylineLayerVisibleReducer from "./slices/polylineLayerVisibleSlice"; +import locationDevicesFromDBReducer from "./slices/db/locationDevicesFromDBSlice"; +import gisStationsStaticDistrictReducer from "./slices/webService/gisStationsStaticDistrictSlice"; +import gisStationsStatusDistrictReducer from "./slices/webService/gisStationsStatusDistrictSlice"; +import gisStationsMeasurementsReducer from "./slices/webService/gisStationsMeasurementsSlice"; +import gisSystemStaticReducer from "./slices/webService/gisSystemStaticSlice"; +import gisStationsStaticReducer from "./slices/webService/gisStationsStaticSlice"; +import poiTypesReducer from "./slices/db/poiTypesSlice"; +import addPoiOnPolylineReducer from "./slices/addPoiOnPolylineSlice"; +import polylineContextMenuReducer from "./slices/polylineContextMenuSlice"; export const store = configureStore({ reducer: { lineVisibility: lineVisibilityReducer, currentPoi: currentPoiReducer, - gisStationsStaticDistrict: gisStationsStaticDistrictReducer, polylineLayerVisible: polylineLayerVisibleReducer, + locationDevicesFromDB: locationDevicesFromDBReducer, + gisStationsStaticDistrict: gisStationsStaticDistrictReducer, + gisStationsStatusDistrict: gisStationsStatusDistrictReducer, + gisStationsMeasurements: gisStationsMeasurementsReducer, + gisSystemStatic: gisSystemStaticReducer, + gisStationsStatic: gisStationsStaticReducer, + poiTypes: poiTypesReducer, + addPoiOnPolyline: addPoiOnPolylineReducer, + polylineContextMenu: polylineContextMenuReducer, }, }); diff --git a/services/api/fetchGisStationsStaticDistrict.js b/services/api/fetchGisStationsStaticDistrict.js index 4c933ed9d..d11652bce 100644 --- a/services/api/fetchGisStationsStaticDistrict.js +++ b/services/api/fetchGisStationsStaticDistrict.js @@ -1,4 +1,4 @@ -import { setGisStationsStaticDistrict } from "../../redux/slices/gisStationsStaticDistrictSlice"; +import { setGisStationsStaticDistrict } from "../../redux/slices/webService/gisStationsStaticDistrictSlice"; export const fetchGisStationsStaticDistrict = async (url, dispatch, fetchOptions) => { try { diff --git a/utils/createAndSetDevices.js b/utils/createAndSetDevices.js index c592c5c53..646b5d51e 100644 --- a/utils/createAndSetDevices.js +++ b/utils/createAndSetDevices.js @@ -3,7 +3,7 @@ import L from "leaflet"; import "leaflet.smooth_marker_bouncing"; import { toast } from "react-toastify"; import * as config from "../config/config.js"; -import { disablePolylineEvents, enablePolylineEvents } from "./setupPolylines"; +import { disablePolylineEvents, enablePolylineEvents } from "./polylines/setupPolylines.js"; import { store } from "../redux/store"; import { updateLineStatus } from "../redux/slices/lineVisibilitySlice"; @@ -40,8 +40,8 @@ export const createAndSetDevices = async (systemId, setMarkersFunction, GisSyste if (config.isMockMode()) { console.log("⚠️ Mock-API: Geräte-Daten geladen"); - staticDistrictData = await fetchJsonSafely("/mockData/gisStationsStaticDistrictMock.json"); - statusDistrictData = await fetchJsonSafely("/mockData/gisStationsStatusDistrictMock.json"); + staticDistrictData = await fetchJsonSafely(config.mapGisStationsStaticDistrictUrl); + statusDistrictData = await fetchJsonSafely(config.mapGisStationsStatusDistrictUrl); } else { staticDistrictData = await fetchJsonSafely(config.mapGisStationsStaticDistrictUrl); statusDistrictData = await fetchJsonSafely(config.mapGisStationsStatusDistrictUrl); diff --git a/utils/markerUtils.js b/utils/markerUtils.js index da7417e3b..5c2b2b9ff 100644 --- a/utils/markerUtils.js +++ b/utils/markerUtils.js @@ -1,6 +1,7 @@ // /utils/markerUtils.js import circleIcon from "../components/CircleIcon"; -import { saveLineData, redrawPolyline } from "./mapUtils"; +import { saveLineData } from "./mapUtils"; +import { redrawPolyline } from "./mapUtils"; import L from "leaflet"; import { toast } from "react-toastify"; @@ -9,10 +10,7 @@ export const insertNewMarker = (closestPoints, newPoint, lineData, map) => { icon: circleIcon, draggable: true, }).addTo(map); - lineData.coordinates.splice(closestPoints[2], 0, [ - newPoint.lat, - newPoint.lng, - ]); + lineData.coordinates.splice(closestPoints[2], 0, [newPoint.lat, newPoint.lng]); // Hier direkt speichern nach Einfügen saveLineData(lineData); @@ -39,9 +37,7 @@ export const removeMarker = (marker, lineData, currentZoom, currentCenter) => { //localStorage.setItem("mapCenter", JSON.stringify(currentCenter)); // Find the index of the coordinate that matches the marker's position - const index = lineData.coordinates.findIndex((coord) => - L.latLng(coord[0], coord[1]).equals(marker.getLatLng()) - ); + const index = lineData.coordinates.findIndex((coord) => L.latLng(coord[0], coord[1]).equals(marker.getLatLng())); if (index !== -1) { // Remove the coordinate from the line data diff --git a/utils/poiUtils.js b/utils/poiUtils.js index 229e10a0b..0887d2b2f 100644 --- a/utils/poiUtils.js +++ b/utils/poiUtils.js @@ -1,6 +1,7 @@ // /utils/poiUtils.js import circleIcon from "../components/gisPolylines/icons/CircleIcon.js"; -import { saveLineData, redrawPolyline } from "./mapUtils.js"; +import { saveLineData } from "./mapUtils.js"; +import { redrawPolyline } from "./polylines/redrawPolyline.js"; import L from "leaflet"; import "leaflet.smooth_marker_bouncing"; import { toast } from "react-toastify"; diff --git a/utils/polylines/contextMenu.js b/utils/polylines/contextMenu.js new file mode 100644 index 000000000..4d4cf0343 --- /dev/null +++ b/utils/polylines/contextMenu.js @@ -0,0 +1,29 @@ +// /utils/polylines/contextMenu.js +export function closePolylineSelectionAndContextMenu(map) { + try { + if (window.selectedPolyline) { + window.selectedPolyline.setStyle({ weight: 3 }); + window.selectedPolyline = null; + } + + if (map?.contextmenu?.hide) { + map.contextmenu.hide(); + } + } catch (error) { + console.error("Fehler beim Schließen des Kontextmenüs:", error); + } + + localStorage.removeItem("contextMenuCountdown"); + localStorage.removeItem("contextMenuExpired"); +} + +export function monitorContextMenu(map) { + function checkAndClose() { + if (localStorage.getItem("contextMenuExpired") === "true") { + closePolylineSelectionAndContextMenu(map); + localStorage.removeItem("contextMenuExpired"); + } + setTimeout(checkAndClose, 1000); + } + checkAndClose(); +} diff --git a/utils/polylines/eventHandlers.js b/utils/polylines/eventHandlers.js new file mode 100644 index 000000000..c645ba2fd --- /dev/null +++ b/utils/polylines/eventHandlers.js @@ -0,0 +1,19 @@ +// /utils/polylines/eventHandlers.js +export function enablePolylineEvents(polylines, lineColors) { + if (!polylines || polylines.length === 0) { + //console.warn("Keine Polylinien vorhanden oder polylines ist undefined."); + return; + } + + polylines.forEach((polyline) => { + polyline.on("mouseover", () => polyline.setStyle({ weight: 14 })); + polyline.on("mouseout", () => polyline.setStyle({ weight: 3 })); + }); +} + +export function disablePolylineEvents(polylines) { + polylines.forEach((polyline) => { + polyline.off("mouseover"); + polyline.off("mouseout"); + }); +} diff --git a/utils/polylines/monitorContextMenu.js b/utils/polylines/monitorContextMenu.js new file mode 100644 index 000000000..026781aab --- /dev/null +++ b/utils/polylines/monitorContextMenu.js @@ -0,0 +1,21 @@ +// utils/polylines/monitorContextMenu.js +import { closePolylineSelectionAndContextMenu } from "./contextMenu"; + +export function monitorContextMenu(map) { + function checkAndClose() { + const isContextMenuExpired = localStorage.getItem("contextMenuExpired") === "true"; + + if (isContextMenuExpired) { + if (map && map.contextmenu && typeof map.contextmenu.hide === "function") { + closePolylineSelectionAndContextMenu(map); + localStorage.removeItem("contextMenuExpired"); + } else { + console.warn("Kontextmenü war nicht verfügbar und konnte nicht geschlossen werden."); + } + } + + setTimeout(checkAndClose, 1000); // **Recursive Timeout statt Intervall** + } + + checkAndClose(); +} diff --git a/utils/polylines/polylineSubscription.js b/utils/polylines/polylineSubscription.js new file mode 100644 index 000000000..1f6ba0fdf --- /dev/null +++ b/utils/polylines/polylineSubscription.js @@ -0,0 +1,17 @@ +// utils/polylines/polylineSubscription.js +import { store } from "../../redux/store"; +import { closePolylineContextMenu } from "../../redux/slices/polylineContextMenuSlice"; + +export function subscribeToPolylineContextMenu() { + store.subscribe(() => { + const state = store.getState(); // Redux-Toolkit empfohlene Methode + if (state.polylineContextMenu.forceClose) { + console.log("🚀 Redux-Event erkannt - Kontextmenü wird geschlossen."); + store.dispatch(closePolylineContextMenu()); + + if (window.map && window.map.contextmenu) { + window.map.contextmenu.hide(); + } + } + }); +} diff --git a/utils/polylines/redrawPolyline.js b/utils/polylines/redrawPolyline.js new file mode 100644 index 000000000..5dbfa7325 --- /dev/null +++ b/utils/polylines/redrawPolyline.js @@ -0,0 +1,35 @@ +// utils/redrawPolyline.js +export const redrawPolyline = (lineData, lineColors, tooltipContents, map) => { + if (!lineData || !lineColors || !tooltipContents || !map) { + console.error("Invalid parameters for redrawPolyline"); + return; + } + + if (!lineData.coordinates || !Array.isArray(lineData.coordinates)) { + console.error("Invalid coordinates in lineData"); + return; + } + + const color = lineColors[lineData.idModul] || "#000000"; + const tooltipContent = tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt"; + + if (lineData.polyline) map.removeLayer(lineData.polyline); + + lineData.polyline = L.polyline(lineData.coordinates, { + color: color, + }).addTo(map); + + lineData.polyline.bindTooltip(tooltipContent, { + permanent: false, + direction: "auto", + }); + + lineData.polyline.on("mouseover", () => { + lineData.polyline.setStyle({ weight: 10 }); + lineData.polyline.bringToFront(); + }); + + lineData.polyline.on("mouseout", () => { + lineData.polyline.setStyle({ weight: 5 }); + }); +}; diff --git a/utils/setupPolylines.js b/utils/polylines/setupPolylines.js similarity index 63% rename from utils/setupPolylines.js rename to utils/polylines/setupPolylines.js index d3e780525..cc310835b 100644 --- a/utils/setupPolylines.js +++ b/utils/polylines/setupPolylines.js @@ -1,91 +1,29 @@ -// utils/setupPolylines.js -import { findClosestPoints } from "./geometryUtils"; -import handlePoiSelect from "./handlePoiSelect"; -import { updateLocationInDatabase } from "../services/api/updateLocationInDatabase"; - -import { handleEditPoi, insertNewPOI, removePOI } from "./poiUtils"; -import { parsePoint } from "./geometryUtils"; -import circleIcon from "../components/gisPolylines/icons/CircleIcon"; -import startIcon from "../components/gisPolylines/icons/StartIcon"; -import endIcon from "../components/gisPolylines/icons/EndIcon"; -import { redrawPolyline } from "./mapUtils"; -import { openInNewTab } from "./openInNewTab"; +// utils/polylines/setupPolylines.js +import { findClosestPoints } from "../geometryUtils"; +import handlePoiSelect from "../handlePoiSelect"; +import { updateLocationInDatabase } from "../../services/api/updateLocationInDatabase"; +import { handleEditPoi, insertNewPOI, removePOI } from "../poiUtils"; +import { parsePoint } from "../geometryUtils"; +import circleIcon from "../../components/gisPolylines/icons/CircleIcon"; +import startIcon from "../../components/gisPolylines/icons/StartIcon"; +import endIcon from "../../components/gisPolylines/icons/EndIcon"; +import { redrawPolyline } from "./redrawPolyline"; +import { openInNewTab } from "../openInNewTab"; import { toast } from "react-toastify"; -import { polylineLayerVisibleState } from "../redux/slices/polylineLayerVisibleSlice"; -import { useRecoilValue } from "recoil"; -import { store } from "../redux/store"; // Importiere den Store - -// Funktion zum Deaktivieren der Polyline-Ereignisse -export function disablePolylineEvents(polylines) { - polylines.forEach((polyline) => { - polyline.off("mouseover"); - polyline.off("mouseout"); - }); -} - -// Funktion zum Aktivieren der Polyline-Ereignisse -export function enablePolylineEvents(polylines, lineColors) { - // Überprüfe, ob polylines definiert ist und ob es Elemente enthält - if (!polylines || polylines.length === 0) { - //console.warn("Keine Polylinien vorhanden oder polylines ist undefined."); - return; - } - - // Falls Polylinien vorhanden sind, wende die Events an - polylines.forEach((polyline) => { - polyline.on("mouseover", (e) => { - //console.log("Mouseover on polyline", polyline.options); - polyline.setStyle({ weight: 14 }); - const link = `${process.env.NEXT_PUBLIC_BASE_URL}cpl.aspx?id=${polyline.options.idLD}`; - //localStorage.setItem("lastElementType", "polyline"); - //localStorage.setItem("polylineLink", link); - }); - - polyline.on("mouseout", (e) => { - //console.log("Mouseout from polyline", polyline.options); - polyline.setStyle({ weight: 3 }); - }); - }); -} -// Funktion zum Schließen des Kontextmenüs und Entfernen der Markierung -function closePolylineSelectionAndContextMenu(map) { - try { - // Entferne alle markierten Polylinien - if (window.selectedPolyline) { - window.selectedPolyline.setStyle({ weight: 3 }); // Originalstil wiederherstellen - window.selectedPolyline = null; - } - - // Überprüfe, ob map und map.contextmenu definiert sind - if (map && map.contextmenu) { - map.contextmenu.hide(); // Kontextmenü schließen - } else { - console.warn("Kontextmenü ist nicht verfügbar."); - } - } catch (error) { - console.error("Fehler beim Schließen des Kontextmenüs:", error); - window.location.reload(); - } - - // Countdown-Status zurücksetzen - localStorage.removeItem("contextMenuCountdown"); - localStorage.removeItem("contextMenuExpired"); -} - -// Überprüft regelmäßig den Status in localStorage -function monitorContextMenu(map) { - setInterval(() => { - const isContextMenuExpired = localStorage.getItem("contextMenuExpired") === "true"; - if (isContextMenuExpired) { - closePolylineSelectionAndContextMenu(map); - localStorage.removeItem("contextMenuExpired"); // Flagge entfernen, um wiederverwendbar zu sein - } - }, 1000); // Alle 1 Sekunde überprüfen -} +import { polylineLayerVisibleState } from "../../redux/slices/polylineLayerVisibleSlice"; +import { store } from "../../redux/store"; // Importiere den Store +import { openAddPoiOnPolylineModal } from "../../redux/slices/addPoiOnPolylineSlice"; +import { openPolylineContextMenu, closePolylineContextMenu } from "../../redux/slices/polylineContextMenuSlice"; +import { enablePolylineEvents, disablePolylineEvents } from "./eventHandlers"; +import { closePolylineSelectionAndContextMenu } from "./contextMenu"; +import { monitorContextMenu } from "./monitorContextMenu"; +import { subscribeToPolylineContextMenu } from "./polylineSubscription"; +import { forceCloseContextMenu } from "../../redux/slices/polylineContextMenuSlice"; +//-------------------------------------------- export const setupPolylines = (map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, currentZoom, currentCenter, polylineVisible) => { if (!polylineVisible) { - console.warn("Polylines deaktiviert - keine Zeichnung"); + //console.warn("Polylines deaktiviert - keine Zeichnung"); return { markers: [], polylines: [] }; } @@ -284,14 +222,14 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents, callback: (e) => map.panTo(e.latlng), }, { separator: true }, - { + /* { text: "POI hinzufügen", icon: "/img/add_station.png", callback: (e) => { - // Hier kannst du die Logik für das Hinzufügen eines POIs implementieren - alert("POI hinzufügen an: " + e.latlng); + store.dispatch(openAddPoiOnPolylineModal(e.latlng)); }, }, + */ { text: "Stützpunkt hinzufügen", icon: "/img/icons/gisLines/add-support-point.svg", @@ -343,15 +281,14 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents, icon: "/img/center_focus.png", callback: (e) => map.panTo(e.latlng), }, - { separator: true }, - { + { separator: true } + /* { text: "POI hinzufügen", icon: "/img/add_station.png", callback: (e) => { - // Hier kannst du die Logik für das Hinzufügen eines POIs implementieren - alert("POI hinzufügen an: " + e.latlng); + store.dispatch(openAddPoiOnPolylineModal(e.latlng)); }, - } + } */ ); } @@ -363,56 +300,43 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents, polyline.on("mouseover", (e) => { const startTime = Date.now(); // Startzeit erfassen - localStorage.setItem("contextMenuStartTime", startTime); // Speichern in localStorage - // Starte einen Intervall-Timer, um die Differenz zu berechnen - /* const countdownInterval = setInterval(() => { - const currentTime = Date.now(); - const elapsedTime = (currentTime - startTime) / 1000; // Differenz in Sekunden - - // Speichern der abgelaufenen Zeit in localStorage - localStorage.setItem("contextMenuCountdown", elapsedTime); - - // Wenn die Zeit 17 Sekunden erreicht, schließe das Menü - if (elapsedTime >= 17) { - clearInterval(countdownInterval); - const contextMenu = map.contextmenu; // Zugriff auf das Kontextmenü - contextMenu.hide(); // Kontextmenü schließen - } - }, 1000); */ - // Jede Sekunde - //console.log("Mouseover on polyline", lineData); polyline.setStyle({ weight: 14 }); const link = `${process.env.NEXT_PUBLIC_BASE_URL}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`; - console.log("Link der Linie:", link); - //localStorage.setItem("lastElementType", "polyline"); - //localStorage.setItem("polylineLink", link); + // console.log("Link der Linie:", link); }); - + // error TypeError: Cannot read properties of null (reading 'contextmenu') wenn der Mas auf die Linie bleibt polyline.on("mouseout", (e) => { - // console.log("Mouseout from polyline", lineData); polyline.setStyle({ weight: 3 }); - // Setze den Countdown auf 0, wenn mouseout ausgelöst wird - localStorage.setItem("contextMenuCountdown", 0); - }); - // Speichere den Link bei einem Rechtsklick (Kontextmenü) - /* - polyline.on("contextmenu", (e) => { - const link = `${process.env.NEXT_PUBLIC_BASE_URL}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`; - console.log("Link der Linie (via Rechtsklick):", link); - localStorage.setItem("lastElementType", "polyline"); - localStorage.setItem("polylineLink", link); - }); - */ - // Starte den Timer zum Schließen des Kontextmenüs nach 15 Sekunden - polyline.on("contextmenu", function (e) { - const contextMenu = this._map.contextmenu; // Zugriff auf das Kontextmenü - const closeMenu = () => contextMenu.hide(); // Funktion zum Schließen des Menüs + //console.log("🚀 Maus hat die Polyline verlassen - Warten auf Klick außerhalb des Menüs."); - const countdown = parseInt(localStorage.getItem("contextMenuCountdown"), 30); - if (countdown >= 28) { - closeMenu(); - } + document.addEventListener("click", function handleOutsideClick(event) { + if (!event.target.closest(".leaflet-contextmenu")) { + //console.log("🛑 Klick außerhalb des Kontextmenüs erkannt - Schließe Menü."); + + try { + store.dispatch(closePolylineContextMenu()); + store.dispatch(forceCloseContextMenu()); + + if (window.map?.contextmenu) { + window.map.contextmenu.hide(); + } + } catch (error) { + console.error("❌ Fehler beim Schließen des Kontextmenüs:", error); + // **Seite NICHT sofort neuladen, sondern global unterdrücken lassen** + } + + document.removeEventListener("click", handleOutsideClick); + } + }); + }); + polyline.on("contextmenu", (e) => { + store.dispatch( + openPolylineContextMenu({ + position: { lat: e.latlng.lat, lng: e.latlng.lng }, + polylineId: polyline.options.idLD, + }) + ); }); polylines.push(polyline); diff --git a/utils/setupPOIs.js b/utils/setupPOIs.js index b4885bbfc..6789faa61 100644 --- a/utils/setupPOIs.js +++ b/utils/setupPOIs.js @@ -7,9 +7,9 @@ import { parsePoint } from "./geometryUtils"; import circleIcon from "../components/gisPolylines/icons/CircleIcon"; import startIcon from "../components/gisPolylines/icons/StartIcon"; import endIcon from "../components/gisPolylines/icons/EndIcon"; -import { redrawPolyline } from "./mapUtils"; +import { redrawPolyline } from "./polylines/redrawPolyline"; import { openInNewTab } from "../utils/openInNewTab"; -import { disablePolylineEvents, enablePolylineEvents } from "./setupPolylines"; // Importiere die Funktionen +import { disablePolylineEvents, enablePolylineEvents } from "./polylines/setupPolylines"; // Importiere die Funktionen export const setupPOIs = async ( map, @@ -83,7 +83,7 @@ export const setupPOIs = async ( `); marker.on("mouseover", function () { - console.log("Device Name:", marker); // Debugging + //console.log("Device Name:", marker); // Debugging handlePoiSelect( { id: location.idPoi,