feat: Healthcheck um Webservices, API-Routen und .env-Prüfungen erweitert

- Externe Webservices von TALAS V5 integriert und geprüft (Statuscode + Antwortstruktur)
- Eigene API-Endpunkte wie /api/talas_v5_DB/getDevices hinzugefügt und validiert
- Prüfung von NEXT_PUBLIC_USE_MOCKS zur Vermeidung von Mockdaten in Produktion
- Validierung der Umgebungsvariablen wie DB_HOST, DB_NAME und NODE_ENV ergänzt
- Response-Status 200 bei vollständigem Erfolg, 207 bei Teilfehlern
- Verbesserung der JSON-Antwortstruktur zur einfacheren Analyse
This commit is contained in:
ISA
2025-06-05 15:23:59 +02:00
parent 9273195d8f
commit ec31b36b3d
31 changed files with 397 additions and 163 deletions

View File

@@ -7,13 +7,13 @@ DB_NAME=talas_v5
DB_PORT=3306 DB_PORT=3306
# Public Settings (Client braucht IP/Domain) , Variablen mit dem Präfix "NEXT_PUBLIC" ist in Browser sichtbar # Public Settings (Client braucht IP/Domain) , Variablen mit dem Präfix "NEXT_PUBLIC" ist in Browser sichtbar
NEXT_PUBLIC_DEBUG_LOG=true NEXT_PUBLIC_DEBUG_LOG=false
#auf dem Entwicklungsrechner dev läuft auf Port 3000 und auf dem Server prod auf Port 80, aber der WebService ist immer auf PORT 80 #auf dem Entwicklungsrechner dev läuft auf Port 3000 und auf dem Server prod auf Port 80, aber der WebService ist immer auf PORT 80
NEXT_PUBLIC_API_PORT_MODE=prod NEXT_PUBLIC_API_PORT_MODE=prod
NEXT_PUBLIC_USE_MOCKS=false NEXT_PUBLIC_USE_MOCKS=true
# Der Unterordner talas5 gleich hinter der IP-Adresse (oder Servername) muss konfigurierbar sein. # Der Unterordner talas5 gleich hinter der IP-Adresse (oder Servername) muss konfigurierbar sein.
# Es muss auch möglich sein kein Unterorder anzugeben (z.B. nur http://talasserver/). # Es muss auch möglich sein kein Unterorder anzugeben (z.B. nur http://talasserver/).

View File

