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

@@ -5,7 +5,15 @@ import "leaflet/dist/leaflet.css";
import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
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;
if (!mapRef.current) {
@@ -14,7 +22,9 @@ export const initializeMap = (mapRef, setMap, setOms, setMenuItemAdded, addItems
}
if (mapRef.current._leaflet_id) {
console.log("⚠️ Karte bereits initialisiert");
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("⚠️ Karte bereits initialisiert");
}
return;
}

View File

@@ -2,7 +2,7 @@
import L from "leaflet";
// 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 savedCenter = localStorage.getItem("mapCenter");
@@ -29,7 +29,7 @@ export const checkOverlappingMarkers = (map, markers, plusIcon, oms) => {
const overlappingGroups = {};
markers.forEach((marker) => {
markers.forEach(marker => {
if (map.hasLayer(marker)) {
const latlngStr = marker.getLatLng().toString();
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 = [];
for (const coords in overlappingGroups) {
@@ -62,18 +62,26 @@ export const checkOverlappingMarkers = (map, markers, plusIcon, oms) => {
export const handlePlusIconClick = (map, markers, oms, clickedLatLng) => {
// Debugging-Ausgabe
console.log("Plus-Icon Position:", clickedLatLng);
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Plus-Icon Position:", clickedLatLng);
}
// 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
console.log("Gefundene Marker in der Nähe:", nearbyMarkers);
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Gefundene Marker in der Nähe:", nearbyMarkers);
}
if (oms && nearbyMarkers.length > 0) {
// Spiderfy die gefundenen Marker
oms.spiderfy(nearbyMarkers);
} else {
console.log("Keine überlappenden Marker gefunden.");
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Keine überlappenden Marker gefunden.");
}
}
};

View File

@@ -26,23 +26,31 @@ function getPool() {
cachedPool.on("acquire", () => {
connectionCount++;
if (process.env.NODE_ENV === "development") {
console.log("\x1b[36m%s\x1b[0m", ` Connection acquired (${connectionCount} total)`);
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("\x1b[36m%s\x1b[0m", ` Connection acquired (${connectionCount} total)`);
}
if (connectionCount > maxUsed) {
maxUsed = connectionCount;
console.log(`📈 Neue Höchstzahl aktiver gleichzeitiger Verbindungen: ${maxUsed}`);
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log(`📈 Neue Höchstzahl aktiver gleichzeitiger Verbindungen: ${maxUsed}`);
}
}
}
});
cachedPool.on("release", () => {
connectionCount--;
if (process.env.NODE_ENV === "development") {
console.log("\x1b[32m%s\x1b[0m", ` Connection released (${connectionCount} total)`);
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("\x1b[32m%s\x1b[0m", ` Connection released (${connectionCount} total)`);
}
}
});
cachedPool.on("enqueue", () => {
if (process.env.NODE_ENV === "development") {
console.warn("\x1b[33m%s\x1b[0m", "⏳ Pool voll Anfrage in Warteschlange");
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
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) {
console.log("🟢 Öffne Link:", link);
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🟢 Öffne Link:", link);
}
window.open(link, "_blank");
} else {
console.error("❌ Kein gültiger Link gefunden.");

View File

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

View File

@@ -6,7 +6,9 @@ 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.");
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("🚀 Redux-Event erkannt - Kontextmenü wird geschlossen.");
}
store.dispatch(closePolylineContextMenu());
if (window.map && window.map.contextmenu) {

View File

@@ -7,14 +7,27 @@ import endIcon from "../../components/gisPolylines/icons/EndIcon";
import { redrawPolyline } from "./redrawPolyline";
import { toast } from "react-toastify";
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 { forceCloseContextMenu } from "../../redux/slices/database/polylines/polylineContextMenuSlice";
import { updatePolylineCoordinatesThunk } from "../../redux/thunks/database/polylines/updatePolylineCoordinatesThunk";
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 basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
if (!polylineVisible) {
@@ -25,7 +38,7 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
if (!polylineVisible) {
// Entferne alle Polylinien, wenn sie ausgeblendet werden sollen
if (window.polylines) {
window.polylines.forEach((polyline) => {
window.polylines.forEach(polyline => {
if (map.hasLayer(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
linePositions.forEach((lineData, lineIndex) => {
//console.log("LineData:", lineData.idLD, lineData.idModul);
// **Fix: Sicherstellen, dass activeLines definiert ist und idLD existiert**
const lineMarkers = [];
@@ -74,10 +85,13 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
color: lineColors[`${lineData.idLD}-${lineData.idModul}`] || "#000000",
}).addTo(map);
updatedPolyline.bindTooltip(tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Tooltip", {
permanent: false,
direction: "auto",
});
updatedPolyline.bindTooltip(
tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Tooltip",
{
permanent: false,
direction: "auto",
}
);
updatedPolyline.on("mouseover", () => updatedPolyline.setStyle({ weight: 20 }));
updatedPolyline.on("mouseout", () => updatedPolyline.setStyle({ weight: 3 }));
@@ -95,10 +109,12 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
store
.dispatch(updatePolylineCoordinatesThunk(requestData))
.unwrap()
.then((data) => {
console.log("Koordinaten erfolgreich aktualisiert:", data);
.then(data => {
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("Koordinaten erfolgreich aktualisiert:", data);
}
})
.catch((error) => {
.catch(error => {
console.error("Fehler beim Aktualisieren der Koordinaten:", error.message);
});
} else {
@@ -150,32 +166,34 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
{
text: "Station öffnen (Tab)",
icon: "/img/screen_new.png",
callback: (e) => openInNewTab(e, lineData),
callback: e => openInNewTab(e, lineData),
},
{ separator: true },
{
text: "Koordinaten anzeigen",
icon: "/img/not_listed_location.png",
callback: (e) => {
alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5));
callback: e => {
alert(
"Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5)
);
},
},
{ separator: true },
{
text: "Reinzoomen",
icon: "/img/zoom_in.png",
callback: (e) => map.zoomIn(),
callback: e => map.zoomIn(),
},
{
text: "Rauszoomen",
icon: "/img/zoom_out.png",
callback: (e) => map.zoomOut(),
callback: e => map.zoomOut(),
},
{
text: "Hier zentrieren",
icon: "/img/center_focus.png",
callback: (e) => map.panTo(e.latlng),
callback: e => map.panTo(e.latlng),
},
{ separator: true },
/* {
@@ -189,7 +207,7 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
{
text: "Stützpunkt hinzufügen",
icon: "/img/icons/gisLines/add-support-point.svg",
callback: (e) => {
callback: e => {
if (tempMarker) {
tempMarker.remove();
}
@@ -206,10 +224,13 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
{
text: "Station öffnen (Tab)",
icon: "/img/screen_new.png",
callback: (e) => {
callback: e => {
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}`;
@@ -221,26 +242,28 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
{
text: "Koordinaten anzeigen",
icon: "/img/not_listed_location.png",
callback: (e) => {
alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5));
callback: e => {
alert(
"Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5)
);
},
},
{ separator: true },
{
text: "Reinzoomen",
icon: "/img/zoom_in.png",
callback: (e) => map.zoomIn(),
callback: e => map.zoomIn(),
},
{
text: "Rauszoomen",
icon: "/img/zoom_out.png",
callback: (e) => map.zoomOut(),
callback: e => map.zoomOut(),
},
{
text: "Hier zentrieren",
icon: "/img/center_focus.png",
callback: (e) => map.panTo(e.latlng),
callback: e => map.panTo(e.latlng),
},
{ separator: true }
/* {
@@ -254,32 +277,33 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
}
// Hier wird der Tooltip hinzugefügt
polyline.bindTooltip(tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Standard-Tooltip-Inhalt setup", {
permanent: false,
direction: "auto",
});
polyline.bindTooltip(
tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Standard-Tooltip-Inhalt setup",
{
permanent: false,
direction: "auto",
}
);
polyline.on("mouseover", (e) => {
polyline.on("mouseover", e => {
const startTime = Date.now(); // Startzeit erfassen
polyline.setStyle({ weight: 14 });
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}`;
// 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) => {
polyline.on("mouseout", e => {
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) {
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());
@@ -296,7 +320,7 @@ export const setupPolylines = (map, linePositions, lineColors, tooltipContents,
}
});
});
polyline.on("contextmenu", (e) => {
polyline.on("contextmenu", e => {
store.dispatch(
openPolylineContextMenu({
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) => {
for (const marker of deviceMarkers) {
marker.on("mouseover", function () {
console.log("✅ Gerät ausgewählt:", marker);
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("✅ Gerät ausgewählt:", marker);
}
dispatch(setSelectedDevice(marker.options)); // Gerät in Redux speichern
});
marker.on("mouseout", function () {
console.log("❌ Gerät abgewählt");
if (process.env.NEXT_PUBLIC_DEBUG_LOG === "true") {
console.log("❌ Gerät abgewählt");
}
dispatch(clearSelectedDevice()); // Gerät aus Redux entfernen
});