@@ -1,37 +0,0 @@
// components/TestScript.js
import { useEffect } from "react";
import setupPolylinesCode from "!!raw-loader!../utils/polylines/setupPolylines.js"; // Lädt die gesamte setupPolylines.js als Text
export default function TestScript() {
useEffect(() => {
// Regulärer Ausdruck für "Stützpunkt entfernen" im Kontextmenü
const removeRegex = /marker\.on\("mouseover", function \(\) {\s*this\.bindContextMenu\({\s*contextmenuItems: \[\s*\{\s*text: "Stützpunkt entfernen"/;
// Regulärer Ausdruck für "Stützpunkt hinzufügen" im Kontextmenü
const addRegex = /contextmenuItems: \[\s*\{\s*text: "Stützpunkt hinzufügen"/;
// Stilvorlagen für das Konsolen-Logging
const successStyle = "color: #fff; background-color: #28a745; padding: 4px 8px; font-size: 14px; border-radius: 4px;";
const failStyle = "color: #fff; background-color: #dc3545; padding: 4px 8px; font-size: 14px; border-radius: 4px;";
const neutralStyle = "color: #006400; font-size: 14px; background-color: #f0f0f0; padding: 4px 8px; border-radius: 4px;";
// Überprüfung für "Stützpunkt entfernen"
if (removeRegex.test(setupPolylinesCode)) {
console.log("%c✔ Test bestanden: Der Text für 'Stützpunkt entfernen' wurde gefunden.", successStyle);
} else {
console.log("%c✘ Test fehlgeschlagen: Der Text für 'Stützpunkt entfernen' wurde nicht gefunden.", failStyle);
}
// Überprüfung für "Stützpunkt hinzufügen"
if (addRegex.test(setupPolylinesCode)) {
console.log("%c✔ Test bestanden: Der Text für 'Stützpunkt hinzufügen' wurde gefunden.", successStyle);
} else {
//console.log("%c✘ Test fehlgeschlagen: Der Text für 'Stützpunkt hinzufügen' wurde nicht gefunden.", failStyle);
}
// Beispiel einer neutralen Nachricht (falls benötigt)
console.log("%c Info: Überprüfung abgeschlossen.", neutralStyle);
}, []);
return null; // Keine visuelle Ausgabe erforderlich
}

View File

@@ -12,7 +12,7 @@ const addItemsToMapContextMenu = (
setPopupCoordinates, setPopupCoordinates,
openPopupWithCoordinates // Hier wird die Funktion als Parameter hinzugefügt openPopupWithCoordinates // Hier wird die Funktion als Parameter hinzugefügt
) => { ) => {
const openPoiModal = (e) => { const openPoiModal = e => {
setShowCoordinatesModal(false); // ✅ Jetzt verfügbar, weil als Parameter übergeben setShowCoordinatesModal(false); // ✅ Jetzt verfügbar, weil als Parameter übergeben
setPopupCoordinates(e.latlng); setPopupCoordinates(e.latlng);
setShowPoiModal(true); setShowPoiModal(true);
@@ -29,7 +29,7 @@ const addItemsToMapContextMenu = (
map.contextmenu.addItem({ map.contextmenu.addItem({
text: "Reinzoomen", text: "Reinzoomen",
icon: "img/zoom_in.png", icon: "img/zoom_in.png",
callback: (e) => { callback: e => {
const currentZoom = map.getZoom(); const currentZoom = map.getZoom();
const newZoom = Math.min(15, currentZoom + 3); // Stellt sicher, dass max. 15 erreicht wird 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 zoomDifference = Math.abs(newZoom - currentZoom); // Anzahl der Zoom-Stufen
@@ -61,7 +61,7 @@ const addItemsToMapContextMenu = (
map.contextmenu.addItem({ map.contextmenu.addItem({
text: "Hier zentrieren", text: "Hier zentrieren",
icon: "img/center_focus.png", icon: "img/center_focus.png",
callback: (e) => { callback: e => {
map.panTo(e.latlng); map.panTo(e.latlng);
}, },
}); });
@@ -71,8 +71,9 @@ const addItemsToMapContextMenu = (
if (!menuItemAdded && map && map.contextmenu) { if (!menuItemAdded && map && map.contextmenu) {
const editMode = localStorage.getItem("editMode") === "true"; const editMode = localStorage.getItem("editMode") === "true";
if (editMode) { if (editMode) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("editMode localStorage:", localStorage.getItem("editMode")); console.log("editMode localStorage:", localStorage.getItem("editMode"));
//console.log("editMode:", editMode); }
map.contextmenu.addItem({ map.contextmenu.addItem({
text: "POI hinzufügen", text: "POI hinzufügen",

View File

@@ -148,7 +148,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
// Konstanten für die URLs // Konstanten für die URLs
//console.log("priorityConfig in MapComponent1: ", priorityConfig);
//----------------------------------------- //-----------------------------------------
const [linePositions, setLinePositions] = useState([]); const [linePositions, setLinePositions] = useState([]);
const { lineColors, tooltipContents } = useLineData(); const { lineColors, tooltipContents } = useLineData();
@@ -234,7 +233,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
} }
locations.forEach(location => {}); locations.forEach(location => {});
}; };
//console.log("trigger in MapComponent.js:", poiReadTrigger);
}, [map, locations, poiReadTrigger]); }, [map, locations, poiReadTrigger]);
//-------------------------------------------- //--------------------------------------------
@@ -275,7 +273,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
]); ]);
//--------------------------------------------- //---------------------------------------------
//console.log("priorityConfig in MapComponent2: ", priorityConfig);
useEffect(() => { useEffect(() => {
if (map) { if (map) {
} }
@@ -319,7 +317,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
); );
newPolylines.forEach((polyline, index) => { newPolylines.forEach((polyline, index) => {
//console.log("polyline: ", polyline);
const tooltipContent = const tooltipContent =
tooltipContents[`${linePositions[index].idLD}-${linePositions[index].idModul}`] || tooltipContents[`${linePositions[index].idLD}-${linePositions[index].idModul}`] ||
"Die Linie ist noch nicht in Webservice vorhanden oder bekommt keine Daten"; "Die Linie ist noch nicht in Webservice vorhanden oder bekommt keine Daten";
@@ -380,14 +377,18 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
//Test in useEffect //Test in useEffect
useEffect(() => { useEffect(() => {
if (map) { if (map) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🗺️ Map-Einstellungen werden wiederhergestellt..."); console.log("🗺️ Map-Einstellungen werden wiederhergestellt...");
}
restoreMapSettings(map); restoreMapSettings(map);
} }
}, [map]); }, [map]);
//-------------------------------------------- //--------------------------------------------
useEffect(() => { useEffect(() => {
if (map) { if (map) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("map in MapComponent: ", map); console.log("map in MapComponent: ", map);
}
const handleMapMoveEnd = event => { const handleMapMoveEnd = event => {
const newCenter = map.getCenter(); const newCenter = map.getCenter();
const newZoom = map.getZoom(); const newZoom = map.getZoom();
@@ -411,8 +412,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
//-------------------------------------------- //--------------------------------------------
// Area in DataSheet ->dropdownmenu // Area in DataSheet ->dropdownmenu
useEffect(() => { useEffect(() => {
//console.log("🔍 GisStationsStaticDistrict Inhalt:", GisStationsStaticDistrict);
// Sicherstellen, dass `Points` existiert und ein Array ist // Sicherstellen, dass `Points` existiert und ein Array ist
const points = GisStationsStaticDistrict?.Points; const points = GisStationsStaticDistrict?.Points;
@@ -420,7 +419,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
const station = points.find(s => s.Area_Name === selectedArea); const station = points.find(s => s.Area_Name === selectedArea);
if (station) { if (station) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("📌 Gefundene Station:", station); console.log("📌 Gefundene Station:", station);
}
map.flyTo([station.X, station.Y], 14); map.flyTo([station.X, station.Y], 14);
} else { } else {
console.warn("⚠️ Keine passende Station für die Area gefunden:", selectedArea); console.warn("⚠️ Keine passende Station für die Area gefunden:", selectedArea);
@@ -464,8 +465,10 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
//-------------------------------------------- //--------------------------------------------
useEffect(() => { useEffect(() => {
if (map) { if (map) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("6- Karteninstanz (map) wurde jetzt erfolgreich initialisiert"); console.log("6- Karteninstanz (map) wurde jetzt erfolgreich initialisiert");
} }
}
}, [map]); }, [map]);
//-------------------------------------------- //--------------------------------------------
useEffect(() => { useEffect(() => {
@@ -474,7 +477,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
map.whenReady(() => { map.whenReady(() => {
setTimeout(() => { setTimeout(() => {
if (map.contextmenu) { if (map.contextmenu) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
//console.log("Contextmenu ist vorhanden"); //console.log("Contextmenu ist vorhanden");
}
} else { } else {
console.warn("Contextmenu ist nicht verfügbar."); console.warn("Contextmenu ist nicht verfügbar.");
} }
@@ -499,7 +504,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
const handleLocationUpdate = async (idLocation, idMap, newCoords) => { const handleLocationUpdate = async (idLocation, idMap, newCoords) => {
try { try {
await dispatch(updateAreaThunk({ idLocation, idMap, newCoords })).unwrap(); await dispatch(updateAreaThunk({ idLocation, idMap, newCoords })).unwrap();
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Koordinaten erfolgreich aktualisiert:", result); console.log("Koordinaten erfolgreich aktualisiert:", result);
}
} catch (error) { } catch (error) {
console.error("Fehler beim Aktualisieren der Location:", error); console.error("Fehler beim Aktualisieren der Location:", error);
} }
@@ -661,15 +668,15 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
//-------------------------------------- //--------------------------------------
useEffect(() => { useEffect(() => {
if (isPolylineContextMenuOpen && countdownActive) { if (isPolylineContextMenuOpen && countdownActive) {
//console.log("🔄 Starte Redux-Countdown für Kontextmenü!");
const interval = setInterval(() => { const interval = setInterval(() => {
dispatch(updateCountdown()); dispatch(updateCountdown());
// console.log(`⏳ Redux Countdown: ${countdown} Sekunden`); // console.log(`⏳ Redux Countdown: ${countdown} Sekunden`);
if (countdown <= 2) { if (countdown <= 2) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🚀 Kontextmenü wird wegen Countdown < 2 geschlossen."); console.log("🚀 Kontextmenü wird wegen Countdown < 2 geschlossen.");
}
dispatch(closePolylineContextMenu()); dispatch(closePolylineContextMenu());
if (window.map?.contextmenu) { if (window.map?.contextmenu) {
@@ -690,8 +697,10 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
useEffect(() => { useEffect(() => {
if (map) { if (map) {
window.map = map; window.map = map;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("✅ window.map wurde gesetzt:", window.map); console.log("✅ window.map wurde gesetzt:", window.map);
} }
}
}, [map]); }, [map]);
//--------------------------------------- //---------------------------------------
@@ -756,7 +765,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
// 🧠 Optional für Debugging für überlappende Markers // 🧠 Optional für Debugging für überlappende Markers
useEffect(() => { useEffect(() => {
if (oms) { if (oms) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("📌 OMS ready:", oms); console.log("📌 OMS ready:", oms);
}
window.oms = oms; // Für Debugging global window.oms = oms; // Für Debugging global
} }
}, [oms]); }, [oms]);
@@ -764,7 +775,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
//---------------------------------------------- //----------------------------------------------
useEffect(() => { useEffect(() => {
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
alert("🚧 Development Mode aktiviert Mock-Daten werden verwendet!"); console.log("🚧 Development Mode aktiviert Mock-Daten werden verwendet!");
} else {
console.log("Production Mode aktiviert");
} }
}, []); }, []);
//--------------------------------------------- //---------------------------------------------

View File

@@ -143,7 +143,9 @@ function MapLayersControlPanel() {
//------------------------------ //------------------------------
useEffect(() => { useEffect(() => {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🔍 GisStationsStaticDistrict Inhalt:", GisStationsStaticDistrict); console.log("🔍 GisStationsStaticDistrict Inhalt:", GisStationsStaticDistrict);
}
if (!GisStationsStaticDistrict) { if (!GisStationsStaticDistrict) {
console.warn("⚠️ GisStationsStaticDistrict ist `null` oder nicht geladen."); console.warn("⚠️ GisStationsStaticDistrict ist `null` oder nicht geladen.");
@@ -172,8 +174,9 @@ function MapLayersControlPanel() {
} }
return isUnique; return isUnique;
}); });
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("📌 stationListing aktualisiert:", filteredAreas); console.log("📌 stationListing aktualisiert:", filteredAreas);
}
}, [GisStationsStaticDistrict, GisSystemStatic]); }, [GisStationsStaticDistrict, GisSystemStatic]);
//--------------------------- //---------------------------

View File

@@ -1,2 +1,2 @@
// /config/appVersion // /config/appVersion
export const APP_VERSION = "1.1.235"; export const APP_VERSION = "1.1.236";

View File

@@ -90,7 +90,9 @@ const useAreaMarkersLayer = (map, oms, apiUrl, onUpdateSuccess) => {
newCoords: { x: lat, y: lng }, newCoords: { x: lat, y: lng },
}) })
).unwrap(); ).unwrap();
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("✔️ Koordinaten erfolgreich aktualisiert:", { lat, lng }); console.log("✔️ Koordinaten erfolgreich aktualisiert:", { lat, lng });
}
onUpdateSuccess?.(); // optionaler Callback onUpdateSuccess?.(); // optionaler Callback
} catch (error) { } catch (error) {
console.error("❌ Fehler beim Aktualisieren der Koordinaten:", error); console.error("❌ Fehler beim Aktualisieren der Koordinaten:", error);

View File

@@ -62,7 +62,7 @@ export class OverlappingMarkerSpiderfier {
} }
nearbyMarkers(marker) { nearbyMarkers(marker) {
return this.markers.filter((m) => { return this.markers.filter(m => {
const distance = this.map.distance(marker.getLatLng(), m.getLatLng()); const distance = this.map.distance(marker.getLatLng(), m.getLatLng());
return distance < this.nearbyDistance && marker !== m; return distance < this.nearbyDistance && marker !== m;
}); });
@@ -74,7 +74,10 @@ export class OverlappingMarkerSpiderfier {
markers.forEach((marker, i) => { markers.forEach((marker, i) => {
const angle = this.circleStartAngle + (i * 2 * Math.PI) / markers.length; const angle = this.circleStartAngle + (i * 2 * Math.PI) / markers.length;
const legLength = this.circleFootSeparation * (2 + i / 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); const newLatLng = this.map.layerPointToLatLng(newPt);
if (!marker._oms) { if (!marker._oms) {
@@ -99,7 +102,7 @@ export class OverlappingMarkerSpiderfier {
//--------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------
unspiderfy() { unspiderfy() {
this.markers.forEach((marker) => { this.markers.forEach(marker => {
if (marker._oms && marker._oms.spidered) { if (marker._oms && marker._oms.spidered) {
// Falls eine Linie existiert, entferne sie aus der Karte // Falls eine Linie existiert, entferne sie aus der Karte
if (marker._oms.leg) { if (marker._oms.leg) {
@@ -115,7 +118,9 @@ export class OverlappingMarkerSpiderfier {
// 🔥 Künstliches Click-Event auslösen, um die UI zu aktualisieren // 🔥 Künstliches Click-Event auslösen, um die UI zu aktualisieren
setTimeout(() => { setTimeout(() => {
this.map.fire("click"); this.map.fire("click");
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Click-Event ausgelöst in OverlappingMarkerspiderfier.js in unspiderfy "); console.log("Click-Event ausgelöst in OverlappingMarkerspiderfier.js in unspiderfy ");
}
}, 10); // Kurze Verzögerung, um sicherzustellen, dass die UI neu gerendert wird }, 10); // Kurze Verzögerung, um sicherzustellen, dass die UI neu gerendert wird
} }

133
pages/api/health.js Normal file
View File

@@ -0,0 +1,133 @@
// /pages/api/health.js
export default async function handler(req, res) {
const basePath = "talas5";
const protocol = "http";
const hostname = "10.10.0.70";
const port = "80";
const idMap = "12";
const idUser = "484";
const idLD = "50922";
const buildUrl = method =>
`${protocol}://${hostname}:${port}/${basePath}/ClientData/WebServiceMap.asmx/${method}?idMap=${idMap}&idUser=${idUser}`;
const externalUrls = {
GisStationsStaticDistrict: buildUrl("GisStationsStaticDistrict"),
GisLinesStatus: `${protocol}://${hostname}:${port}/${basePath}/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`,
GisStationsMeasurements: buildUrl("GisStationsMeasurements"),
GisStationsStatusDistrict: buildUrl("GisStationsStatusDistrict"),
GisSystemStatic: buildUrl("GisSystemStatic"),
};
const internalApiBase = "http://localhost:3000";
const internalApis = {
//area
readArea: `${internalApiBase}/api/talas_v5_DB/area/readArea?m=${idMap}`,
//device
getAllStationsNames: `${internalApiBase}/api/talas_v5_DB/device/getAllStationsNames`,
getDevices: `${internalApiBase}/api/talas_v5_DB/device/getDevices`,
//gisLines
readGisLines: `${internalApiBase}/api/talas_v5_DB/gisLines/readGisLines`,
//locationDevice
getDeviceId: `${internalApiBase}/api/talas_v5_DB/locationDevice/getDeviceId`,
locationDeviceNameById: `${internalApiBase}/api/talas_v5_DB/locationDevice/locationDeviceNameById?idLD=${idLD}`,
locationDevices: `${internalApiBase}/api/talas_v5_DB/locationDevice/locationDevices`,
//pois
addPoi: `${internalApiBase}/api/talas_v5_DB/pois/addPoi`,
deletePoi: `${internalApiBase}/api/talas_v5_DB/pois/deletePoi`,
getPoiById: `${internalApiBase}/api/talas_v5_DB/pois/getPoiById`,
poiIcons: `${internalApiBase}/api/talas_v5_DB/pois/poi-icons`,
readAllPOIs: `${internalApiBase}/api/talas_v5_DB/pois/readAllPOIs`,
updateLocation: `${internalApiBase}/api/talas_v5_DB/pois/updateLocation`,
updatePoi: `${internalApiBase}/api/talas_v5_DB/pois/updatePoi`,
//poiTyp
readPoiTyp: `${internalApiBase}/api/talas_v5_DB/poiTyp/readPoiTyp`,
//station
getAllStationsNames: `${internalApiBase}/api/talas_v5_DB/station/getAllStationsNames`,
getDevices: `${internalApiBase}/api/talas_v5_DB/station/getDevices`,
//
priorityConfig: `${internalApiBase}/api/talas_v5_DB/priorityConfig`,
};
const results = {};
// Prüfe externe Webservices
await Promise.all(
Object.entries(externalUrls).map(async ([name, url]) => {
try {
const response = await fetch(url);
results[name] = {
ok: response.ok,
status: response.status,
url,
};
if (name === "GisSystemStatic" && response.ok) {
const data = await response.json();
results["UserRights"] = {
ok: Array.isArray(data.Rights),
length: data.Rights?.length || 0,
};
}
} catch (error) {
results[name] = {
ok: false,
error: error.message,
url,
};
}
})
);
// Prüfe interne API-Routen
await Promise.all(
Object.entries(internalApis).map(async ([name, url]) => {
try {
const response = await fetch(url);
results[`API_${name}`] = {
ok: response.ok,
status: response.status,
url,
};
} catch (error) {
results[`API_${name}`] = {
ok: false,
error: error.message,
url,
};
}
})
);
// Prüfe Mock-Status
const useMocksEnv = process.env.NEXT_PUBLIC_USE_MOCKS;
results["MockMode"] = {
expected: "false",
actual: useMocksEnv,
ok: useMocksEnv === "false",
info:
useMocksEnv === "false"
? "✅ Mockdaten deaktiviert Live-Daten aktiv."
: "⚠️ Mockdaten aktiv nicht für Produktion geeignet!",
};
// Prüfe Konfiguration der .env.production
results["envConfig"] = {
NODE_ENV: process.env.NODE_ENV || "undefined",
DB_HOST: process.env.DB_HOST || "❌ fehlt",
NEXT_PUBLIC_USE_MOCKS: useMocksEnv || "❌ fehlt",
status:
process.env.NODE_ENV === "production" && useMocksEnv === "false" && process.env.DB_HOST
? "✅ .env.production scheint korrekt."
: "⚠️ Bitte .env.production prüfen möglicherweise fehlt etwas.",
};
const allOk = Object.values(results).every(r => r.ok);
res.status(allOk ? 200 : 207).json({
status: allOk ? "ok" : "partial",
version: "1.0.0",
services: results,
});
}

BIN
pages/api/talas_v5_DB.zip Normal file

Binary file not shown.

View File

@@ -2,7 +2,9 @@
import getPool from "../../../../utils/mysqlPool"; import getPool from "../../../../utils/mysqlPool";
export default async function handler(req, res) { export default async function handler(req, res) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Request erhalten:", req.method, req.body); // Debugging console.log("Request erhalten:", req.method, req.body); // Debugging
}
const pool = getPool(); const pool = getPool();
@@ -15,7 +17,9 @@ export default async function handler(req, res) {
const { idLocation, idMap, x, y } = req.body; const { idLocation, idMap, x, y } = req.body;
if (!idLocation || !idMap || x === undefined || y === undefined) { if (!idLocation || !idMap || x === undefined || y === undefined) {
return res.status(400).json({ error: "Alle Felder (idLocation, idMap, x, y) sind erforderlich" }); return res
.status(400)
.json({ error: "Alle Felder (idLocation, idMap, x, y) sind erforderlich" });
} }
let connection; let connection;
@@ -23,18 +27,25 @@ export default async function handler(req, res) {
try { try {
// Verbindung zur Datenbank herstellen // Verbindung zur Datenbank herstellen
connection = await pool.getConnection(); connection = await pool.getConnection();
const query = "UPDATE location_coordinates SET x = ?, y = ? WHERE idLocation = ? AND idMaps = ?"; const query =
"UPDATE location_coordinates SET x = ?, y = ? WHERE idLocation = ? AND idMaps = ?";
const [result] = await connection.query(query, [x, y, idLocation, idMap]); const [result] = await connection.query(query, [x, y, idLocation, idMap]);
// Erfolgreiche Aktualisierung prüfen // Erfolgreiche Aktualisierung prüfen
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return res.status(200).json({ success: true, message: "Koordinaten erfolgreich aktualisiert" }); return res
.status(200)
.json({ success: true, message: "Koordinaten erfolgreich aktualisiert" });
} else { } else {
return res.status(404).json({ error: "Kein Eintrag gefunden, der aktualisiert werden konnte" }); return res
.status(404)
.json({ error: "Kein Eintrag gefunden, der aktualisiert werden konnte" });
} }
} catch (error) { } catch (error) {
console.error("Fehler beim Aktualisieren der Koordinaten:", error); console.error("Fehler beim Aktualisieren der Koordinaten:", error);
return res.status(500).json({ error: "Interner Serverfehler beim Aktualisieren der Koordinaten" }); return res
.status(500)
.json({ error: "Interner Serverfehler beim Aktualisieren der Koordinaten" });
} finally { } finally {
if (connection) { if (connection) {
connection.release(); connection.release();

View File

@@ -1,5 +1,5 @@
// /pages/api/talas_v5_DB/device/getDevices.js // /pages/api/talas_v5_DB/device/getDevices.js
import getPool from "../../../../utils/mysqlPool"; // Import Singleton-Pool import getPool from "@/utils/mysqlPool"; // Import Singleton-Pool
// API-Handler // API-Handler
export default async function handler(req, res) { export default async function handler(req, res) {

View File

@@ -13,9 +13,12 @@ export default async function handler(req, res) {
return res.status(400).json({ error: "Fehlende Daten" }); return res.status(400).json({ error: "Fehlende Daten" });
} }
const newLineString = `LINESTRING(${newCoordinates.map((coord) => `${coord[0]} ${coord[1]}`).join(",")})`; const newLineString = `LINESTRING(${newCoordinates
.map(coord => `${coord[0]} ${coord[1]}`)
.join(",")})`;
const query = "UPDATE talas_v5.gis_lines SET points = ST_GeomFromText(?) WHERE idLD = ? AND idModul = ?;"; const query =
"UPDATE talas_v5.gis_lines SET points = ST_GeomFromText(?) WHERE idLD = ? AND idModul = ?;";
let connection; let connection;
@@ -31,8 +34,9 @@ export default async function handler(req, res) {
// Commit der Transaktion // Commit der Transaktion
await connection.commit(); await connection.commit();
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Transaction Complete."); console.log("Transaction Complete.");
}
res.status(200).json({ res.status(200).json({
success: "Updated successfully.", success: "Updated successfully.",
affectedRows: results.affectedRows, affectedRows: results.affectedRows,

View File

@@ -6,9 +6,12 @@ export default async function handler(req, res) {
if (req.method === "POST") { if (req.method === "POST") {
const { name, poiTypeId, latitude, longitude, idLD } = req.body; const { name, poiTypeId, latitude, longitude, idLD } = req.body;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Received data:", req.body); // Überprüfen der empfangenen Daten console.log("Received data:", req.body); // Überprüfen der empfangenen Daten
}
const query = "INSERT INTO poi (description, idPoiTyp, position, idLD) VALUES (?, ?, ST_GeomFromText(?),?)"; const query =
"INSERT INTO poi (description, idPoiTyp, position, idLD) VALUES (?, ?, ST_GeomFromText(?),?)";
const point = `POINT(${longitude} ${latitude})`; const point = `POINT(${longitude} ${latitude})`;
const values = [name, poiTypeId, point, idLD]; const values = [name, poiTypeId, point, idLD];

View File

@@ -9,15 +9,16 @@ import { addPoiThunk } from "../redux/thunks/database/pois/addPoiThunk";
import { selectPoiMarkers } from "../redux/slices/database/pois/poiMarkersSlice"; import { selectPoiMarkers } from "../redux/slices/database/pois/poiMarkersSlice";
import { selectAddPoiStatus, selectAddPoiError } from "../redux/slices/database/pois/addPoiSlice"; import { selectAddPoiStatus, selectAddPoiError } from "../redux/slices/database/pois/addPoiSlice";
const MapComponentWithNoSSR = dynamic(() => import("../components/mainComponent/MapComponent"), { ssr: false }); const MapComponentWithNoSSR = dynamic(() => import("../components/mainComponent/MapComponent"), {
const TestScriptWithNoSSR = dynamic(() => import("../components/TestScript"), { ssr: false }); ssr: false,
});
export default function Home() { export default function Home() {
const dispatch = useDispatch(); const dispatch = useDispatch();
// Redux State // Redux State
const locations = useSelector(selectPoiMarkers); const locations = useSelector(selectPoiMarkers);
const poiReadTrigger = useSelector((state) => state.poiReadFromDbTrigger.trigger); const poiReadTrigger = useSelector(state => state.poiReadFromDbTrigger.trigger);
const addPoiStatus = useSelector(selectAddPoiStatus); const addPoiStatus = useSelector(selectAddPoiStatus);
const addPoiError = useSelector(selectAddPoiError); const addPoiError = useSelector(selectAddPoiError);
@@ -27,7 +28,7 @@ export default function Home() {
// URL-Parameter auslesen und POIs laden // URL-Parameter auslesen und POIs laden
useEffect(() => { useEffect(() => {
const getURLParameter = (name) => { const getURLParameter = name => {
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
return params.get(name); return params.get(name);
}; };
@@ -58,7 +59,6 @@ export default function Home() {
return ( return (
<div> <div>
<MapComponentWithNoSSR locations={locations} onAddLocation={handleAddLocation} /> <MapComponentWithNoSSR locations={locations} onAddLocation={handleAddLocation} />
<TestScriptWithNoSSR />
{addPoiStatus === "failed" && <p className="text-red-600"> Fehler: {addPoiError}</p>} {addPoiStatus === "failed" && <p className="text-red-600"> Fehler: {addPoiError}</p>}
</div> </div>

View File

@@ -31,5 +31,6 @@ const newContent = content.replace(versionRegex, `export const APP_VERSION = "${
// Datei speichern // Datei speichern
fs.writeFileSync(versionFilePath, newContent, "utf8"); fs.writeFileSync(versionFilePath, newContent, "utf8");
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log(`✅ Version erhöht auf: ${newVersion}`); console.log(`✅ Version erhöht auf: ${newVersion}`);
}

BIN
services/database.zip Normal file

Binary file not shown.

View File

@@ -3,7 +3,11 @@ export const fetchGisLinesStatusService = async () => {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
if (useMocks) { if (useMocks) {
console.log("🧪 Mock-Modus aktiviert: fetchGisLinesStatusService"); const mockBasePath = "/api/mocks/webservice/gisLinesStatus";
const mockURL = `${window.location.origin}${mockBasePath}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🧪 Mock-Modus aktiviert: fetchGisLinesStatusService ", mockURL);
}
const response = await fetch("/api/mocks/webservice/gisLinesStatus"); const response = await fetch("/api/mocks/webservice/gisLinesStatus");
if (!response.ok) { if (!response.ok) {
@@ -24,7 +28,9 @@ export const fetchGisLinesStatusService = async () => {
const idMap = params.get("m"); const idMap = params.get("m");
const url = `${baseUrl}/GisLinesStatus?idMap=${idMap}`; const url = `${baseUrl}/GisLinesStatus?idMap=${idMap}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("📡 fetchGisLinesStatusService URL:", url); console.log("📡 fetchGisLinesStatusService URL:", url);
}
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {

View File

@@ -3,7 +3,11 @@ export const fetchGisStationsMeasurementsService = async () => {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
if (useMocks) { if (useMocks) {
console.log("🧪 Mock-Modus aktiviert: fetchGisStationsMeasurementsService"); const mockBasePath = "/api/mocks/webservice/gisStationsMeasurements";
const mockURL = `${window.location.origin}${mockBasePath}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🧪 Mock-Modus aktiviert: fetchGisStationsMeasurementsService ", mockURL);
}
const response = await fetch("/api/mocks/webservice/gisStationsMeasurements"); const response = await fetch("/api/mocks/webservice/gisStationsMeasurements");
if (!response.ok) { if (!response.ok) {
@@ -24,7 +28,9 @@ export const fetchGisStationsMeasurementsService = async () => {
const idUser = params.get("u"); const idUser = params.get("u");
const url = `${baseUrl}/GisStationsMeasurements?idMap=${idMap}&idUser=${idUser}`; const url = `${baseUrl}/GisStationsMeasurements?idMap=${idMap}&idUser=${idUser}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("📡 fetchGisStationsMeasurementsService URL:", url); console.log("📡 fetchGisStationsMeasurementsService URL:", url);
}
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {

View File

@@ -10,7 +10,11 @@ export const fetchGisStationsStaticDistrictService = async () => {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
if (useMocks) { if (useMocks) {
console.log("🧪 Mock-Modus aktiviert: fetchGisStationsStaticDistrictService"); const mockBasePath = "/api/mocks/webservice/gisStationsStaticDistrict";
const mockURL = `${window.location.origin}${mockBasePath}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🧪 Mock-Modus aktiviert: fetchGisStationsStaticDistrictService ", mockURL);
}
const res = await fetch("/api/mocks/webservice/gisStationsStaticDistrict"); const res = await fetch("/api/mocks/webservice/gisStationsStaticDistrict");
if (!res.ok) { if (!res.ok) {
@@ -31,7 +35,9 @@ export const fetchGisStationsStaticDistrictService = async () => {
const idUser = params.get("u"); const idUser = params.get("u");
const url = `${baseUrl}/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`; const url = `${baseUrl}/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("📡 fetchGisStationsStaticDistrictService URL:", url); console.log("📡 fetchGisStationsStaticDistrictService URL:", url);
}
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {

View File

@@ -10,7 +10,11 @@ export const fetchGisStationsStatusDistrictService = async () => {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
if (useMocks) { if (useMocks) {
console.log("🧪 Mock-Modus aktiviert: fetchGisStationsStatusDistrictService"); const mockBasePath = "/api/mocks/webservice/gisStationsStatusDistrict";
const mockURL = `${window.location.origin}${mockBasePath}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🧪 Mock-Modus aktiviert: fetchGisStationsStatusDistrictService ", mockURL);
}
const response = await fetch("/api/mocks/webservice/gisStationsStatusDistrict"); const response = await fetch("/api/mocks/webservice/gisStationsStatusDistrict");
if (!response.ok) { if (!response.ok) {
@@ -31,7 +35,9 @@ export const fetchGisStationsStatusDistrictService = async () => {
const idUser = params.get("u"); const idUser = params.get("u");
const url = `${baseUrl}/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`; const url = `${baseUrl}/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("📡 fetchGisStationsStatusDistrictService URL:", url); console.log("📡 fetchGisStationsStatusDistrictService URL:", url);
}
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {

View File

@@ -9,7 +9,11 @@ export const fetchGisSystemStaticService = async () => {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
if (useMocks) { if (useMocks) {
console.log("🧪 Mock-Modus aktiviert: fetchGisSystemStaticService"); const mockBasePath = "/api/mocks/webservice/gisSystemStatic";
const mockURL = `${window.location.origin}${mockBasePath}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🧪 Mock-Modus aktiviert: fetchGisSystemStaticService ", mockURL);
}
const response = await fetch("/api/mocks/webservice/gisSystemStatic "); const response = await fetch("/api/mocks/webservice/gisSystemStatic ");
if (!response.ok) { if (!response.ok) {
@@ -30,7 +34,9 @@ export const fetchGisSystemStaticService = async () => {
const idUser = params.get("u"); const idUser = params.get("u");
const url = `${baseUrl}/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`; const url = `${baseUrl}/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("📡 fetchGisSystemStaticService von service URL:", url); console.log("📡 fetchGisSystemStaticService von service URL:", url);
}
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {

View File

@@ -9,7 +9,11 @@ export const fetchUserRightsService = async () => {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
if (useMocks) { if (useMocks) {
console.log("🧪 Mock-Modus aktiviert: fetchUserRightsService"); const mockBasePath = "/api/mocks/webservice/gisSystemStatic";
const mockURL = `${window.location.origin}${mockBasePath}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🧪 Mock-Modus aktiviert: fetchUserRightsService ", mockURL);
}
const response = await fetch("/api/mocks/webservice/gisSystemStatic "); //gisSystemStatic enthält die Systeme (Systems) und die User Rechte (Rights) const response = await fetch("/api/mocks/webservice/gisSystemStatic "); //gisSystemStatic enthält die Systeme (Systems) und die User Rechte (Rights)
if (!response.ok) { if (!response.ok) {
@@ -26,7 +30,9 @@ export const fetchUserRightsService = async () => {
const idUser = params.get("u"); const idUser = params.get("u");
const url = `${baseUrl}/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`; const url = `${baseUrl}/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🔍 Rechte-Fetch URL:", url); console.log("🔍 Rechte-Fetch URL:", url);
}
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: "GET",
@@ -40,7 +46,9 @@ export const fetchUserRightsService = async () => {
} }
const json = await response.json(); const json = await response.json();
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("👤 Rechte-Response JSON:", json); console.log("👤 Rechte-Response JSON:", json);
}
return json.Rights || []; return json.Rights || [];
} }

View File

@@ -5,7 +5,15 @@ import "leaflet/dist/leaflet.css";
import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
import "overlapping-marker-spiderfier-leaflet"; import "overlapping-marker-spiderfier-leaflet";
export const initializeMap = (mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled) => { export const initializeMap = (
mapRef,
setMap,
setOms,
setMenuItemAdded,
addItemsToMapContextMenu,
hasRights,
setPolylineEventsDisabled
) => {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH; const basePath = process.env.NEXT_PUBLIC_BASE_PATH;
if (!mapRef.current) { if (!mapRef.current) {
@@ -14,7 +22,9 @@ export const initializeMap = (mapRef, setMap, setOms, setMenuItemAdded, addItems
} }
if (mapRef.current._leaflet_id) { if (mapRef.current._leaflet_id) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("⚠️ Karte bereits initialisiert"); console.log("⚠️ Karte bereits initialisiert");
}
return; return;
} }

View File

@@ -2,7 +2,7 @@
import L from "leaflet"; import L from "leaflet";
// Call this function on page load to restore zoom and center // Call this function on page load to restore zoom and center
export const restoreMapSettings = (map) => { export const restoreMapSettings = map => {
const savedZoom = localStorage.getItem("mapZoom"); const savedZoom = localStorage.getItem("mapZoom");
const savedCenter = localStorage.getItem("mapCenter"); const savedCenter = localStorage.getItem("mapCenter");
@@ -29,7 +29,7 @@ export const checkOverlappingMarkers = (map, markers, plusIcon, oms) => {
const overlappingGroups = {}; const overlappingGroups = {};
markers.forEach((marker) => { markers.forEach(marker => {
if (map.hasLayer(marker)) { if (map.hasLayer(marker)) {
const latlngStr = marker.getLatLng().toString(); const latlngStr = marker.getLatLng().toString();
if (overlappingGroups[latlngStr]) { if (overlappingGroups[latlngStr]) {
@@ -40,7 +40,7 @@ export const checkOverlappingMarkers = (map, markers, plusIcon, oms) => {
} }
}); });
plusMarkers.forEach((plusMarker) => map.removeLayer(plusMarker)); plusMarkers.forEach(plusMarker => map.removeLayer(plusMarker));
plusMarkers = []; plusMarkers = [];
for (const coords in overlappingGroups) { for (const coords in overlappingGroups) {
@@ -62,18 +62,26 @@ export const checkOverlappingMarkers = (map, markers, plusIcon, oms) => {
export const handlePlusIconClick = (map, markers, oms, clickedLatLng) => { export const handlePlusIconClick = (map, markers, oms, clickedLatLng) => {
// Debugging-Ausgabe // Debugging-Ausgabe
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Plus-Icon Position:", clickedLatLng); console.log("Plus-Icon Position:", clickedLatLng);
}
// Finde Marker in der Nähe der Klickposition // Finde Marker in der Nähe der Klickposition
const nearbyMarkers = markers.filter((marker) => map.distance(marker.getLatLng(), clickedLatLng) < 50); const nearbyMarkers = markers.filter(
marker => map.distance(marker.getLatLng(), clickedLatLng) < 50
);
// Debugging-Ausgabe // Debugging-Ausgabe
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Gefundene Marker in der Nähe:", nearbyMarkers); console.log("Gefundene Marker in der Nähe:", nearbyMarkers);
}
if (oms && nearbyMarkers.length > 0) { if (oms && nearbyMarkers.length > 0) {
// Spiderfy die gefundenen Marker // Spiderfy die gefundenen Marker
oms.spiderfy(nearbyMarkers); oms.spiderfy(nearbyMarkers);
} else { } else {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Keine überlappenden Marker gefunden."); console.log("Keine überlappenden Marker gefunden.");
} }
}
}; };

View File

@@ -26,24 +26,32 @@ function getPool() {
cachedPool.on("acquire", () => { cachedPool.on("acquire", () => {
connectionCount++; connectionCount++;
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("\x1b[36m%s\x1b[0m", ` Connection acquired (${connectionCount} total)`); console.log("\x1b[36m%s\x1b[0m", ` Connection acquired (${connectionCount} total)`);
}
if (connectionCount > maxUsed) { if (connectionCount > maxUsed) {
maxUsed = connectionCount; maxUsed = connectionCount;
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log(`📈 Neue Höchstzahl aktiver gleichzeitiger Verbindungen: ${maxUsed}`); console.log(`📈 Neue Höchstzahl aktiver gleichzeitiger Verbindungen: ${maxUsed}`);
} }
} }
}
}); });
cachedPool.on("release", () => { cachedPool.on("release", () => {
connectionCount--; connectionCount--;
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("\x1b[32m%s\x1b[0m", ` Connection released (${connectionCount} total)`); console.log("\x1b[32m%s\x1b[0m", ` Connection released (${connectionCount} total)`);
} }
}
}); });
cachedPool.on("enqueue", () => { cachedPool.on("enqueue", () => {
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.warn("\x1b[33m%s\x1b[0m", "⏳ Pool voll Anfrage in Warteschlange"); console.warn("\x1b[33m%s\x1b[0m", "⏳ Pool voll Anfrage in Warteschlange");
} }
}
}); });
} }

View File

@@ -28,7 +28,9 @@ export function openInNewTab(e, target) {
} }
if (link) { if (link) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🟢 Öffne Link:", link); console.log("🟢 Öffne Link:", link);
}
window.open(link, "_blank"); window.open(link, "_blank");
} else { } else {
console.error("❌ Kein gültiger Link gefunden."); console.error("❌ Kein gültiger Link gefunden.");

View File

@@ -2,7 +2,6 @@
export function openInSameWindow(e, marker, baseUrl) { export function openInSameWindow(e, marker, baseUrl) {
if (marker && marker.options && marker.options.link) { if (marker && marker.options && marker.options.link) {
//console.log("Marker data:", baseUrl + marker.options.link);
window.location.href = baseUrl + marker.options.link; window.location.href = baseUrl + marker.options.link;
} else { } else {
console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft"); console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft");

View File

@@ -6,7 +6,9 @@ export function subscribeToPolylineContextMenu() {
store.subscribe(() => { store.subscribe(() => {
const state = store.getState(); // Redux-Toolkit empfohlene Methode const state = store.getState(); // Redux-Toolkit empfohlene Methode
if (state.polylineContextMenu.forceClose) { if (state.polylineContextMenu.forceClose) {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🚀 Redux-Event erkannt - Kontextmenü wird geschlossen."); console.log("🚀 Redux-Event erkannt - Kontextmenü wird geschlossen.");
}
store.dispatch(closePolylineContextMenu()); store.dispatch(closePolylineContextMenu());
if (window.map && window.map.contextmenu) { if (window.map && window.map.contextmenu) {

View File

@@ -7,14 +7,27 @@ import endIcon from "../../components/gisPolylines/icons/EndIcon";
import { redrawPolyline } from "./redrawPolyline"; import { redrawPolyline } from "./redrawPolyline";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import { store } from "../../redux/store"; // Importiere den Store import { store } from "../../redux/store"; // Importiere den Store
import { openPolylineContextMenu, closePolylineContextMenu } from "../../redux/slices/database/polylines/polylineContextMenuSlice"; import {
openPolylineContextMenu,
closePolylineContextMenu,
} from "../../redux/slices/database/polylines/polylineContextMenuSlice";
import { monitorContextMenu } from "./monitorContextMenu"; import { monitorContextMenu } from "./monitorContextMenu";
import { forceCloseContextMenu } from "../../redux/slices/database/polylines/polylineContextMenuSlice"; import { forceCloseContextMenu } from "../../redux/slices/database/polylines/polylineContextMenuSlice";
import { updatePolylineCoordinatesThunk } from "../../redux/thunks/database/polylines/updatePolylineCoordinatesThunk"; import { updatePolylineCoordinatesThunk } from "../../redux/thunks/database/polylines/updatePolylineCoordinatesThunk";
import { openInNewTab } from "../../utils/openInNewTab"; import { openInNewTab } from "../../utils/openInNewTab";
//-------------------------------------------- //--------------------------------------------
export const setupPolylines = (map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, currentZoom, currentCenter, polylineVisible) => { export const setupPolylines = (
map,
linePositions,
lineColors,
tooltipContents,
setNewCoords,
tempMarker,
currentZoom,
currentCenter,
polylineVisible
) => {
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE; const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
if (!polylineVisible) { if (!polylineVisible) {
@@ -25,7 +38,7 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
if (!polylineVisible) { if (!polylineVisible) {
// Entferne alle Polylinien, wenn sie ausgeblendet werden sollen // Entferne alle Polylinien, wenn sie ausgeblendet werden sollen
if (window.polylines) { if (window.polylines) {
window.polylines.forEach((polyline) => { window.polylines.forEach(polyline => {
if (map.hasLayer(polyline)) { if (map.hasLayer(polyline)) {
map.removeLayer(polyline); map.removeLayer(polyline);
} }
@@ -38,8 +51,6 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
const editMode = localStorage.getItem("editMode") === "true"; // Prüfen, ob der Bearbeitungsmodus aktiv ist const editMode = localStorage.getItem("editMode") === "true"; // Prüfen, ob der Bearbeitungsmodus aktiv ist
linePositions.forEach((lineData, lineIndex) => { linePositions.forEach((lineData, lineIndex) => {
//console.log("LineData:", lineData.idLD, lineData.idModul);
// **Fix: Sicherstellen, dass activeLines definiert ist und idLD existiert** // **Fix: Sicherstellen, dass activeLines definiert ist und idLD existiert**
const lineMarkers = []; const lineMarkers = [];
@@ -74,10 +85,13 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
color: lineColors[`${lineData.idLD}-${lineData.idModul}`] || "#000000", color: lineColors[`${lineData.idLD}-${lineData.idModul}`] || "#000000",
}).addTo(map); }).addTo(map);
updatedPolyline.bindTooltip(tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Tooltip", { updatedPolyline.bindTooltip(
tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Tooltip",
{
permanent: false, permanent: false,
direction: "auto", direction: "auto",
}); }
);
updatedPolyline.on("mouseover", () => updatedPolyline.setStyle({ weight: 20 })); updatedPolyline.on("mouseover", () => updatedPolyline.setStyle({ weight: 20 }));
updatedPolyline.on("mouseout", () => updatedPolyline.setStyle({ weight: 3 })); updatedPolyline.on("mouseout", () => updatedPolyline.setStyle({ weight: 3 }));
@@ -95,10 +109,12 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
store store
.dispatch(updatePolylineCoordinatesThunk(requestData)) .dispatch(updatePolylineCoordinatesThunk(requestData))
.unwrap() .unwrap()
.then((data) => { .then(data => {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Koordinaten erfolgreich aktualisiert:", data); console.log("Koordinaten erfolgreich aktualisiert:", data);
}
}) })
.catch((error) => { .catch(error => {
console.error("Fehler beim Aktualisieren der Koordinaten:", error.message); console.error("Fehler beim Aktualisieren der Koordinaten:", error.message);
}); });
} else { } else {
@@ -150,32 +166,34 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
{ {
text: "Station öffnen (Tab)", text: "Station öffnen (Tab)",
icon: "/img/screen_new.png", icon: "/img/screen_new.png",
callback: (e) => openInNewTab(e, lineData), callback: e => openInNewTab(e, lineData),
}, },
{ separator: true }, { separator: true },
{ {
text: "Koordinaten anzeigen", text: "Koordinaten anzeigen",
icon: "/img/not_listed_location.png", icon: "/img/not_listed_location.png",
callback: (e) => { callback: e => {
alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5)); alert(
"Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5)
);
}, },
}, },
{ separator: true }, { separator: true },
{ {
text: "Reinzoomen", text: "Reinzoomen",
icon: "/img/zoom_in.png", icon: "/img/zoom_in.png",
callback: (e) => map.zoomIn(), callback: e => map.zoomIn(),
}, },
{ {
text: "Rauszoomen", text: "Rauszoomen",
icon: "/img/zoom_out.png", icon: "/img/zoom_out.png",
callback: (e) => map.zoomOut(), callback: e => map.zoomOut(),
}, },
{ {
text: "Hier zentrieren", text: "Hier zentrieren",
icon: "/img/center_focus.png", icon: "/img/center_focus.png",
callback: (e) => map.panTo(e.latlng), callback: e => map.panTo(e.latlng),
}, },
{ separator: true }, { separator: true },
/* { /* {
@@ -189,7 +207,7 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
{ {
text: "Stützpunkt hinzufügen", text: "Stützpunkt hinzufügen",
icon: "/img/icons/gisLines/add-support-point.svg", icon: "/img/icons/gisLines/add-support-point.svg",
callback: (e) => { callback: e => {
if (tempMarker) { if (tempMarker) {
tempMarker.remove(); tempMarker.remove();
} }
@@ -206,10 +224,13 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
{ {
text: "Station öffnen (Tab)", text: "Station öffnen (Tab)",
icon: "/img/screen_new.png", icon: "/img/screen_new.png",
callback: (e) => { callback: e => {
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE; const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
const baseUrl = mode === "dev" ? `${window.location.protocol}//${window.location.hostname}:80${basePath}/` : `${window.location.origin}${basePath}/`; const baseUrl =
mode === "dev"
? `${window.location.protocol}//${window.location.hostname}:80${basePath}/`
: `${window.location.origin}${basePath}/`;
const link = `${baseUrl}devices/cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`; const link = `${baseUrl}devices/cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`;
@@ -221,26 +242,28 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
{ {
text: "Koordinaten anzeigen", text: "Koordinaten anzeigen",
icon: "/img/not_listed_location.png", icon: "/img/not_listed_location.png",
callback: (e) => { callback: e => {
alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5)); alert(
"Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5)
);
}, },
}, },
{ separator: true }, { separator: true },
{ {
text: "Reinzoomen", text: "Reinzoomen",
icon: "/img/zoom_in.png", icon: "/img/zoom_in.png",
callback: (e) => map.zoomIn(), callback: e => map.zoomIn(),
}, },
{ {
text: "Rauszoomen", text: "Rauszoomen",
icon: "/img/zoom_out.png", icon: "/img/zoom_out.png",
callback: (e) => map.zoomOut(), callback: e => map.zoomOut(),
}, },
{ {
text: "Hier zentrieren", text: "Hier zentrieren",
icon: "/img/center_focus.png", icon: "/img/center_focus.png",
callback: (e) => map.panTo(e.latlng), callback: e => map.panTo(e.latlng),
}, },
{ separator: true } { separator: true }
/* { /* {
@@ -254,32 +277,33 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
} }
// Hier wird der Tooltip hinzugefügt // Hier wird der Tooltip hinzugefügt
polyline.bindTooltip(tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Standard-Tooltip-Inhalt setup", { polyline.bindTooltip(
tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Standard-Tooltip-Inhalt setup",
{
permanent: false, permanent: false,
direction: "auto", direction: "auto",
}); }
);
polyline.on("mouseover", (e) => { polyline.on("mouseover", e => {
const startTime = Date.now(); // Startzeit erfassen const startTime = Date.now(); // Startzeit erfassen
polyline.setStyle({ weight: 14 }); polyline.setStyle({ weight: 14 });
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE; const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
const baseUrl = mode === "dev" ? `${window.location.protocol}//${window.location.hostname}:80${basePath}/` : `${window.location.origin}${basePath}/`; const baseUrl =
mode === "dev"
? `${window.location.protocol}//${window.location.hostname}:80${basePath}/`
: `${window.location.origin}${basePath}/`;
const link = `${baseUrl}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`; const link = `${baseUrl}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`;
// console.log("Link der Linie:", link);
}); });
// error TypeError: Cannot read properties of null (reading 'contextmenu') wenn der Mas auf die Linie bleibt // error TypeError: Cannot read properties of null (reading 'contextmenu') wenn der Mas auf die Linie bleibt
polyline.on("mouseout", (e) => { polyline.on("mouseout", e => {
polyline.setStyle({ weight: 3 }); polyline.setStyle({ weight: 3 });
//console.log("🚀 Maus hat die Polyline verlassen - Warten auf Klick außerhalb des Menüs.");
document.addEventListener("click", function handleOutsideClick(event) { document.addEventListener("click", function handleOutsideClick(event) {
if (!event.target.closest(".leaflet-contextmenu")) { if (!event.target.closest(".leaflet-contextmenu")) {
//console.log("🛑 Klick außerhalb des Kontextmenüs erkannt - Schließe Menü.");
try { try {
store.dispatch(closePolylineContextMenu()); store.dispatch(closePolylineContextMenu());
store.dispatch(forceCloseContextMenu()); store.dispatch(forceCloseContextMenu());
@@ -296,7 +320,7 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
} }
}); });
}); });
polyline.on("contextmenu", (e) => { polyline.on("contextmenu", e => {
store.dispatch( store.dispatch(
openPolylineContextMenu({ openPolylineContextMenu({
position: { lat: e.latlng.lat, lng: e.latlng.lng }, position: { lat: e.latlng.lat, lng: e.latlng.lng },

View File

@@ -4,12 +4,16 @@ import { setSelectedDevice, clearSelectedDevice } from "../redux/slices/selected
export const setupDevices = async (map, deviceMarkers, dispatch) => { export const setupDevices = async (map, deviceMarkers, dispatch) => {
for (const marker of deviceMarkers) { for (const marker of deviceMarkers) {
marker.on("mouseover", function () { marker.on("mouseover", function () {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("✅ Gerät ausgewählt:", marker); console.log("✅ Gerät ausgewählt:", marker);
}
dispatch(setSelectedDevice(marker.options)); // Gerät in Redux speichern dispatch(setSelectedDevice(marker.options)); // Gerät in Redux speichern
}); });
marker.on("mouseout", function () { marker.on("mouseout", function () {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("❌ Gerät abgewählt"); console.log("❌ Gerät abgewählt");
}
dispatch(clearSelectedDevice()); // Gerät aus Redux entfernen dispatch(clearSelectedDevice()); // Gerät aus Redux entfernen
}); });