polylines tooltip content
This commit is contained in:
3
.babelrc
Normal file
3
.babelrc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"presets": ["@babel/preset-env", "@babel/preset-react"]
|
||||||
|
}
|
||||||
45
.env.local
45
.env.local
@@ -1,10 +1,45 @@
|
|||||||
|
#.env.local
|
||||||
|
#je nach dem Mysql Server, ob localhost freigegeben ist oder die IP Adresse des Servers, manchmal die beide und manchmal nur eine
|
||||||
|
|
||||||
DB_HOST=localhost
|
#DB_HOST=10.10.0.30
|
||||||
#DB_HOST=192.168.10.58
|
#DB_USER=root
|
||||||
#DB_HOST=10.10.0.13
|
#DB_PASSWORD="root#$"
|
||||||
|
#DB_NAME=talas_v5
|
||||||
|
#DB_PORT=3306
|
||||||
|
|
||||||
|
|
||||||
|
#########################
|
||||||
|
|
||||||
|
#NEXT_PUBLIC_BASE_URL="http://10.10.0.30/talas5/devices/"
|
||||||
|
#NEXT_PUBLIC_SERVER_URL="http://10.10.0.30"
|
||||||
|
#NEXT_PUBLIC_PROXY_TARGET="http://10.10.0.30"
|
||||||
|
#NEXT_PUBLIC_ONLINE_TILE_LAYER="http://10.10.0.30:3000/mapTiles/{z}/{x}/{y}.png"
|
||||||
|
#########################
|
||||||
|
|
||||||
|
|
||||||
|
#DB_HOST=10.10.0.70
|
||||||
|
#DB_USER=root
|
||||||
|
#DB_PASSWORD="root#$"
|
||||||
|
#DB_NAME=talas_v5
|
||||||
|
#DB_PORT=3306
|
||||||
|
|
||||||
|
|
||||||
|
#########################
|
||||||
|
|
||||||
|
#NEXT_PUBLIC_BASE_URL="http://10.10.0.70/talas5/devices/"
|
||||||
|
#NEXT_PUBLIC_SERVER_URL="http://10.10.0.70"
|
||||||
|
#NEXT_PUBLIC_PROXY_TARGET="http://10.10.0.70"
|
||||||
|
#NEXT_PUBLIC_ONLINE_TILE_LAYER="http://10.10.0.13:3000/mapTiles/{z}/{x}/{y}.png"
|
||||||
|
#########################
|
||||||
|
|
||||||
|
DB_HOST=192.168.10.167
|
||||||
DB_USER=root
|
DB_USER=root
|
||||||
DB_PASSWORD="root#$"
|
DB_PASSWORD="root#$"
|
||||||
DB_NAME=talas_v5
|
DB_NAME=talas_v5
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
######################### Kontetmenü -> Station in tab öffnen
|
#########################
|
||||||
#BASE_URL=http://10.10.0.13/talas5/devices/
|
#URLs für den Client (clientseitig)
|
||||||
|
NEXT_PUBLIC_BASE_URL="http://192.168.10.167/talas5/devices/"
|
||||||
|
NEXT_PUBLIC_SERVER_URL="http://192.168.10.167"
|
||||||
|
NEXT_PUBLIC_PROXY_TARGET="http://192.168.10.167"
|
||||||
|
NEXT_PUBLIC_ONLINE_TILE_LAYER="http://192.168.10.14:3000/mapTiles/{z}/{x}/{y}.png"
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -26,3 +26,4 @@ trace
|
|||||||
|
|
||||||
# Ignore specific Next.js build files
|
# Ignore specific Next.js build files
|
||||||
pages-manifest.json
|
pages-manifest.json
|
||||||
|
nodeMap für 13 am 16.07.2024.zip
|
||||||
|
|||||||
3
.prettierrc
Normal file
3
.prettierrc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 250
|
||||||
|
}
|
||||||
1
.vscode/settings.json
vendored
Normal file
1
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
81
Jenkinsfile
vendored
81
Jenkinsfile
vendored
@@ -1,96 +1,37 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
|
|
||||||
environment {
|
|
||||||
NODE_ENV = 'production'
|
|
||||||
}
|
|
||||||
|
|
||||||
tools {
|
|
||||||
nodejs 'nodejs' // Ensure this matches the name defined in Jenkins
|
|
||||||
}
|
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage('Checkout') {
|
stage('Checkout SCM') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
checkout([$class: 'GitSCM', branches: [[name: '**']],
|
||||||
try {
|
doGenerateSubmoduleConfigurations: false,
|
||||||
// Code aus dem Repository holen
|
extensions: [],
|
||||||
git branch: 'develop', url: 'http://172.19.0.2:3000/Ismail/NodeMap.git'
|
userRemoteConfigs: [[url: 'http://172.20.0.2:3000/Ismail/NodeMap', credentialsId: 'd378f013-2f24-417b-9afd-33df5d410ab8']]])
|
||||||
} catch (Exception e) {
|
|
||||||
error "Branch 'develop' exists nicht im Repository"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Check Node.js Version') {
|
stage('Check Node.js Version') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
sh 'node --version'
|
def nodeVersion = sh(script: 'node --version', returnStdout: true).trim()
|
||||||
|
echo "Node.js version: ${nodeVersion}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Install Dependencies') {
|
stage('Install Dependencies') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
try {
|
sh 'npm install'
|
||||||
// Install dependencies
|
|
||||||
sh 'npm install'
|
|
||||||
} catch (Exception e) {
|
|
||||||
error "Dependency Installation failed: ${e.message}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage('Run Unit Tests') {
|
||||||
stage('Build') {
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
try {
|
sh 'npm test'
|
||||||
// Build the project
|
|
||||||
sh 'npm run build'
|
|
||||||
} catch (Exception e) {
|
|
||||||
error "Build failed: ${e.message}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weitere Stages ...
|
||||||
stage('Test') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
try {
|
|
||||||
// Run tests
|
|
||||||
sh 'npm test'
|
|
||||||
} catch (Exception e) {
|
|
||||||
error "Tests failed: ${e.message}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Deploy') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
try {
|
|
||||||
// Add your deployment steps here
|
|
||||||
// For example: sh 'npm run deploy'
|
|
||||||
echo 'Deployment steps go here'
|
|
||||||
} catch (Exception e) {
|
|
||||||
error "Deployment failed: ${e.message}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
post {
|
|
||||||
success {
|
|
||||||
echo 'Build, tests, and deployment were successful!'
|
|
||||||
}
|
|
||||||
failure {
|
|
||||||
echo 'Build, tests, or deployment failed.'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
MapTypC.aspx.txt
Normal file
47
MapTypC.aspx.txt
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/Standard.Master" AutoEventWireup="true" CodeBehind="MapTypC.aspx.cs" Inherits="TALAS_V5.MessagesMap.MapTypC" %>
|
||||||
|
<%@ Register assembly="DevExpress.Web.v19.2, Version=19.2.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" namespace="DevExpress.Web" tagprefix="dx" %>
|
||||||
|
|
||||||
|
<asp:Content ID="NaviContent" ContentPlaceHolderID="NaviContent" runat="server">
|
||||||
|
</asp:Content>
|
||||||
|
|
||||||
|
<asp:Content ID="Content" ContentPlaceHolderID="MainContent" runat="server">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.responsive-iframe-wrapper {
|
||||||
|
position: relative !important;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 97.2vh !important; /* Setzt die Höhe des Wrappers auf die Höhe des Viewports */
|
||||||
|
overflow: hidden !important; /* Verhindert Scrollbalken innerhalb des Wrappers */
|
||||||
|
padding: 0 0 0 0 !important;
|
||||||
|
margin: 0 0 0 0 !important;
|
||||||
|
}
|
||||||
|
.responsive-iframe-wrapper iframe {
|
||||||
|
position: absolute !important;
|
||||||
|
top: 0 !important;
|
||||||
|
left: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
border: none !important; /* Removes the border */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="responsive-iframe-wrapper">
|
||||||
|
<iframe frameborder="0"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
var url = new URL(window.location.href);
|
||||||
|
var mValue = url.searchParams.get("m");
|
||||||
|
var uValue = url.searchParams.get("u");
|
||||||
|
|
||||||
|
// Setzen der src-Eigenschaft des iframe mit den abgerufenen Parametern
|
||||||
|
document.querySelector('.responsive-iframe-wrapper iframe').src =
|
||||||
|
// "http://10.10.0.70:3000?m=" + encodeURIComponent(mValue) + "&u=" + encodeURIComponent(uValue);
|
||||||
|
"http://10.10.0.13:3000?m=" + encodeURIComponent(mValue) + "&u=" + encodeURIComponent(uValue);
|
||||||
|
//"http://localhost:3000?m=" + encodeURIComponent(mValue) + "&u=" + encodeURIComponent(uValue);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</asp:Content>
|
||||||
2
Wiki.md
2
Wiki.md
@@ -146,7 +146,7 @@ Bei Problemen während der Weiterentwicklung könnte es hilfreich sein, die Seit
|
|||||||
- **DataSheet.js**: Verantwortlich für die Anzeige und Interaktion mit den Layer- und Stationsauswahlen. Ermöglicht das Aktivieren/Deaktivieren von Layern und zeigt Informationen zu geografischen Punkten.
|
- **DataSheet.js**: Verantwortlich für die Anzeige und Interaktion mit den Layer- und Stationsauswahlen. Ermöglicht das Aktivieren/Deaktivieren von Layern und zeigt Informationen zu geografischen Punkten.
|
||||||
- **MapComponent.js**: Kernkomponente für die Darstellung der Karte. Beinhaltet Logik für das Hinzufügen von Layern, Zoom-Funktionen und andere interaktive Elemente.
|
- **MapComponent.js**: Kernkomponente für die Darstellung der Karte. Beinhaltet Logik für das Hinzufügen von Layern, Zoom-Funktionen und andere interaktive Elemente.
|
||||||
- **PoiUpdateModal.js**:Komponente zum Aktualisieren(update) und löschen von Pois.
|
- **PoiUpdateModal.js**:Komponente zum Aktualisieren(update) und löschen von Pois.
|
||||||
- **ShowAddStationPopup.js**:Komponente zum hinzufügen von Pois.
|
- **AddPoiModalWindow.js**:Komponente zum hinzufügen von Pois.
|
||||||
|
|
||||||
### /public
|
### /public
|
||||||
|
|
||||||
|
|||||||
23
__mocks__/leaflet.js
Normal file
23
__mocks__/leaflet.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// __mocks__/leaflet.js
|
||||||
|
const L = {
|
||||||
|
divIcon: jest.fn(() => new L.DivIcon()),
|
||||||
|
DivIcon: function () {
|
||||||
|
this.options = {
|
||||||
|
className: "custom-start-icon",
|
||||||
|
html: `
|
||||||
|
<svg width="18" height="18" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<polygon points="10,2 18,18 2,18" fill="black" />
|
||||||
|
<polygon points="10,5 16,16 4,16" fill="gray" />
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
iconSize: [18, 18],
|
||||||
|
iconAnchor: [9, 10],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
L.DivIcon.prototype = {
|
||||||
|
constructor: L.DivIcon,
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = L;
|
||||||
82
__tests__/unit/components/DataSheet.test.js
Normal file
82
__tests__/unit/components/DataSheet.test.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
// __tests__/components/DataSheet.test.js
|
||||||
|
import React from "react";
|
||||||
|
import { render, screen, waitFor } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
import userEvent from "@testing-library/user-event";
|
||||||
|
import DataSheet from "../../components/DataSheet";
|
||||||
|
import { RecoilRoot } from "recoil";
|
||||||
|
import * as Recoil from "recoil";
|
||||||
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||||
|
import { gisStationsStaticDistrictState } from "../../store/atoms/gisStationState";
|
||||||
|
import { gisSystemStaticState } from "../../store/atoms/gisSystemState";
|
||||||
|
import { mapLayersState } from "../../store/atoms/mapLayersState";
|
||||||
|
import { selectedAreaState } from "../../store/atoms/selectedAreaState";
|
||||||
|
import { zoomTriggerState } from "../../store/atoms/zoomTriggerState";
|
||||||
|
import { poiLayerVisibleState } from "../../store/atoms/poiLayerVisibleState";
|
||||||
|
|
||||||
|
// Stelle sicher, dass alle notwendigen Atome korrekt gemockt sind
|
||||||
|
jest.mock("../../store/atoms/gisStationState", () => ({
|
||||||
|
gisStationState: {
|
||||||
|
subscribe: jest.fn(),
|
||||||
|
getSnapshot: jest.fn(() => []), // Mocked return value
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("../../store/atoms/gisSystemState", () => ({
|
||||||
|
gisSystemStaticState: {
|
||||||
|
subscribe: jest.fn(),
|
||||||
|
getSnapshot: jest.fn(() => []), // Mocked return value
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("DataSheet Component", () => {
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
it("renders the basic fields and initial station/system listings", async () => {
|
||||||
|
render(
|
||||||
|
<RecoilRoot>
|
||||||
|
<DataSheet />
|
||||||
|
</RecoilRoot>
|
||||||
|
);
|
||||||
|
|
||||||
|
// Waiting for asynchronous tasks to complete
|
||||||
|
await waitFor(() => {
|
||||||
|
// Check if the specific elements are present after data processing
|
||||||
|
expect(screen.getByRole("combobox")).toBeInTheDocument();
|
||||||
|
expect(screen.getByLabelText("POIs")).toBeInTheDocument();
|
||||||
|
expect(screen.getByRole("option", { name: "Station wählen" })).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Optionally print out the full DOM for debugging
|
||||||
|
screen.debug();
|
||||||
|
});
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
test("should open dropdown on click", async () => {
|
||||||
|
render(
|
||||||
|
<RecoilRoot>
|
||||||
|
<DataSheet />
|
||||||
|
</RecoilRoot>
|
||||||
|
);
|
||||||
|
const combobox = screen.getByRole("combobox");
|
||||||
|
userEvent.click(combobox);
|
||||||
|
// Überprüfe, ob die Dropdown-Optionen angezeigt werden
|
||||||
|
expect(screen.getByRole("option", { name: "Station wählen" })).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
test("should toggle checkbox", async () => {
|
||||||
|
render(
|
||||||
|
<RecoilRoot>
|
||||||
|
<DataSheet />
|
||||||
|
</RecoilRoot>
|
||||||
|
);
|
||||||
|
const checkbox = screen.getByLabelText("POIs");
|
||||||
|
// Stelle sicher, dass die Checkbox nicht angekreuzt ist
|
||||||
|
expect(checkbox).not.toBeChecked();
|
||||||
|
// Klicke auf die Checkbox
|
||||||
|
userEvent.click(checkbox);
|
||||||
|
// Jetzt sollte sie angekreuzt sein
|
||||||
|
expect(checkbox).toBeChecked();
|
||||||
|
});
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
});
|
||||||
89
__tests__/unit/components/MapComponent.test.js
Normal file
89
__tests__/unit/components/MapComponent.test.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
// __tests__/MapComponent.test.js
|
||||||
|
|
||||||
|
// Ein einfacher Testfall, der sicherstellt, dass die Addition korrekt ist
|
||||||
|
test("simple addition", () => {
|
||||||
|
const a = 1;
|
||||||
|
const b = 2;
|
||||||
|
const c = a + b;
|
||||||
|
expect(c).toBe(3); // Überprüft, ob c gleich 3 ist
|
||||||
|
});
|
||||||
|
|
||||||
|
//import L from "leaflet";
|
||||||
|
//import { checkOverlappingMarkers } from "../utils/mapUtils"; // Passe den Pfad entsprechend an
|
||||||
|
|
||||||
|
/* describe("checkOverlappingMarkers", () => {
|
||||||
|
let map;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// Erstelle eine neue Leaflet-Karte für jeden Test
|
||||||
|
map = L.map(document.createElement("div"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should group markers by coordinates and add plus icons for overlapping markers", () => {
|
||||||
|
// Erstelle einige Beispielmarker
|
||||||
|
const markers = [
|
||||||
|
L.marker([51.505, -0.09]),
|
||||||
|
L.marker([51.505, -0.09]),
|
||||||
|
L.marker([51.51, -0.1]),
|
||||||
|
];
|
||||||
|
|
||||||
|
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||||
|
|
||||||
|
// Rufe die Funktion auf
|
||||||
|
checkOverlappingMarkers(map, markers, plusIcon);
|
||||||
|
|
||||||
|
// Überprüfe, dass die Marker zu Gruppen hinzugefügt wurden
|
||||||
|
const overlappingGroups = map._layers;
|
||||||
|
expect(Object.keys(overlappingGroups).length).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
// Überprüfe, dass die Plus-Marker hinzugefügt wurden
|
||||||
|
const plusMarkers = Object.values(overlappingGroups).filter(
|
||||||
|
(layer) =>
|
||||||
|
layer.options.icon &&
|
||||||
|
layer.options.icon.options.className === "plus-icon"
|
||||||
|
);
|
||||||
|
expect(plusMarkers.length).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle non-array markers argument gracefully", () => {
|
||||||
|
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||||
|
|
||||||
|
// Rufe die Funktion mit einem ungültigen Argument auf
|
||||||
|
checkOverlappingMarkers(map, null, plusIcon);
|
||||||
|
|
||||||
|
// Stelle sicher, dass keine Marker hinzugefügt wurden
|
||||||
|
const layers = map._layers;
|
||||||
|
expect(Object.keys(layers).length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not add plus markers if there are no overlaps", () => {
|
||||||
|
// Erstelle einige Beispielmarker
|
||||||
|
const markers = [
|
||||||
|
L.marker([51.505, -0.09]),
|
||||||
|
L.marker([51.51, -0.1]),
|
||||||
|
L.marker([51.52, -0.12]),
|
||||||
|
];
|
||||||
|
|
||||||
|
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||||
|
|
||||||
|
// Rufe die Funktion auf
|
||||||
|
checkOverlappingMarkers(map, markers, plusIcon);
|
||||||
|
|
||||||
|
// Überprüfe, dass keine Plus-Marker hinzugefügt wurden
|
||||||
|
const plusMarkers = Object.values(map._layers).filter(
|
||||||
|
(layer) =>
|
||||||
|
layer.options.icon &&
|
||||||
|
layer.options.icon.options.className === "plus-icon"
|
||||||
|
);
|
||||||
|
expect(plusMarkers.length).toBe(0);
|
||||||
|
});
|
||||||
|
}); */
|
||||||
|
/*
|
||||||
|
In diesem Test:
|
||||||
|
|
||||||
|
Wird eine neue Leaflet-Karte vor jedem Test erstellt.
|
||||||
|
checkOverlappingMarkers wird aufgerufen, um zu überprüfen, ob die Funktion die Marker richtig gruppiert und Plus-Icons für überlappende Marker hinzufügt.
|
||||||
|
Der Test überprüft auch, ob die Funktion ungültige Argumente (wie null für Marker) korrekt behandelt.
|
||||||
|
Es wird sichergestellt, dass keine Plus-Marker hinzugefügt werden, wenn keine Überlappungen vorliegen.
|
||||||
|
Stelle sicher, dass du die Pfade und Importe entsprechend deiner Projektstruktur anpasst.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// __tests__/components/gisPolylines/icons/CircleIcon.test.js
|
||||||
|
jest.mock("leaflet", () => {
|
||||||
|
const actualLeaflet = jest.requireActual("leaflet");
|
||||||
|
return {
|
||||||
|
...actualLeaflet,
|
||||||
|
DivIcon: jest.fn().mockImplementation((options) => ({
|
||||||
|
...options,
|
||||||
|
options,
|
||||||
|
_leaflet_id: Math.random(),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
import L from "leaflet";
|
||||||
|
import CircleIcon from "../../../components/gisPolylines/icons/CircleIcon";
|
||||||
|
|
||||||
|
describe("CircleIcon", () => {
|
||||||
|
test("should be a Leaflet divIcon with correct properties", () => {
|
||||||
|
// console.log("CircleIcon options:", CircleIcon.options);
|
||||||
|
expect(CircleIcon).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
options: expect.objectContaining({
|
||||||
|
className: "custom-circle-icon leaflet-marker-icon",
|
||||||
|
html: '<div style="background-color:gray; width:10px; height:10px; border-radius:50%; border: solid black 1px;"></div>',
|
||||||
|
iconSize: [25, 25],
|
||||||
|
iconAnchor: [5, 5],
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
expect(CircleIcon.options.className).toContain("custom-circle-icon");
|
||||||
|
expect(CircleIcon.options.html).toContain("<div");
|
||||||
|
expect(CircleIcon.options.html).toContain("background-color:gray");
|
||||||
|
expect(CircleIcon.options.html).toContain("border-radius:50%");
|
||||||
|
expect(CircleIcon.options.html).toContain("width:10px");
|
||||||
|
expect(CircleIcon.options.html).toContain("height:10px");
|
||||||
|
expect(CircleIcon.options.html).toContain("border: solid black 1px");
|
||||||
|
expect(CircleIcon.options.iconSize).toEqual([25, 25]);
|
||||||
|
expect(CircleIcon.options.iconAnchor).toEqual([5, 5]);
|
||||||
|
});
|
||||||
|
});
|
||||||
24
__tests__/unit/components/gisPolylines/icons/EndIcon.test.js
Normal file
24
__tests__/unit/components/gisPolylines/icons/EndIcon.test.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// __tests__/components/gisPolylines/icons/EndIcon.test.js
|
||||||
|
jest.mock("leaflet", () => {
|
||||||
|
const actualLeaflet = jest.requireActual("leaflet");
|
||||||
|
return {
|
||||||
|
...actualLeaflet,
|
||||||
|
DivIcon: jest.fn().mockImplementation((options) => ({
|
||||||
|
...options,
|
||||||
|
options,
|
||||||
|
_leaflet_id: Math.random(),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
import L from "leaflet";
|
||||||
|
import EndIcon from "../../../../components/gisPolylines/icons/EndIcon";
|
||||||
|
//console.log("console log EndIcon: ", EndIcon);
|
||||||
|
describe("endIcon", () => {
|
||||||
|
test("should be a custom-end-icon with correct HTML and styles", () => {
|
||||||
|
expect(EndIcon.options.className).toBe("custom-end-icon");
|
||||||
|
expect(EndIcon.options.html).toBe("<div style='background-color: gray; width: 14px; height: 14px; border: solid black 2px;'></div>");
|
||||||
|
expect(EndIcon.options.iconSize).toEqual([14, 14]);
|
||||||
|
expect(EndIcon.options.iconAnchor).toEqual([7, 7]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// __tests__/components/gisPolylines/icons/StartIcon.test.js
|
||||||
|
jest.mock("leaflet", () => {
|
||||||
|
const actualLeaflet = jest.requireActual("leaflet");
|
||||||
|
return {
|
||||||
|
...actualLeaflet,
|
||||||
|
DivIcon: jest.fn().mockImplementation((options) => ({
|
||||||
|
...options,
|
||||||
|
options,
|
||||||
|
_leaflet_id: Math.random(),
|
||||||
|
_createIcon: jest.fn(),
|
||||||
|
_createImg: jest.fn(),
|
||||||
|
_getIconUrl: jest.fn(),
|
||||||
|
_initHooks: [],
|
||||||
|
_initHooksCalled: true,
|
||||||
|
_setIconStyles: jest.fn(),
|
||||||
|
callInitHooks: jest.fn(),
|
||||||
|
createIcon: jest.fn(),
|
||||||
|
createShadow: jest.fn(),
|
||||||
|
initialize: jest.fn(),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
import L from "leaflet";
|
||||||
|
import StartIcon from "../../../../../components/gisPolylines/icons/StartIcon";
|
||||||
|
|
||||||
|
describe("StartIcon", () => {
|
||||||
|
test("should be a Leaflet divIcon with correct properties", () => {
|
||||||
|
//console.log("StartIcon options:", StartIcon.options);
|
||||||
|
expect(StartIcon).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
options: expect.objectContaining({
|
||||||
|
className: "custom-start-icon",
|
||||||
|
html: expect.stringContaining("<svg"),
|
||||||
|
iconSize: [18, 18],
|
||||||
|
iconAnchor: [9, 10],
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
42
__tests__/unit/hooks/useLineData.test.js
Normal file
42
__tests__/unit/hooks/useLineData.test.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { renderHook, act, waitFor } from "@testing-library/react";
|
||||||
|
import useLineData from "../../../hooks/useLineData";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const mockUrl = "http://mockurl.com";
|
||||||
|
const mockData1 = {
|
||||||
|
Statis: [{ IdLD: 1, Modul: "mod1", PrioColor: "red", ModulName: "Module 1", ModulTyp: "Type 1", Message: "Message 1", PrioName: "High", DpName: "DP 1", Value: "Value 1" }],
|
||||||
|
};
|
||||||
|
const mockData2 = [{ idLD: 1, idModul: "mod1" }];
|
||||||
|
|
||||||
|
global.fetch = jest.fn((url) => {
|
||||||
|
if (url === mockUrl) {
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve(mockData1),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve(mockData2),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("useLineData", () => {
|
||||||
|
test("should fetch line data and set line colors and tooltip contents", async () => {
|
||||||
|
const setLineStatusData = jest.fn();
|
||||||
|
|
||||||
|
const { result } = renderHook(() => useLineData(mockUrl, setLineStatusData));
|
||||||
|
|
||||||
|
await waitFor(
|
||||||
|
() => {
|
||||||
|
expect(setLineStatusData).toHaveBeenCalledWith(expect.any(Array));
|
||||||
|
expect(result.current).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
lineColors: expect.any(Object),
|
||||||
|
tooltipContents: expect.any(Object),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ timeout: 5000 } // Increase the timeout to 5000ms
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
86
__tests__/unit/pois/AddPoiModalWindow.test.js
Normal file
86
__tests__/unit/pois/AddPoiModalWindow.test.js
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
// __tests__/components/pois/AddPoiModalWindow.test.js
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
import AddPoiModalWindow from "../../../components/pois/AddPoiModalWindow";
|
||||||
|
import { RecoilRoot } from "recoil";
|
||||||
|
|
||||||
|
// Mock für die fetch-Funktion
|
||||||
|
global.fetch = jest.fn((url) => {
|
||||||
|
if (url === "/api/talas_v5_DB/poiTyp/readPoiTyp") {
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]),
|
||||||
|
});
|
||||||
|
} else if (url === "/api/talas5/location_device") {
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve([{ idLD: "1", name: "Device1" }]),
|
||||||
|
});
|
||||||
|
} else if (url === "/api/talas_v5_DB/pois/addLocation") {
|
||||||
|
return Promise.resolve({ ok: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("AddPoiModalWindow", () => {
|
||||||
|
const mockOnClose = jest.fn();
|
||||||
|
const mockMap = {
|
||||||
|
closePopup: jest.fn(),
|
||||||
|
};
|
||||||
|
const mockLatLng = { lat: 52.52, lng: 13.405 };
|
||||||
|
|
||||||
|
// Mock window.location.reload
|
||||||
|
beforeAll(() => {
|
||||||
|
Object.defineProperty(window, "location", {
|
||||||
|
value: {
|
||||||
|
...window.location,
|
||||||
|
reload: jest.fn(),
|
||||||
|
},
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fetch.mockClear();
|
||||||
|
window.location.reload.mockClear(); // Clear the mock before each test
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders correctly and allows form submission", async () => {
|
||||||
|
await act(async () => {
|
||||||
|
render(
|
||||||
|
<RecoilRoot>
|
||||||
|
<AddPoiModalWindow onClose={mockOnClose} map={mockMap} latlng={mockLatLng} />
|
||||||
|
</RecoilRoot>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Überprüfen, ob die Formularelemente gerendert werden
|
||||||
|
expect(screen.getByLabelText(/Name/i)).toBeInTheDocument();
|
||||||
|
expect(screen.getByLabelText(/Gerät/i)).toBeInTheDocument();
|
||||||
|
expect(screen.getByLabelText(/Typ/i)).toBeInTheDocument();
|
||||||
|
expect(screen.getByText(/Lat/i)).toHaveTextContent(`Lat : ${mockLatLng.lat.toFixed(5)}`);
|
||||||
|
expect(screen.getByText(/Lng/i)).toHaveTextContent(`Lng : ${mockLatLng.lng.toFixed(5)}`);
|
||||||
|
|
||||||
|
// Simulieren der Eingabe in das Namensfeld
|
||||||
|
fireEvent.change(screen.getByLabelText(/Name/i), { target: { value: "New POI" } });
|
||||||
|
expect(screen.getByLabelText(/Name/i)).toHaveValue("New POI");
|
||||||
|
|
||||||
|
// Simulieren der Auswahl eines Geräts
|
||||||
|
fireEvent.change(screen.getByLabelText(/Gerät/i), { target: { value: "Device1" } });
|
||||||
|
expect(screen.getByLabelText(/Gerät/i)).toHaveValue("Device1");
|
||||||
|
|
||||||
|
// Simulieren der Auswahl eines Typs
|
||||||
|
fireEvent.change(screen.getByLabelText(/Typ/i), { target: { value: "1" } });
|
||||||
|
expect(screen.getByLabelText(/Typ/i)).toHaveValue("1");
|
||||||
|
|
||||||
|
// Simulieren des Formulareingabeverfahrens
|
||||||
|
fireEvent.submit(screen.getByRole("button", { name: /POI hinzufügen/i }));
|
||||||
|
|
||||||
|
// Warten auf die Formulareinreichung und Überprüfen der Ergebnisse
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockOnClose).toHaveBeenCalled();
|
||||||
|
expect(mockMap.closePopup).toHaveBeenCalled();
|
||||||
|
expect(fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/addLocation", expect.any(Object));
|
||||||
|
expect(window.location.reload).toHaveBeenCalled(); // Verify that reload was called
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
77
__tests__/unit/pois/AddPoiModalWindowPopup.test.js
Normal file
77
__tests__/unit/pois/AddPoiModalWindowPopup.test.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// __tests__/components/pois/AddPoiModalWindowPopup.test.js
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { render, screen, fireEvent } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
import AddPoiModalWindowPopup from "../../../components/pois/AddPoiModalWindowPopup";
|
||||||
|
|
||||||
|
// Mock the AddPoiModalWindow component
|
||||||
|
jest.mock("../../../components/pois/AddPoiModalWindow", () => ({ onClose, onSubmit, latlng }) => (
|
||||||
|
<div data-testid="add-poi-modal-window">
|
||||||
|
<button onClick={() => console.log("Mocked Close Modal Click")}>Close Modal</button>
|
||||||
|
<button onClick={onSubmit}>Submit</button>
|
||||||
|
<div>
|
||||||
|
Coordinates: {latlng.lat}, {latlng.lng}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
describe("AddPoiModalWindowPopup", () => {
|
||||||
|
const closePopupMock = jest.fn();
|
||||||
|
const handleAddStationMock = jest.fn();
|
||||||
|
const popupCoordinatesMock = { lat: 52.52, lng: 13.405 };
|
||||||
|
|
||||||
|
// Suppress console.log for the duration of these tests
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(console, "log").mockImplementation(() => {});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Restore console.log after all tests
|
||||||
|
afterAll(() => {
|
||||||
|
console.log.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
closePopupMock.mockClear();
|
||||||
|
handleAddStationMock.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders the popup when showPopup is true", () => {
|
||||||
|
render(<AddPoiModalWindowPopup showPopup={true} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||||
|
|
||||||
|
expect(screen.getByTestId("add-poi-modal-window")).toBeInTheDocument();
|
||||||
|
expect(screen.getByText("Coordinates: 52.52, 13.405")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not render the popup when showPopup is false", () => {
|
||||||
|
render(<AddPoiModalWindowPopup showPopup={false} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||||
|
|
||||||
|
expect(screen.queryByTestId("add-poi-modal-window")).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("closes the popup when the top right close button is clicked", () => {
|
||||||
|
render(<AddPoiModalWindowPopup showPopup={true} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||||
|
|
||||||
|
// Use the aria-label to uniquely identify the close button in the outer component
|
||||||
|
const closeButton = screen.getByRole("button", { name: "Close" });
|
||||||
|
|
||||||
|
// Click the button with aria-label "Close"
|
||||||
|
fireEvent.click(closeButton);
|
||||||
|
expect(closePopupMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("submits the form when the submit button is clicked", () => {
|
||||||
|
render(<AddPoiModalWindowPopup showPopup={true} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("Submit"));
|
||||||
|
expect(handleAddStationMock).toHaveBeenCalledTimes(1); // This should now pass
|
||||||
|
});
|
||||||
|
|
||||||
|
test('clicking the "Close Modal" button inside AddPoiModalWindow should not close the popup', () => {
|
||||||
|
render(<AddPoiModalWindowPopup showPopup={true} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||||
|
|
||||||
|
// Click the "Close Modal" button inside the mock
|
||||||
|
fireEvent.click(screen.getByText("Close Modal"));
|
||||||
|
expect(closePopupMock).toHaveBeenCalledTimes(0); // Should not call the popup close
|
||||||
|
});
|
||||||
|
});
|
||||||
75
__tests__/unit/pois/AddPoiModalWindowWrapper.test.js
Normal file
75
__tests__/unit/pois/AddPoiModalWindowWrapper.test.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
// __tests__/components/pois/AddPoiModalWindowWrapper.test.js
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { render, screen, fireEvent } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
import AddPoiModalWindowWrapper from "../../../components/pois/AddPoiModalWindowWrapper";
|
||||||
|
|
||||||
|
// Mock the AddPoiModalWindow component to avoid testing its internal implementation here
|
||||||
|
jest.mock("../../../components/pois/AddPoiModalWindow", () => ({ onClose, onSubmit, latlng }) => (
|
||||||
|
<div data-testid="add-poi-modal-window">
|
||||||
|
<button onClick={onClose}>Mocked Close</button>
|
||||||
|
<button onClick={onSubmit}>Mocked Submit</button>
|
||||||
|
<div>
|
||||||
|
Mocked Coordinates: {latlng.lat}, {latlng.lng}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
describe("AddPoiModalWindowWrapper", () => {
|
||||||
|
const onCloseMock = jest.fn();
|
||||||
|
const handleAddStationMock = jest.fn();
|
||||||
|
const latlngMock = { lat: 52.52, lng: 13.405 };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
onCloseMock.mockClear();
|
||||||
|
handleAddStationMock.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders the modal when 'show' is true", () => {
|
||||||
|
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||||
|
|
||||||
|
// Check if the modal and its contents are in the document
|
||||||
|
expect(screen.getByTestId("add-poi-modal-window")).toBeInTheDocument();
|
||||||
|
expect(screen.getByText("Mocked Coordinates: 52.52, 13.405")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not render the modal when 'show' is false", () => {
|
||||||
|
render(<AddPoiModalWindowWrapper show={false} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||||
|
|
||||||
|
// Check if the modal is not in the document
|
||||||
|
expect(screen.queryByTestId("add-poi-modal-window")).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("calls onClose when the close button is clicked", () => {
|
||||||
|
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||||
|
|
||||||
|
// Click the close button
|
||||||
|
fireEvent.click(screen.getByRole("button", { name: "Close" }));
|
||||||
|
expect(onCloseMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("calls onClose when the background is clicked", () => {
|
||||||
|
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||||
|
|
||||||
|
// Click the background overlay
|
||||||
|
fireEvent.click(screen.getByTestId("modal-overlay"));
|
||||||
|
expect(onCloseMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not call onClose when the modal content is clicked", () => {
|
||||||
|
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||||
|
|
||||||
|
// Click the modal content
|
||||||
|
fireEvent.click(screen.getByRole("dialog"));
|
||||||
|
expect(onCloseMock).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("calls handleAddStation when the submit button is clicked", () => {
|
||||||
|
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||||
|
|
||||||
|
// Click the submit button
|
||||||
|
fireEvent.click(screen.getByText("Mocked Submit"));
|
||||||
|
expect(handleAddStationMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
117
__tests__/unit/pois/PoiUpdateModal.test.js
Normal file
117
__tests__/unit/pois/PoiUpdateModal.test.js
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
// __tests__/components/pois/PoiUpdateModal.test.js
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
import PoiUpdateModal from "../../../components/pois/PoiUpdateModal";
|
||||||
|
import { useRecoilValue } from "recoil";
|
||||||
|
import { selectedPoiState, currentPoiState } from "../../../store/atoms/poiState";
|
||||||
|
|
||||||
|
// Mock the recoil states
|
||||||
|
jest.mock("recoil");
|
||||||
|
|
||||||
|
describe("PoiUpdateModal", () => {
|
||||||
|
const mockOnClose = jest.fn();
|
||||||
|
const mockOnSubmit = jest.fn();
|
||||||
|
const poiDataMock = {
|
||||||
|
idPoi: "123",
|
||||||
|
name: "Test POI",
|
||||||
|
description: "Test Description",
|
||||||
|
idPoiTyp: "1",
|
||||||
|
idLD: "2",
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedPoiMock = {
|
||||||
|
idPoi: "123",
|
||||||
|
typ: "Type1",
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentPoiMock = {
|
||||||
|
idLD: "2",
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
useRecoilValue.mockImplementation((state) => {
|
||||||
|
if (state === selectedPoiState) return selectedPoiMock;
|
||||||
|
if (state === currentPoiState) return currentPoiMock;
|
||||||
|
});
|
||||||
|
|
||||||
|
mockOnClose.mockClear();
|
||||||
|
mockOnSubmit.mockClear();
|
||||||
|
|
||||||
|
global.fetch = jest.fn((url) => {
|
||||||
|
if (url === "/api/talas_v5_DB/poiTyp/readPoiTyp") {
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]),
|
||||||
|
});
|
||||||
|
} else if (url === "/api/talas_v5_DB/locationDevice/locationDevices") {
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve([{ id: "2", name: "Device1" }]),
|
||||||
|
});
|
||||||
|
} else if (url.startsWith("/api/talas_v5_DB/locationDevice/getDeviceId")) {
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve({ idLD: "2", name: "Device1" }),
|
||||||
|
});
|
||||||
|
} else if (url.startsWith("/api/talas_v5_DB/pois/deletePoi")) {
|
||||||
|
return Promise.resolve({ ok: true });
|
||||||
|
} else if (url === "/api/talas_v5_DB/pois/updatePoi") {
|
||||||
|
return Promise.resolve({ ok: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
global.alert = jest.fn(); // Mock alert
|
||||||
|
delete window.location;
|
||||||
|
window.location = { reload: jest.fn() }; // Mock location.reload
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders modal with correct data", async () => {
|
||||||
|
await act(async () => {
|
||||||
|
render(<PoiUpdateModal onClose={mockOnClose} poiData={poiDataMock} onSubmit={mockOnSubmit} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.getByDisplayValue("Test Description")).toBeInTheDocument();
|
||||||
|
expect(screen.getByDisplayValue("Device1")).toBeInTheDocument();
|
||||||
|
expect(screen.getByDisplayValue("Type1")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles POI update submission", async () => {
|
||||||
|
await act(async () => {
|
||||||
|
render(<PoiUpdateModal onClose={mockOnClose} poiData={poiDataMock} onSubmit={mockOnSubmit} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.change(screen.getByLabelText("Beschreibung:"), { target: { value: "Updated Description" } });
|
||||||
|
fireEvent.click(screen.getByText("POI aktualisieren"));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(global.fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/updatePoi", expect.any(Object));
|
||||||
|
expect(mockOnClose).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles POI deletion", async () => {
|
||||||
|
window.confirm = jest.fn().mockImplementation(() => true); // Mock confirm dialog to always accept
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
render(<PoiUpdateModal onClose={mockOnClose} poiData={poiDataMock} onSubmit={mockOnSubmit} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("POI löschen"));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(global.fetch).toHaveBeenCalledWith(expect.stringContaining("/api/talas_v5_DB/pois/deletePoi"), { method: "DELETE" });
|
||||||
|
expect(mockOnClose).toHaveBeenCalledTimes(1);
|
||||||
|
expect(window.location.reload).toHaveBeenCalledTimes(1);
|
||||||
|
expect(global.alert).toHaveBeenCalledWith("POI wurde erfolgreich gelöscht.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("closes the modal when the close button is clicked", async () => {
|
||||||
|
await act(async () => {
|
||||||
|
render(<PoiUpdateModal onClose={mockOnClose} poiData={poiDataMock} onSubmit={mockOnSubmit} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByLabelText("Close"));
|
||||||
|
|
||||||
|
expect(mockOnClose).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
57
__tests__/unit/pois/PoiUpdateModalWindow.test.js
Normal file
57
__tests__/unit/pois/PoiUpdateModalWindow.test.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// __tests__/components/pois/PoiUpdateModalWindow.test.js
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
import PoiUpdateModalWindow from "../../../components/pois/PoiUpdateModalWindow";
|
||||||
|
import PoiUpdateModal from "../../../components/pois/PoiUpdateModal";
|
||||||
|
|
||||||
|
// Mock the PoiUpdateModal component to avoid testing its internal implementation here
|
||||||
|
jest.mock("../../../components/pois/PoiUpdateModal", () => ({ onClose, poiData, onSubmit, latlng }) => (
|
||||||
|
<div data-testid="poi-update-modal">
|
||||||
|
<button onClick={onClose}>Close</button>
|
||||||
|
<div>POI Data: {poiData ? poiData.name : "No Data"}</div>
|
||||||
|
<div>LatLng: {latlng ? `${latlng.lat}, ${latlng.lng}` : "No Coordinates"}</div>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
describe("PoiUpdateModalWindow", () => {
|
||||||
|
const closePoiUpdateModalMock = jest.fn();
|
||||||
|
const currentPoiDataMock = {
|
||||||
|
idPoi: "123",
|
||||||
|
name: "Test POI",
|
||||||
|
description: "Test Description",
|
||||||
|
idPoiTyp: "1",
|
||||||
|
idLD: "2",
|
||||||
|
};
|
||||||
|
|
||||||
|
const popupCoordinatesMock = { lat: 52.52, lng: 13.405 };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
closePoiUpdateModalMock.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders PoiUpdateModal when showPoiUpdateModal is true", () => {
|
||||||
|
render(<PoiUpdateModalWindow showPoiUpdateModal={true} closePoiUpdateModal={closePoiUpdateModalMock} currentPoiData={currentPoiDataMock} popupCoordinates={popupCoordinatesMock} />);
|
||||||
|
|
||||||
|
// Check if the modal and its contents are in the document
|
||||||
|
expect(screen.getByTestId("poi-update-modal")).toBeInTheDocument();
|
||||||
|
expect(screen.getByText("POI Data: Test POI")).toBeInTheDocument();
|
||||||
|
expect(screen.getByText("LatLng: 52.52, 13.405")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not render PoiUpdateModal when showPoiUpdateModal is false", () => {
|
||||||
|
render(<PoiUpdateModalWindow showPoiUpdateModal={false} closePoiUpdateModal={closePoiUpdateModalMock} currentPoiData={currentPoiDataMock} popupCoordinates={popupCoordinatesMock} />);
|
||||||
|
|
||||||
|
// Check if the modal is not in the document
|
||||||
|
expect(screen.queryByTestId("poi-update-modal")).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("calls closePoiUpdateModal when the close button is clicked", () => {
|
||||||
|
render(<PoiUpdateModalWindow showPoiUpdateModal={true} closePoiUpdateModal={closePoiUpdateModalMock} currentPoiData={currentPoiDataMock} popupCoordinates={popupCoordinatesMock} />);
|
||||||
|
|
||||||
|
// Click the close button
|
||||||
|
screen.getByText("Close").click();
|
||||||
|
expect(closePoiUpdateModalMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
79
__tests__/unit/pois/PoiUpdateModalWrapper.test.js
Normal file
79
__tests__/unit/pois/PoiUpdateModalWrapper.test.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// __tests__/components/pois/PoiUpdateModalWrapper.test.js
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { render, screen, fireEvent, act } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
import PoiUpdateModalWrapper from "../../../components/pois/PoiUpdateModalWrapper";
|
||||||
|
import { useRecoilValue, useSetRecoilState } from "recoil";
|
||||||
|
import { currentPoiState, selectedPoiState } from "../../../store/atoms/poiState";
|
||||||
|
import { poiReadFromDbTriggerAtom } from "../../../store/atoms/poiReadFromDbTriggerAtom";
|
||||||
|
|
||||||
|
// Mock Recoil hooks
|
||||||
|
jest.mock("recoil");
|
||||||
|
|
||||||
|
describe("PoiUpdateModalWrapper", () => {
|
||||||
|
const mockOnClose = jest.fn();
|
||||||
|
const currentPoiMock = {
|
||||||
|
idPoi: "123",
|
||||||
|
name: "Test POI",
|
||||||
|
description: "Test Description",
|
||||||
|
idPoiTyp: "1",
|
||||||
|
idLD: "2",
|
||||||
|
};
|
||||||
|
const latlngMock = { lat: 52.52, lng: 13.405 };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// Mock the recoil values
|
||||||
|
useRecoilValue.mockImplementation((atom) => {
|
||||||
|
if (atom === currentPoiState) return currentPoiMock;
|
||||||
|
if (atom === poiReadFromDbTriggerAtom) return 0;
|
||||||
|
});
|
||||||
|
useSetRecoilState.mockImplementation(() => jest.fn());
|
||||||
|
|
||||||
|
mockOnClose.mockClear();
|
||||||
|
|
||||||
|
// Mock global fetch
|
||||||
|
global.fetch = jest.fn((url) =>
|
||||||
|
Promise.resolve({
|
||||||
|
json: () => {
|
||||||
|
if (url.includes("getDeviceIdById")) {
|
||||||
|
return Promise.resolve({ idLD: "2", name: "Device1" });
|
||||||
|
}
|
||||||
|
if (url.includes("readPoiTyp")) {
|
||||||
|
return Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]);
|
||||||
|
}
|
||||||
|
if (url.includes("locationDevices")) {
|
||||||
|
return Promise.resolve([{ id: "2", name: "Device1" }]);
|
||||||
|
}
|
||||||
|
return Promise.resolve({});
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders PoiUpdateModal when 'show' is true", async () => {
|
||||||
|
await act(async () => {
|
||||||
|
render(<PoiUpdateModalWrapper show={true} onClose={mockOnClose} latlng={latlngMock} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if the modal and its contents are in the document
|
||||||
|
expect(screen.getByDisplayValue("Test Description")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not render PoiUpdateModal when 'show' is false", () => {
|
||||||
|
render(<PoiUpdateModalWrapper show={false} onClose={mockOnClose} latlng={latlngMock} />);
|
||||||
|
|
||||||
|
// Check if the modal is not in the document
|
||||||
|
expect(screen.queryByDisplayValue("Test POI")).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("calls onClose when the modal close button is clicked", async () => {
|
||||||
|
await act(async () => {
|
||||||
|
render(<PoiUpdateModalWrapper show={true} onClose={mockOnClose} latlng={latlngMock} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Simulate closing the modal
|
||||||
|
fireEvent.click(screen.getByLabelText("Close"));
|
||||||
|
expect(mockOnClose).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
111
__tests__/unit/pois/PoiUtils.test.js
Normal file
111
__tests__/unit/pois/PoiUtils.test.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
// __tests__/components/pois/PoiUtils.test.js
|
||||||
|
|
||||||
|
import { createPoiMarkers, addMarkersToMap, updateLocationInDatabase } from "../../../components/pois/PoiUtils";
|
||||||
|
|
||||||
|
// Mock Leaflet
|
||||||
|
jest.mock("leaflet", () => {
|
||||||
|
const Leaflet = {
|
||||||
|
marker: jest.fn((latlng, options) => ({
|
||||||
|
addTo: jest.fn(),
|
||||||
|
on: jest.fn(),
|
||||||
|
options: options,
|
||||||
|
getLatLng: jest.fn(() => ({
|
||||||
|
lat: latlng[0],
|
||||||
|
lng: latlng[1],
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
icon: jest.fn((options) => options),
|
||||||
|
};
|
||||||
|
return Leaflet;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("PoiUtils", () => {
|
||||||
|
describe("createPoiMarkers", () => {
|
||||||
|
it("should create markers with correct coordinates and icon", () => {
|
||||||
|
const poiData = [
|
||||||
|
{ idPoi: "1", latitude: 52.52, longitude: 13.405 },
|
||||||
|
{ idPoi: "2", latitude: 48.8566, longitude: 2.3522 },
|
||||||
|
];
|
||||||
|
const iconPath = "path/to/icon.png";
|
||||||
|
const markers = createPoiMarkers(poiData, iconPath);
|
||||||
|
|
||||||
|
expect(markers).toHaveLength(2);
|
||||||
|
|
||||||
|
markers.forEach((marker, index) => {
|
||||||
|
expect(marker.options.icon.iconUrl).toBe(iconPath);
|
||||||
|
expect(marker.options.icon.iconSize).toEqual([25, 41]);
|
||||||
|
expect(marker.options.id).toBe(poiData[index].idPoi);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("addMarkersToMap", () => {
|
||||||
|
it("should add markers to map and bind events", () => {
|
||||||
|
const mockMap = {};
|
||||||
|
const mockLayerGroup = { addLayer: jest.fn() };
|
||||||
|
const mockMarker = {
|
||||||
|
addTo: jest.fn(),
|
||||||
|
on: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const markers = [mockMarker, mockMarker];
|
||||||
|
|
||||||
|
addMarkersToMap(markers, mockMap, mockLayerGroup);
|
||||||
|
|
||||||
|
markers.forEach((marker) => {
|
||||||
|
expect(marker.addTo).toHaveBeenCalledWith(mockLayerGroup);
|
||||||
|
expect(marker.on).toHaveBeenCalledWith("mouseover", expect.any(Function));
|
||||||
|
expect(marker.on).toHaveBeenCalledWith("mouseout", expect.any(Function));
|
||||||
|
expect(marker.on).toHaveBeenCalledWith("dragend", expect.any(Function));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("updateLocationInDatabase", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
global.fetch = jest.fn(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
json: () => Promise.resolve({}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call fetch with correct parameters", async () => {
|
||||||
|
const id = "1";
|
||||||
|
const newLatitude = 52.52;
|
||||||
|
const newLongitude = 13.405;
|
||||||
|
|
||||||
|
await updateLocationInDatabase(id, newLatitude, newLongitude);
|
||||||
|
|
||||||
|
expect(fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/updateLocation", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
id,
|
||||||
|
latitude: newLatitude,
|
||||||
|
longitude: newLongitude,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should log error when fetch response is not ok", async () => {
|
||||||
|
console.error = jest.fn();
|
||||||
|
|
||||||
|
global.fetch = jest.fn(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
ok: false,
|
||||||
|
json: () => Promise.resolve({}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await updateLocationInDatabase("1", 52.52, 13.405);
|
||||||
|
|
||||||
|
expect(console.error).toHaveBeenCalledWith("Fehler beim Aktualisieren der Position");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
6
__tests__/unit/utils/mapUtils.test.js
Normal file
6
__tests__/unit/utils/mapUtils.test.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// __tests__/utils/mapUtils.test.js
|
||||||
|
describe("Dummy test suite", () => {
|
||||||
|
test("dummy test", () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
3
babel.config.js
Normal file
3
babel.config.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: ["@babel/preset-env", "@babel/preset-react"],
|
||||||
|
};
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// components/DataSheet.js
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||||
import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState";
|
import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState";
|
||||||
@@ -5,18 +6,15 @@ import { gisSystemStaticState } from "../store/atoms/gisSystemState";
|
|||||||
import { mapLayersState } from "../store/atoms/mapLayersState";
|
import { mapLayersState } from "../store/atoms/mapLayersState";
|
||||||
import { selectedAreaState } from "../store/atoms/selectedAreaState";
|
import { selectedAreaState } from "../store/atoms/selectedAreaState";
|
||||||
import { zoomTriggerState } from "../store/atoms/zoomTriggerState";
|
import { zoomTriggerState } from "../store/atoms/zoomTriggerState";
|
||||||
import { poiLayerVisibleState } from "../store/atoms/poiLayerVisible";
|
import { poiLayerVisibleState } from "../store/atoms/poiLayerVisibleState";
|
||||||
|
|
||||||
function DataSheet() {
|
function DataSheet() {
|
||||||
const [poiVisible, setPoiVisible] = useRecoilState(poiLayerVisibleState);
|
const [poiVisible, setPoiVisible] = useRecoilState(poiLayerVisibleState);
|
||||||
const setSelectedArea = useSetRecoilState(selectedAreaState);
|
const setSelectedArea = useSetRecoilState(selectedAreaState);
|
||||||
const [mapLayersVisibility, setMapLayersVisibility] =
|
const [mapLayersVisibility, setMapLayersVisibility] = useRecoilState(mapLayersState);
|
||||||
useRecoilState(mapLayersState);
|
|
||||||
const [stationListing, setStationListing] = useState([]);
|
const [stationListing, setStationListing] = useState([]);
|
||||||
const [systemListing, setSystemListing] = useState([]);
|
const [systemListing, setSystemListing] = useState([]);
|
||||||
const GisStationsStaticDistrict = useRecoilValue(
|
const GisStationsStaticDistrict = useRecoilValue(gisStationsStaticDistrictState);
|
||||||
gisStationsStaticDistrictState
|
|
||||||
);
|
|
||||||
const GisSystemStatic = useRecoilValue(gisSystemStaticState);
|
const GisSystemStatic = useRecoilValue(gisSystemStaticState);
|
||||||
const setZoomTrigger = useSetRecoilState(zoomTriggerState);
|
const setZoomTrigger = useSetRecoilState(zoomTriggerState);
|
||||||
|
|
||||||
@@ -24,30 +22,31 @@ function DataSheet() {
|
|||||||
const selectedIndex = event.target.options.selectedIndex;
|
const selectedIndex = event.target.options.selectedIndex;
|
||||||
const areaName = event.target.options[selectedIndex].text;
|
const areaName = event.target.options[selectedIndex].text;
|
||||||
setSelectedArea(areaName);
|
setSelectedArea(areaName);
|
||||||
console.log("Area selected oder areaName in DataSheet.js:", areaName);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const allowedSystems = new Set(
|
console.log("GisStationsStaticDistrict:", GisStationsStaticDistrict);
|
||||||
GisSystemStatic.filter((system) => system.Allow === 1).map(
|
console.log("GisSystemStatic:", GisSystemStatic);
|
||||||
(system) => system.IdSystem
|
const allowedSystems = new Set(GisSystemStatic.filter((system) => system.Allow === 1).map((system) => system.IdSystem));
|
||||||
)
|
console.log("allowedSystems:", allowedSystems);
|
||||||
);
|
|
||||||
const seenNames = new Set();
|
const seenNames = new Set();
|
||||||
const filteredAreas = GisStationsStaticDistrict.filter((item) => {
|
const filteredAreas = GisStationsStaticDistrict.filter((item) => {
|
||||||
const isUnique =
|
const isUnique = !seenNames.has(item.Area_Name) && allowedSystems.has(item.System);
|
||||||
!seenNames.has(item.Area_Name) && allowedSystems.has(item.System);
|
|
||||||
if (isUnique) {
|
if (isUnique) {
|
||||||
seenNames.add(item.Area_Name);
|
seenNames.add(item.Area_Name);
|
||||||
}
|
}
|
||||||
return isUnique;
|
return isUnique;
|
||||||
});
|
});
|
||||||
|
|
||||||
setStationListing(
|
setStationListing(
|
||||||
filteredAreas.map((area, index) => ({
|
filteredAreas.map((area, index) => ({
|
||||||
id: index + 1,
|
id: index + 1,
|
||||||
name: area.Area_Name,
|
name: area.Area_Name,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
//console.log("filteredAreas:", filteredAreas);
|
||||||
|
|
||||||
const seenSystemNames = new Set();
|
const seenSystemNames = new Set();
|
||||||
const filteredSystems = GisSystemStatic.filter((item) => {
|
const filteredSystems = GisSystemStatic.filter((item) => {
|
||||||
const formattedName = item.Name.replace(/[\s\-]+/g, "");
|
const formattedName = item.Name.replace(/[\s\-]+/g, "");
|
||||||
@@ -57,6 +56,7 @@ function DataSheet() {
|
|||||||
}
|
}
|
||||||
return isUnique;
|
return isUnique;
|
||||||
});
|
});
|
||||||
|
|
||||||
setSystemListing(
|
setSystemListing(
|
||||||
filteredSystems.map((system, index) => ({
|
filteredSystems.map((system, index) => ({
|
||||||
id: index + 1,
|
id: index + 1,
|
||||||
@@ -64,19 +64,21 @@ function DataSheet() {
|
|||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
}, [GisStationsStaticDistrict, GisSystemStatic]);
|
}, [GisStationsStaticDistrict, GisSystemStatic]);
|
||||||
|
//}, []);
|
||||||
|
//-----------------------------------------
|
||||||
|
//-----------------------------------------
|
||||||
|
|
||||||
const handleCheckboxChange = (name, event) => {
|
const handleCheckboxChange = (name, event) => {
|
||||||
const { checked } = event.target;
|
const { checked } = event.target;
|
||||||
console.log(`Checkbox ${name} checked state:`, checked);
|
|
||||||
|
|
||||||
setMapLayersVisibility((prev) => {
|
setMapLayersVisibility((prev) => {
|
||||||
const newState = {
|
const newState = {
|
||||||
...prev,
|
...prev,
|
||||||
[name]: checked,
|
[name]: checked,
|
||||||
};
|
};
|
||||||
console.log(`New mapLayersVisibility state:`, newState);
|
|
||||||
return newState;
|
return newState;
|
||||||
});
|
});
|
||||||
|
console.log("mapLayersVisibility:", mapLayersVisibility);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleIconClick = () => {
|
const handleIconClick = () => {
|
||||||
@@ -85,16 +87,14 @@ function DataSheet() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div id="mainDataSheet" className="absolute top-3 right-3 w-1/6 min-w-[300px] z-10 bg-white p-2 rounded-lg shadow-lg">
|
||||||
id="mainDataSheet"
|
|
||||||
className="absolute top-3 right-3 w-1/6 min-w-[300px] z-10 bg-white p-2 rounded-lg shadow-lg"
|
|
||||||
>
|
|
||||||
<div className="flex flex-col gap-4 p-4">
|
<div className="flex flex-col gap-4 p-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<select
|
<select
|
||||||
onChange={handleAreaChange}
|
onChange={handleAreaChange}
|
||||||
id="stationListing"
|
id="stationListing"
|
||||||
className="border-solid-1 p-2 rounded ml-1 font-semibold"
|
className="border-solid-1 p-2 rounded ml-1 font-semibold"
|
||||||
|
role="combobox" // Ensure the correct role is set
|
||||||
>
|
>
|
||||||
<option value="Station wählen">Station wählen</option>
|
<option value="Station wählen">Station wählen</option>
|
||||||
{stationListing.map((station) => (
|
{stationListing.map((station) => (
|
||||||
@@ -103,22 +103,15 @@ function DataSheet() {
|
|||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
<img
|
<img src="/img/expand-icon.svg" alt="Expand" className="h-6 w-6 ml-2 cursor-pointer" onClick={handleIconClick} />
|
||||||
src="/img/expand-icon.svg"
|
|
||||||
alt="Expand"
|
|
||||||
className="h-6 w-6 ml-2 cursor-pointer"
|
|
||||||
onClick={handleIconClick}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{systemListing.map((system) => (
|
{systemListing.map((system) => (
|
||||||
<React.Fragment key={system.id}>
|
<React.Fragment key={system.id}>
|
||||||
<input
|
<input type="checkbox" checked={mapLayersVisibility[system.name] || false} onChange={(e) => handleCheckboxChange(system.name, e)} id={`system-${system.id}`} />
|
||||||
type="checkbox"
|
<label htmlFor={`system-${system.id}`} className="text-sm ml-2">
|
||||||
checked={mapLayersVisibility[system.name] || false}
|
{system.name}
|
||||||
onChange={(e) => handleCheckboxChange(system.name, e)}
|
</label>
|
||||||
/>
|
|
||||||
<label className="text-sm ml-2">{system.name}</label>
|
|
||||||
<br />
|
<br />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
@@ -128,12 +121,12 @@ function DataSheet() {
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const checked = e.target.checked;
|
const checked = e.target.checked;
|
||||||
setPoiVisible(checked);
|
setPoiVisible(checked);
|
||||||
console.log(
|
|
||||||
`POIs sind jetzt ${checked ? "sichtbar" : "nicht sichtbar"}.`
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
|
id="poi-checkbox"
|
||||||
/>
|
/>
|
||||||
<label className="text-sm ml-2">POIs</label>
|
<label htmlFor="poi-checkbox" className="text-sm ml-2">
|
||||||
|
POIs
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
30
components/VersionInfoModal.js
Normal file
30
components/VersionInfoModal.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// components/VersionInfoModal.js
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const VersionInfoModal = ({ showVersionInfoModal, closeVersionInfoModal, MAP_VERSION }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{showVersionInfoModal && (
|
||||||
|
<div className="fixed inset-0 flex items-center justify-center z-50">
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-50" onClick={closeVersionInfoModal}></div>
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow-lg z-60 max-w-lg mx-auto">
|
||||||
|
<img src="img/Logo_TALAS.png" alt="TALAS V5 Logo" className="w-1/2 mx-auto my-4" />
|
||||||
|
<div className="bg-white border p-6 rounded-lg shadow-lg z-60 max-w-lg mx-auto">
|
||||||
|
<h2 className="text-xl font-bold mb-6 text-start leading-tight">Littwin Systemtechnik GmbH & Co. KG</h2>
|
||||||
|
<h4 className="text-lg font-bold mb-2 text-start leading-tight">Bürgermeister-Brötje Str. 28</h4>
|
||||||
|
<h4 className="text-lg font-bold mb-2 text-start leading-tight">D-26180 Rastede</h4>
|
||||||
|
<h5 className="text-md mb-2 text-start leading-snug">T: +49 4402 9725 77-0</h5>
|
||||||
|
<h5 className="text-md mb-2 text-start leading-snug">E: kontakt@littwin-systemtechnik.de</h5>
|
||||||
|
</div>
|
||||||
|
<p className="text-gray-700 text-center font-bold mt-4 leading-relaxed">TALAS.Map Version {MAP_VERSION}</p>
|
||||||
|
<button onClick={closeVersionInfoModal} className="mt-4 bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-700 mx-auto block">
|
||||||
|
Schließen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VersionInfoModal;
|
||||||
12
components/gisPolylines/icons/CircleIcon.js
Normal file
12
components/gisPolylines/icons/CircleIcon.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// /components/gisPolylines/icons/CircleIcon.js
|
||||||
|
import L from "leaflet";
|
||||||
|
import "leaflet/dist/leaflet.css";
|
||||||
|
|
||||||
|
const CircleIcon = new L.DivIcon({
|
||||||
|
className: "custom-circle-icon leaflet-marker-icon",
|
||||||
|
html: '<div style="background-color:gray; width:10px; height:10px; border-radius:50%; border: solid black 1px;"></div>',
|
||||||
|
iconSize: [25, 25],
|
||||||
|
iconAnchor: [5, 5],
|
||||||
|
});
|
||||||
|
|
||||||
|
export default CircleIcon;
|
||||||
11
components/gisPolylines/icons/EndIcon.js
Normal file
11
components/gisPolylines/icons/EndIcon.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// /components/gisPolylines/icons/EndIcon.js
|
||||||
|
// Viereck als End-Icon für die Route
|
||||||
|
import L from "leaflet";
|
||||||
|
const EndIcon = L.divIcon({
|
||||||
|
className: "custom-end-icon",
|
||||||
|
html: "<div style='background-color: gray; width: 14px; height: 14px; border: solid black 2px;'></div>", // Graues Viereck
|
||||||
|
iconSize: [14, 14],
|
||||||
|
iconAnchor: [7, 7], // Mittelpunkt des Vierecks als Anker
|
||||||
|
});
|
||||||
|
|
||||||
|
export default EndIcon;
|
||||||
17
components/gisPolylines/icons/StartIcon.js
Normal file
17
components/gisPolylines/icons/StartIcon.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// /components/gisPolylines/icons/StartIcon.js
|
||||||
|
//Custom triangle icon for draggable markers
|
||||||
|
import L from "leaflet";
|
||||||
|
|
||||||
|
const StartIcon = L.divIcon({
|
||||||
|
className: "custom-start-icon",
|
||||||
|
html: `
|
||||||
|
<svg width="18" height="18" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<polygon points="10,2 18,18 2,18" fill="black" />
|
||||||
|
<polygon points="10,5 16,16 4,16" fill="gray" />
|
||||||
|
</svg>
|
||||||
|
`, // Schwarzes Dreieck innerhalb eines grauen Dreiecks
|
||||||
|
iconSize: [18, 18],
|
||||||
|
iconAnchor: [9, 10],
|
||||||
|
});
|
||||||
|
|
||||||
|
export default StartIcon;
|
||||||
27
components/gisPolylines/icons/SupportPointIcons.js
Normal file
27
components/gisPolylines/icons/SupportPointIcons.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// komponents/gisPolylines/icons/SupportPointIcons
|
||||||
|
import L from "leaflet";
|
||||||
|
import "leaflet/dist/leaflet.css";
|
||||||
|
|
||||||
|
// Icon für Stützpunkt hinzufügen
|
||||||
|
export const AddSupportPointIcon = L.divIcon({
|
||||||
|
className: "custom-add-support-point-icon",
|
||||||
|
html: `
|
||||||
|
<div style='background-color:green;border-radius:50%;width:12px;height:12px;border: solid white 2px;'>
|
||||||
|
<div style='color: white; font-size: 10px; text-align: center; line-height: 12px;'>+</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
iconSize: [24, 24],
|
||||||
|
iconAnchor: [12, 12],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Icon für Stützpunkt entfernen
|
||||||
|
export const RemoveSupportPointIcon = L.divIcon({
|
||||||
|
className: "custom-remove-support-point-icon",
|
||||||
|
html: `
|
||||||
|
<div style='background-color:red;border-radius:50%;width:12px;height:12px;border: solid white 2px;'>
|
||||||
|
<div style='color: white; font-size: 10px; text-align: center; line-height: 12px;'>-</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
iconSize: [24, 24],
|
||||||
|
iconAnchor: [12, 12],
|
||||||
|
});
|
||||||
160
components/imports.js
Normal file
160
components/imports.js
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
// imports.js
|
||||||
|
import React, { useEffect, useRef, useState, useCallback } from "react";
|
||||||
|
import L, { marker } 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 urls from "../config/urls.js";
|
||||||
|
import "leaflet.smooth_marker_bouncing";
|
||||||
|
import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet";
|
||||||
|
import DataSheet from "./DataSheet.js";
|
||||||
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||||
|
import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState.js";
|
||||||
|
import { gisSystemStaticState } from "../store/atoms/gisSystemState.js";
|
||||||
|
import { mapLayersState } from "../store/atoms/mapLayersState.js";
|
||||||
|
import { selectedAreaState } from "../store/atoms/selectedAreaState.js";
|
||||||
|
import { zoomTriggerState } from "../store/atoms/zoomTriggerState.js";
|
||||||
|
import { poiTypState } from "../store/atoms/poiTypState.js";
|
||||||
|
import AddPoiModalWindow from "./pois/AddPoiModalWindow.js";
|
||||||
|
import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom.js";
|
||||||
|
import { InformationCircleIcon } from "@heroicons/react/20/solid"; // oder 'outline'
|
||||||
|
import PoiUpdateModal from "./pois/PoiUpdateModal.js";
|
||||||
|
import { selectedPoiState } from "../store/atoms/poiState.js";
|
||||||
|
import { currentPoiState } from "../store/atoms/currentPoiState.js";
|
||||||
|
import { ToastContainer, toast } from "react-toastify";
|
||||||
|
import "react-toastify/dist/ReactToastify.css";
|
||||||
|
import { mapIdState, userIdState } from "../store/atoms/urlParameterState.js";
|
||||||
|
import { poiLayerVisibleState } from "../store/atoms/poiLayerVisibleState.js";
|
||||||
|
import plusRoundIcon from "./PlusRoundIcon.js";
|
||||||
|
import { parsePoint, findClosestPoints } from "../utils/geometryUtils.js";
|
||||||
|
import { insertNewMarker, removeMarker, createAndSetMarkers, handleEditPoi } from "../utils/markerUtils.js";
|
||||||
|
import { redrawPolyline, restoreMapSettings, checkOverlappingMarkers } from "../utils/mapUtils.js";
|
||||||
|
import circleIcon from "./gisPolylines/icons/CircleIcon.js";
|
||||||
|
import startIcon from "./gisPolylines/icons/StartIcon.js";
|
||||||
|
import endIcon from "./gisPolylines/icons/EndIcon.js";
|
||||||
|
import { fetchGisStatusStations, fetchPriorityConfig, fetchPoiData, updateLocationInDatabase, fetchUserRights, fetchDeviceNameById } from "../services/apiService.js";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils.js";
|
||||||
|
import { MAP_VERSION } from "../config/settings.js";
|
||||||
|
import * as layers from "../config/layers.js";
|
||||||
|
import { zoomIn, zoomOut, centerHere } from "../utils/zoomAndCenterUtils.js";
|
||||||
|
import { initializeMap } from "../utils/mapInitialization.js";
|
||||||
|
import { addItemsToMapContextMenu } from "./useMapContextMenu.js";
|
||||||
|
import useGmaMarkersLayer from "../hooks/useGmaMarkersLayer.js"; // Import the custom hook
|
||||||
|
import useTalasMarkersLayer from "../hooks/talasMarkersLayer.js"; // Import the custom hook
|
||||||
|
import useEciMarkersLayer from "../hooks/useEciMarkersLayer.js";
|
||||||
|
import useGsmModemMarkersLayer from "../hooks/useGsmModemMarkersLayer.js";
|
||||||
|
import useCiscoRouterMarkersLayer from "../hooks/useCiscoRouterMarkersLayer.js";
|
||||||
|
import useWagoMarkersLayer from "../hooks/useWagoMarkersLayer.js";
|
||||||
|
import useSiemensMarkersLayer from "../hooks/useSiemensMarkersLayer.js";
|
||||||
|
import useOtdrMarkersLayer from "../hooks/useOtdrMarkersLayer.js";
|
||||||
|
import useWdmMarkersLayer from "../hooks/useWdmMarkersLayer.js";
|
||||||
|
import useMessstellenMarkersLayer from "../hooks/useMessstellenMarkersLayer.js";
|
||||||
|
import useTalasiclMarkersLayer from "../hooks/useTalasiclMarkersLayer.js";
|
||||||
|
import useDauzMarkersLayer from "../hooks/useDauzMarkersLayer.js";
|
||||||
|
import useSmsfunkmodemMarkersLayer from "../hooks/useSmsfunkmodemMarkersLayer.js";
|
||||||
|
import useUlafMarkersLayer from "../hooks/useUlafMarkersLayer.js";
|
||||||
|
import useSonstigeMarkersLayer from "../hooks/useSonstigeMarkersLayer.js";
|
||||||
|
import handlePoiSelect from "../utils/handlePoiSelect.js";
|
||||||
|
import { fetchGisStationsStaticDistrict, fetchGisStationsStatusDistrict, fetchGisStationsMeasurements, fetchGisSystemStatic } from "../services/fetchData.js";
|
||||||
|
import { setupPolylines, setupMarkers } from "../utils/mapFeatures.js"; // Import the functions
|
||||||
|
import VersionInfoModal from "./VersionInfoModal.js";
|
||||||
|
//--------------------------------------------
|
||||||
|
import PoiUpdateModalWrapper from "./pois/PoiUpdateModalWrapper";
|
||||||
|
import AddPoiModalWindowWrapper from "./pois/AddPoiModalWindowWrapper";
|
||||||
|
import useFetchPoiData from "../hooks/useFetchPoiData";
|
||||||
|
import usePoiTypData from "../hooks/usePoiTypData";
|
||||||
|
import useMarkerLayers from "../hooks/useMarkerLayers";
|
||||||
|
import useLayerVisibility from "../hooks/useLayerVisibility";
|
||||||
|
import useLineData from "../hooks/useLineData.js";
|
||||||
|
|
||||||
|
export {
|
||||||
|
React,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
useCallback,
|
||||||
|
L,
|
||||||
|
marker,
|
||||||
|
config,
|
||||||
|
urls,
|
||||||
|
OverlappingMarkerSpiderfier,
|
||||||
|
DataSheet,
|
||||||
|
useRecoilState,
|
||||||
|
useRecoilValue,
|
||||||
|
useSetRecoilState,
|
||||||
|
gisStationsStaticDistrictState,
|
||||||
|
gisSystemStaticState,
|
||||||
|
mapLayersState,
|
||||||
|
selectedAreaState,
|
||||||
|
zoomTriggerState,
|
||||||
|
poiTypState,
|
||||||
|
AddPoiModalWindow,
|
||||||
|
poiReadFromDbTriggerAtom,
|
||||||
|
InformationCircleIcon,
|
||||||
|
PoiUpdateModal,
|
||||||
|
selectedPoiState,
|
||||||
|
currentPoiState,
|
||||||
|
ToastContainer,
|
||||||
|
toast,
|
||||||
|
mapIdState,
|
||||||
|
userIdState,
|
||||||
|
poiLayerVisibleState,
|
||||||
|
plusRoundIcon,
|
||||||
|
parsePoint,
|
||||||
|
findClosestPoints,
|
||||||
|
insertNewMarker,
|
||||||
|
removeMarker,
|
||||||
|
createAndSetMarkers,
|
||||||
|
handleEditPoi,
|
||||||
|
redrawPolyline,
|
||||||
|
restoreMapSettings,
|
||||||
|
checkOverlappingMarkers,
|
||||||
|
circleIcon,
|
||||||
|
startIcon,
|
||||||
|
endIcon,
|
||||||
|
fetchGisStatusStations,
|
||||||
|
fetchPriorityConfig,
|
||||||
|
fetchPoiData,
|
||||||
|
updateLocationInDatabase,
|
||||||
|
fetchUserRights,
|
||||||
|
fetchDeviceNameById,
|
||||||
|
addContextMenuToMarker,
|
||||||
|
MAP_VERSION,
|
||||||
|
layers,
|
||||||
|
zoomIn,
|
||||||
|
zoomOut,
|
||||||
|
centerHere,
|
||||||
|
initializeMap,
|
||||||
|
addItemsToMapContextMenu,
|
||||||
|
useGmaMarkersLayer,
|
||||||
|
useTalasMarkersLayer,
|
||||||
|
useEciMarkersLayer,
|
||||||
|
useGsmModemMarkersLayer,
|
||||||
|
useCiscoRouterMarkersLayer,
|
||||||
|
useWagoMarkersLayer,
|
||||||
|
useSiemensMarkersLayer,
|
||||||
|
useOtdrMarkersLayer,
|
||||||
|
useWdmMarkersLayer,
|
||||||
|
useMessstellenMarkersLayer,
|
||||||
|
useTalasiclMarkersLayer,
|
||||||
|
useDauzMarkersLayer,
|
||||||
|
useSmsfunkmodemMarkersLayer,
|
||||||
|
useUlafMarkersLayer,
|
||||||
|
useSonstigeMarkersLayer,
|
||||||
|
handlePoiSelect,
|
||||||
|
fetchGisStationsStaticDistrict,
|
||||||
|
fetchGisStationsStatusDistrict,
|
||||||
|
fetchGisStationsMeasurements,
|
||||||
|
fetchGisSystemStatic,
|
||||||
|
setupPolylines,
|
||||||
|
setupMarkers,
|
||||||
|
VersionInfoModal,
|
||||||
|
PoiUpdateModalWrapper,
|
||||||
|
AddPoiModalWindowWrapper,
|
||||||
|
useFetchPoiData,
|
||||||
|
usePoiTypData,
|
||||||
|
useMarkerLayers,
|
||||||
|
useLayerVisibility,
|
||||||
|
useLineData,
|
||||||
|
};
|
||||||
145
components/pois/AddPoiModalWindow.js
Normal file
145
components/pois/AddPoiModalWindow.js
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
// components/pois/AddPoiModalWindow.js
|
||||||
|
import React, { useState, useEffect, use } from "react";
|
||||||
|
import ReactDOM from "react-dom";
|
||||||
|
import { useRecoilValue, useRecoilState, useSetRecoilState } from "recoil";
|
||||||
|
import { readPoiMarkersStore } from "../../store/selectors/readPoiMarkersStore";
|
||||||
|
import { poiReadFromDbTriggerAtom } from "../../store/atoms/poiReadFromDbTriggerAtom";
|
||||||
|
|
||||||
|
const AddPoiModalWindow = ({ 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 fetchInitialData = async () => {
|
||||||
|
try {
|
||||||
|
const [poiTypResponse, locationDeviceResponse] = await Promise.all([fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"), fetch("/api/talas5/location_device")]);
|
||||||
|
|
||||||
|
const poiTypData = await poiTypResponse.json();
|
||||||
|
setpoiTypData(poiTypData);
|
||||||
|
|
||||||
|
if (poiTypData.length > 0) {
|
||||||
|
setPoiTypeId(poiTypData[0].idPoiTyp); // Set initial poiTypeId to the id of the first poiType
|
||||||
|
if (poiTypData[1]) {
|
||||||
|
setPoiTypeName(poiTypData[1].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const locationDeviceData = await locationDeviceResponse.json();
|
||||||
|
setLocationDeviceData(locationDeviceData);
|
||||||
|
|
||||||
|
if (locationDeviceData.length > 0) {
|
||||||
|
setDeviceName(locationDeviceData[0].name); // Set initial device name
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der Daten:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchInitialData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------
|
||||||
|
//-----------------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;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Browser aktualisieren
|
||||||
|
window.location.reload();
|
||||||
|
} else {
|
||||||
|
console.error("Fehler beim Hinzufügen des POI");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map && typeof map.closePopup === "function") {
|
||||||
|
map.closePopup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------handleSubmit-------------------
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit} className="m-0 p-2 w-full ">
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="name" className="block mr-2 flex-none">
|
||||||
|
Name :
|
||||||
|
</label>
|
||||||
|
<input type="text" id="name" name="name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Name der Station" className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* {locationDeviceData.----------------------------------------------*/}
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="deviceName" className="block mr-2 flex-none">
|
||||||
|
Gerät :
|
||||||
|
</label>
|
||||||
|
<select id="deviceName" name="deviceName" value={deviceName} onChange={(e) => setDeviceName(e.target.value)} className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm">
|
||||||
|
{locationDeviceData.map((device, index) => (
|
||||||
|
<option key={index} value={device.name}>
|
||||||
|
{device.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{/* {locationDeviceData.----------------------------------------------*/}
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="idPoiTyp2" className="block mr-2 flex-none">
|
||||||
|
Typ:
|
||||||
|
</label>
|
||||||
|
<select id="idPoiTyp2" name="idPoiTyp2" value={poiTypeId} onChange={(e) => setPoiTypeId(e.target.value)} className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm">
|
||||||
|
{poiTypData &&
|
||||||
|
poiTypData.map((poiTyp, index) => (
|
||||||
|
<option key={poiTyp.idPoiTyp || index} value={poiTyp.idPoiTyp}>
|
||||||
|
{poiTyp.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row items-center justify-center">
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="lat" className="block mr-2 flex-none text-xs">
|
||||||
|
Lat : {latitude}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="lng" className="block mr-2 flex-none text-xs">
|
||||||
|
Lng : {longitude}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full">
|
||||||
|
POI hinzufügen
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddPoiModalWindow;
|
||||||
24
components/pois/AddPoiModalWindowPopup.js
Normal file
24
components/pois/AddPoiModalWindowPopup.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// components/pois/AddPoiModalWindowPopup.js
|
||||||
|
import React from "react";
|
||||||
|
import AddPoiModalWindow from "./AddPoiModalWindow.js";
|
||||||
|
|
||||||
|
const AddPoiModalWindowPopup = ({ showPopup, closePopup, handleAddStation, popupCoordinates }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{showPopup && (
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]" onClick={closePopup}>
|
||||||
|
<div className="relative bg-white p-6 rounded-lg shadow-lg" onClick={(e) => e.stopPropagation()}>
|
||||||
|
<button onClick={closePopup} className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600" aria-label="Close">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<AddPoiModalWindow onClose={closePopup} onSubmit={handleAddStation} latlng={popupCoordinates} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddPoiModalWindowPopup;
|
||||||
30
components/pois/AddPoiModalWindowWrapper.js
Normal file
30
components/pois/AddPoiModalWindowWrapper.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// components/pois/AddPoiModalWindowWrapper.js
|
||||||
|
import React from "react";
|
||||||
|
import AddPoiModalWindow from "./AddPoiModalWindow";
|
||||||
|
|
||||||
|
const AddPoiModalWindowWrapper = ({ show, onClose, latlng, handleAddStation }) => {
|
||||||
|
return (
|
||||||
|
show && (
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]"
|
||||||
|
onClick={onClose}
|
||||||
|
data-testid="modal-overlay" // Hinzugefügt, um den Hintergrund zu identifizieren
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="relative bg-white p-6 rounded-lg shadow-lg"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
role="dialog" // Hinzugefügt, um das Dialog-Element zu identifizieren
|
||||||
|
>
|
||||||
|
<button onClick={onClose} className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600" aria-label="Close">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<AddPoiModalWindow onClose={onClose} onSubmit={handleAddStation} latlng={latlng} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddPoiModalWindowWrapper;
|
||||||
213
components/pois/PoiUpdateModal.js
Normal file
213
components/pois/PoiUpdateModal.js
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
// components/pois/poiUpdateModal.js
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { useRecoilValue } from "recoil";
|
||||||
|
import { selectedPoiState } from "../../store/atoms/poiState";
|
||||||
|
import { currentPoiState } from "../../store/atoms/currentPoiState";
|
||||||
|
|
||||||
|
const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => {
|
||||||
|
const currentPoi = useRecoilValue(currentPoiState);
|
||||||
|
const selectedPoi = useRecoilValue(selectedPoiState);
|
||||||
|
const [poiId, setPoiId] = useState(poiData ? poiData.idPoi : "");
|
||||||
|
const [name, setName] = useState(poiData ? poiData.name : "");
|
||||||
|
const [poiTypData, setPoiTypData] = useState([]);
|
||||||
|
const [poiTypeId, setPoiTypeId] = useState("");
|
||||||
|
const [locationDeviceData, setLocationDeviceData] = useState([]);
|
||||||
|
const [deviceName, setDeviceName] = useState("");
|
||||||
|
const [idLD, setIdLD] = useState(poiData ? poiData.idLD : "");
|
||||||
|
|
||||||
|
const [description, setDescription] = useState(poiData ? poiData.description : "");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (poiData) {
|
||||||
|
//console.log("Initial poiData:", poiData);
|
||||||
|
setPoiId(poiData.idPoi);
|
||||||
|
setName(poiData.name);
|
||||||
|
setPoiTypeId(poiData.idPoiTyp);
|
||||||
|
setIdLD(poiData.idLD);
|
||||||
|
setDescription(poiData.description);
|
||||||
|
setDeviceName(poiData.idLD);
|
||||||
|
//console.log("Loaded POI Data for editing:", poiData);
|
||||||
|
}
|
||||||
|
}, [poiData]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchDeviceId = async () => {
|
||||||
|
if (poiData && poiData.idLD) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/talas_v5_DB/locationDevice/getDeviceIdById?idLD=${poiData.idLD}`);
|
||||||
|
const data = await response.json();
|
||||||
|
if (data) setDeviceName(data.name);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der Geräteinformation in PoiUpdateModel.js: ", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchDeviceId();
|
||||||
|
}, [poiData]);
|
||||||
|
|
||||||
|
const handleDeletePoi = async () => {
|
||||||
|
if (confirm("Sind Sie sicher, dass Sie diesen POI löschen möchten?")) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/talas_v5_DB/pois/deletePoi?id=${poiId}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
if (response.ok) {
|
||||||
|
alert("POI wurde erfolgreich gelöscht.");
|
||||||
|
onClose();
|
||||||
|
window.location.reload();
|
||||||
|
} else {
|
||||||
|
throw new Error("Fehler beim Löschen des POI.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Löschen des POI:", error);
|
||||||
|
alert("Fehler beim Löschen des POI.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchPoiTypData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/talas_v5_DB/poiTyp/readPoiTyp");
|
||||||
|
const data = await response.json();
|
||||||
|
setPoiTypData(data);
|
||||||
|
if (selectedPoi && data) {
|
||||||
|
const matchingType = data.find((pt) => pt.name === selectedPoi.typ);
|
||||||
|
if (matchingType) {
|
||||||
|
setPoiTypeId(matchingType.idPoiTyp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der poiTyp Daten:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchPoiTypData();
|
||||||
|
}, [selectedPoi]);
|
||||||
|
|
||||||
|
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();
|
||||||
|
setLocationDeviceData(data);
|
||||||
|
if (poiData && poiData.idLD) {
|
||||||
|
const selectedDevice = data.find((device) => device.id === poiData.idLD);
|
||||||
|
setDeviceName(selectedDevice ? selectedDevice.id : data[0].id);
|
||||||
|
//console.log("Selected Device in poiUpdate:", selectedDevice);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der Standort- und Gerätedaten:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch("/api/talas_v5_DB/locationDevice/locationDevices")
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
setLocationDeviceData(data);
|
||||||
|
const currentDevice = data.find((device) => device.idLD === currentPoi.idLD);
|
||||||
|
if (currentDevice) {
|
||||||
|
setDeviceName(currentDevice.name);
|
||||||
|
//console.log("Current Device name in poiUpdate:", currentDevice.name);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Fehler beim Abrufen der Gerätedaten:", error);
|
||||||
|
setLocationDeviceData([]);
|
||||||
|
});
|
||||||
|
}, [poiData?.idLD, currentPoi]);
|
||||||
|
|
||||||
|
const handleSubmit = async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const idLDResponse = await fetch(`/api/talas_v5_DB/locationDevice/getDeviceId?deviceName=${encodeURIComponent(deviceName)}`);
|
||||||
|
const idLDData = await idLDResponse.json();
|
||||||
|
const idLD = idLDData.idLD;
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/talas_v5_DB/pois/updatePoi", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
idPoi: poiId,
|
||||||
|
name: name,
|
||||||
|
description: description,
|
||||||
|
idPoiTyp: poiTypeId,
|
||||||
|
idLD: idLD,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
onClose();
|
||||||
|
window.location.reload();
|
||||||
|
} else {
|
||||||
|
const errorResponse = await response.json();
|
||||||
|
throw new Error(errorResponse.error || "Fehler beim Aktualisieren des POI.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Aktualisieren des POI:", error);
|
||||||
|
alert("Fehler beim Aktualisieren des POI.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]" onClick={onClose}>
|
||||||
|
<div className="relative bg-white p-6 rounded-lg shadow-lg" onClick={(e) => e.stopPropagation()}>
|
||||||
|
<button onClick={onClose} className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600" aria-label="Close">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<form onSubmit={handleSubmit} className="m-0 p-2 w-full">
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="description" className="block mr-2 flex-none">
|
||||||
|
Beschreibung:
|
||||||
|
</label>
|
||||||
|
<input type="text" id="description" name="description" value={description} onChange={(e) => setDescription(e.target.value)} placeholder="Beschreibung der Station" className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="deviceName" className="block mr-2 flex-none">
|
||||||
|
Gerät:
|
||||||
|
</label>
|
||||||
|
<select id="deviceName" name="deviceName" value={deviceName} onChange={(e) => setDeviceName(e.target.value)} className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm">
|
||||||
|
{locationDeviceData.map((device, index) => (
|
||||||
|
<option key={index} value={device.id}>
|
||||||
|
{device.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="idPoiTyp2" className="block mr-2 flex-none">
|
||||||
|
Typ:
|
||||||
|
</label>
|
||||||
|
<select id="idPoiTyp2" name="idPoiTyp2" value={poiTypeId} onChange={(e) => setPoiTypeId(e.target.value)} className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm">
|
||||||
|
{poiTypData.map((poiTyp, index) => (
|
||||||
|
<option key={index} value={poiTyp.idPoiTyp}>
|
||||||
|
{poiTyp.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="button" onClick={handleDeletePoi} className="bg-red-400 hover:bg-red-600 text-white font-bold py-2 px-4 rounded w-full mb-4">
|
||||||
|
POI löschen
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="submit" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full">
|
||||||
|
POI aktualisieren
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PoiUpdateModal;
|
||||||
9
components/pois/PoiUpdateModalWindow.js
Normal file
9
components/pois/PoiUpdateModalWindow.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// components/pois/PoiUpdateModalWindow.js
|
||||||
|
import React from "react";
|
||||||
|
import PoiUpdateModal from "./PoiUpdateModal.js";
|
||||||
|
|
||||||
|
const PoiUpdateModalWindow = ({ showPoiUpdateModal, closePoiUpdateModal, currentPoiData, popupCoordinates }) => {
|
||||||
|
return <>{showPoiUpdateModal && <PoiUpdateModal onClose={closePoiUpdateModal} poiData={currentPoiData} onSubmit={() => {}} latlng={popupCoordinates} />}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PoiUpdateModalWindow;
|
||||||
26
components/pois/PoiUpdateModalWrapper.js
Normal file
26
components/pois/PoiUpdateModalWrapper.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// components/pois/PoiUpdateModalWrapper.js
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import PoiUpdateModal from "./PoiUpdateModal";
|
||||||
|
import { useRecoilValue, useSetRecoilState } from "recoil";
|
||||||
|
import { currentPoiState, selectedPoiState } from "../../store/atoms/poiState";
|
||||||
|
import { poiReadFromDbTriggerAtom } from "../../store/atoms/poiReadFromDbTriggerAtom";
|
||||||
|
|
||||||
|
const PoiUpdateModalWrapper = ({ show, onClose, latlng }) => {
|
||||||
|
const setSelectedPoi = useSetRecoilState(selectedPoiState);
|
||||||
|
const setCurrentPoi = useSetRecoilState(currentPoiState);
|
||||||
|
const currentPoi = useRecoilValue(currentPoiState);
|
||||||
|
const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom);
|
||||||
|
|
||||||
|
return (
|
||||||
|
show && (
|
||||||
|
<PoiUpdateModal
|
||||||
|
onClose={onClose}
|
||||||
|
poiData={currentPoi}
|
||||||
|
onSubmit={() => {}} // Add your submit logic here
|
||||||
|
latlng={latlng}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PoiUpdateModalWrapper;
|
||||||
52
components/pois/PoiUtils.js
Normal file
52
components/pois/PoiUtils.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// components/pois/PoiUtils.js
|
||||||
|
import L from "leaflet";
|
||||||
|
|
||||||
|
// Funktion, um POI Markers zu erstellen
|
||||||
|
export const createPoiMarkers = (poiData, iconPath) => {
|
||||||
|
return poiData.map((location) => {
|
||||||
|
return L.marker([location.latitude, location.longitude], {
|
||||||
|
icon: L.icon({
|
||||||
|
iconUrl: iconPath,
|
||||||
|
iconSize: [25, 41],
|
||||||
|
iconAnchor: [12, 41],
|
||||||
|
popupAnchor: [1, -34],
|
||||||
|
draggable: true,
|
||||||
|
}),
|
||||||
|
id: location.idPoi,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Funktion zum Hinzufügen von Markern zur Karte und zum Umgang mit Events
|
||||||
|
export const addMarkersToMap = (markers, map, layerGroup) => {
|
||||||
|
markers.forEach((marker) => {
|
||||||
|
marker.addTo(layerGroup);
|
||||||
|
marker.on("mouseover", () => marker.openPopup());
|
||||||
|
marker.on("mouseout", () => marker.closePopup());
|
||||||
|
marker.on("dragend", (e) => {
|
||||||
|
const newLat = e.target.getLatLng().lat;
|
||||||
|
const newLng = e.target.getLatLng().lng;
|
||||||
|
const markerId = e.target.options.id;
|
||||||
|
updateLocationInDatabase(markerId, newLat, newLng);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Funktion zum Aktualisieren der Standorte in der Datenbank
|
||||||
|
export const updateLocationInDatabase = async (id, newLatitude, newLongitude) => {
|
||||||
|
const response = await fetch("/api/talas_v5_DB/pois/updateLocation", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
id,
|
||||||
|
latitude: newLatitude,
|
||||||
|
longitude: newLongitude,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error("Fehler beim Aktualisieren der Position");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Weitere Funktionen können hier hinzugefügt werden
|
||||||
77
components/useMapContextMenu.js
Normal file
77
components/useMapContextMenu.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// /components/useMapContextMenu.js
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import { zoomIn, zoomOut, centerHere } from "../utils/zoomAndCenterUtils"; // Assuming these are imported correctly
|
||||||
|
|
||||||
|
const zoomInCallback = (e, map) => {
|
||||||
|
zoomIn(e, map);
|
||||||
|
};
|
||||||
|
|
||||||
|
const zoomOutCallback = (map) => {
|
||||||
|
zoomOut(map);
|
||||||
|
};
|
||||||
|
|
||||||
|
const centerHereCallback = (e, map) => {
|
||||||
|
centerHere(e, map);
|
||||||
|
};
|
||||||
|
// Funktion zum Anzeigen der Koordinaten
|
||||||
|
const showCoordinates = (e) => {
|
||||||
|
alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5));
|
||||||
|
};
|
||||||
|
// Kontextmenü Callback für "POI hinzufügen"
|
||||||
|
const addStationCallback = (event, hasRights, setShowPopup, setPopupCoordinates) => {
|
||||||
|
if (hasRights) {
|
||||||
|
setPopupCoordinates(event.latlng);
|
||||||
|
setShowPopup(true);
|
||||||
|
} else {
|
||||||
|
toast.error("Benutzer hat keine Berechtigung zum Hinzufügen.", {
|
||||||
|
position: "top-center",
|
||||||
|
autoClose: 5000,
|
||||||
|
hideProgressBar: false,
|
||||||
|
closeOnClick: true,
|
||||||
|
pauseOnHover: true,
|
||||||
|
draggable: true,
|
||||||
|
progress: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addItemsToMapContextMenu = (map, menuItemAdded, setMenuItemAdded, hasRights, setShowPopup, setPopupCoordinates) => {
|
||||||
|
if (!menuItemAdded && map && map.contextmenu) {
|
||||||
|
map.contextmenu.addItem({
|
||||||
|
text: "Koordinaten anzeigen",
|
||||||
|
icon: "img/not_listed_location.png",
|
||||||
|
callback: showCoordinates,
|
||||||
|
});
|
||||||
|
|
||||||
|
map.contextmenu.addItem({ separator: true });
|
||||||
|
|
||||||
|
map.contextmenu.addItem({
|
||||||
|
text: "Reinzoomen",
|
||||||
|
icon: "img/zoom_in.png",
|
||||||
|
callback: (e) => zoomInCallback(e, map),
|
||||||
|
});
|
||||||
|
|
||||||
|
map.contextmenu.addItem({
|
||||||
|
text: "Rauszoomen",
|
||||||
|
icon: "img/zoom_out.png",
|
||||||
|
callback: () => zoomOutCallback(map),
|
||||||
|
});
|
||||||
|
|
||||||
|
map.contextmenu.addItem({
|
||||||
|
text: "Hier zentrieren",
|
||||||
|
icon: "img/center_focus.png",
|
||||||
|
callback: (e) => centerHereCallback(e, map),
|
||||||
|
});
|
||||||
|
|
||||||
|
map.contextmenu.addItem({ separator: true });
|
||||||
|
|
||||||
|
map.contextmenu.addItem({
|
||||||
|
text: "POI hinzufügen",
|
||||||
|
icon: "img/add_station.png",
|
||||||
|
className: "background-red",
|
||||||
|
callback: (event) => addStationCallback(event, hasRights, setShowPopup, setPopupCoordinates),
|
||||||
|
});
|
||||||
|
|
||||||
|
setMenuItemAdded(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte
|
// /config/config.js
|
||||||
|
import * as urls from "../config/urls.js";
|
||||||
|
// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte
|
||||||
const mapVersion = "0.5.3"; // Die Version der verwendeten Karte
|
const mapVersion = "0.5.3"; // Die Version der verwendeten Karte
|
||||||
const standardSideMenu = true; // Einstellung, ob ein standardmäßiges Seitenmenü verwendet wird
|
const standardSideMenu = true; // Einstellung, ob ein standardmäßiges Seitenmenü verwendet wird
|
||||||
const fullSideMenu = false; // Einstellung, ob ein vollständiges Seitenmenü verwendet wird
|
const fullSideMenu = false; // Einstellung, ob ein vollständiges Seitenmenü verwendet wird
|
||||||
const serverURL = "/api"; // Die Basis-URL des Servers, von dem Daten bezogen werden
|
//const serverURL = "/api"; // Die Basis-URL des Servers, von dem Daten bezogen werden
|
||||||
|
//const serverURL = "http://10.10.0.13";
|
||||||
|
//const serverURL = "http://10.10.0.70";
|
||||||
|
const serverURL = process.env.NEXT_PUBLIC_SERVER_URL;
|
||||||
|
if (!serverURL) {
|
||||||
|
throw new Error("Die Umgebungsvariable NEXT_PUBLIC_SERVER_URL ist nicht gesetzt!");
|
||||||
|
}
|
||||||
|
console.log("serverURL in config:", serverURL);
|
||||||
// Initialisieren von Variablen, die später im Browserkontext gesetzt werden
|
// Initialisieren von Variablen, die später im Browserkontext gesetzt werden
|
||||||
let windowHeight, url_string, url, c, user;
|
let windowHeight, url_string, url, idMap, idUser;
|
||||||
//Online Daten
|
//Online Daten
|
||||||
let mapGisStationsStaticDistrictUrl,
|
let mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl, mapDataIconUrl, webserviceGisLinesStatusUrl;
|
||||||
mapGisStationsStatusDistrictUrl,
|
|
||||||
mapGisStationsMeasurementsUrl,
|
|
||||||
mapGisSystemStaticUrl,
|
|
||||||
mapDataIconUrl,
|
|
||||||
webserviceGisLinesStatusUrl;
|
|
||||||
|
|
||||||
// Prüfen, ob das Code im Browser ausgeführt wird
|
// Prüfen, ob das Code im Browser ausgeführt wird
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
@@ -20,28 +23,31 @@ if (typeof window !== "undefined") {
|
|||||||
windowHeight = window.innerHeight; // Die Höhe des Browserfensters
|
windowHeight = window.innerHeight; // Die Höhe des Browserfensters
|
||||||
url_string = window.location.href; // Die vollständige URL als String
|
url_string = window.location.href; // Die vollständige URL als String
|
||||||
url = new URL(url_string); // Die URL als URL-Objekt, um Teile der URL einfacher zu handhaben
|
url = new URL(url_string); // Die URL als URL-Objekt, um Teile der URL einfacher zu handhaben
|
||||||
c = url.searchParams.get("m"); // Ein Parameter aus der URL, Standardwert ist '10'
|
console.log("URL in config:", url);
|
||||||
user = url.searchParams.get("u"); // Ein weiterer Parameter aus der URL, Standardwert ist '484 admin zu testen von Stationen ausblenden und einblenden in der Card'
|
console.log("URL origin in config:", url.origin); //http://localhost:3000
|
||||||
|
idMap = url.searchParams.get("m"); // Ein Parameter aus der URL, Standardwert ist '10'
|
||||||
|
idUser = url.searchParams.get("u"); // Ein weiterer Parameter aus der URL, Standardwert ist '484 admin zu testen von Stationen ausblenden und einblenden in der Card'
|
||||||
|
|
||||||
console.log(`Parameter 'idMap' : ${c}`);
|
console.log(`Parameter 'idMap' : ${idMap}`);
|
||||||
console.log(`Parameter 'idUser': ${user}`);
|
console.log(`Parameter 'idUser': ${idUser}`);
|
||||||
|
|
||||||
console.log(`Parameter 'idMap' : ${c}`);
|
|
||||||
console.log(`Parameter 'idUser': ${user}`);
|
|
||||||
|
|
||||||
// Konstruktion von URLs, die auf spezifische Ressourcen auf dem Server zeigen
|
// Konstruktion von URLs, die auf spezifische Ressourcen auf dem Server zeigen
|
||||||
//http://localhost:3000/?m=10&u=485
|
//http://localhost:3000/?m=10&u=485
|
||||||
|
|
||||||
//-----------------Von WebService------------------------------------------------
|
//-----------------Von WebService------------------------------------------------
|
||||||
mapGisStationsStaticDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`; //idMap: 10, idUser: 484
|
mapGisStationsStaticDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`; //idMap: 10, idUser: 484
|
||||||
mapGisStationsStatusDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`;
|
mapGisStationsStatusDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`;
|
||||||
mapGisStationsMeasurementsUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${c}`;
|
mapGisStationsMeasurementsUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${idMap}`;
|
||||||
mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${c}&idUser=${user}`;
|
mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`;
|
||||||
mapDataIconUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`;
|
mapDataIconUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`;
|
||||||
|
|
||||||
//webserviceGisLinesStatusUrl = `http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${c}`;
|
//webserviceGisLinesStatusUrl = `http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`;
|
||||||
webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`;
|
//webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`;
|
||||||
//webserviceGisLinesStatusUrl = `http://192.168.10.14/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${c}`;
|
//webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`;
|
||||||
|
//webserviceGisLinesStatusUrl = `${"serverURL"}:3000/api/linesColorApi`;
|
||||||
|
// webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`;
|
||||||
|
//webserviceGisLinesStatusUrl = `http://192.168.10.14/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`;
|
||||||
|
webserviceGisLinesStatusUrl = `${serverURL}/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`;
|
||||||
|
|
||||||
//http://10.10.0.13/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=12&idUser=484
|
//http://10.10.0.13/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=12&idUser=484
|
||||||
|
|
||||||
@@ -51,11 +57,11 @@ if (typeof window !== "undefined") {
|
|||||||
mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic`;
|
mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic`;
|
||||||
mapDataIconUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`; */
|
mapDataIconUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`; */
|
||||||
|
|
||||||
/* mapGisStationsStaticDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`;
|
/* mapGisStationsStaticDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`;
|
||||||
mapGisStationsStatusDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`;
|
mapGisStationsStatusDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`;
|
||||||
mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsMeasurements?idMap=${c}`;
|
mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsMeasurements?idMap=${idMap}`;
|
||||||
mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/gisStationsMeasurementsSQL?idMap=${c}`;
|
mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/gisStationsMeasurementsSQL?idMap=${idMap}`;
|
||||||
mapGisSystemStaticUrl = `${serverURL}/api/talas5/webserviceMap/GisSystemStatic?idMap=${c}&idUser=${user}`;
|
mapGisSystemStaticUrl = `${serverURL}/api/talas5/webserviceMap/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`;
|
||||||
mapDataIconUrl = `${serverURL}/api/talas5/webserviceMap/GetIconsStatic`; */
|
mapDataIconUrl = `${serverURL}/api/talas5/webserviceMap/GetIconsStatic`; */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +74,8 @@ export {
|
|||||||
windowHeight,
|
windowHeight,
|
||||||
url_string,
|
url_string,
|
||||||
url,
|
url,
|
||||||
c,
|
idMap,
|
||||||
user,
|
idUser,
|
||||||
mapGisStationsStaticDistrictUrl,
|
mapGisStationsStaticDistrictUrl,
|
||||||
mapGisStationsStatusDistrictUrl,
|
mapGisStationsStatusDistrictUrl,
|
||||||
mapGisStationsMeasurementsUrl,
|
mapGisStationsMeasurementsUrl,
|
||||||
@@ -77,3 +83,9 @@ export {
|
|||||||
mapDataIconUrl,
|
mapDataIconUrl,
|
||||||
webserviceGisLinesStatusUrl,
|
webserviceGisLinesStatusUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Access to fetch at 'http://localhost:3000/api/linesColorApi' from origin 'http://10.10.0.13:3000' has been blocked by CORS policy:
|
||||||
|
No 'Access-Control-Allow-Origin' header is present on the requested resource.
|
||||||
|
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
|
||||||
|
*/
|
||||||
|
|||||||
17
config/layers.js
Normal file
17
config/layers.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import L from "leaflet";
|
||||||
|
|
||||||
|
export const MAP_LAYERS = {
|
||||||
|
TALAS: new L.layerGroup(),
|
||||||
|
ECI: new L.layerGroup(),
|
||||||
|
ULAF: new L.layerGroup(),
|
||||||
|
GSMModem: new L.layerGroup(),
|
||||||
|
CiscoRouter: new L.layerGroup(),
|
||||||
|
WAGO: new L.layerGroup(),
|
||||||
|
Siemens: new L.layerGroup(),
|
||||||
|
OTDR: new L.layerGroup(),
|
||||||
|
WDM: new L.layerGroup(),
|
||||||
|
GMA: new L.layerGroup(),
|
||||||
|
Sonstige: new L.layerGroup(),
|
||||||
|
TALASICL: new L.layerGroup(),
|
||||||
|
lineLayer: new L.LayerGroup(),
|
||||||
|
};
|
||||||
5
config/settings.js
Normal file
5
config/settings.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
// /config/settings.js
|
||||||
|
// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte
|
||||||
|
export const MAP_VERSION = "1.0.0";
|
||||||
|
//export const STANDARD_SIDE_MENU = true;
|
||||||
|
//export const FULL_SIDE_MENU = false;
|
||||||
45
config/urls.js
Normal file
45
config/urls.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// /config/urls.js
|
||||||
|
|
||||||
|
export const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL; //Station in Tab öffnen
|
||||||
|
export const SERVER_URL = process.env.NEXT_PUBLIC_SERVER_URL; //Die Konstante ist in MapComponent.js und useLineData.js verwendet
|
||||||
|
export const PROXY_TARGET = process.env.NEXT_PUBLIC_PROXY_TARGET; // damit nodejs auf Port 3000 auf dem Server Talas5 auf Port 80 aufgerufen kann, ansonsten gibt CORS Fehler
|
||||||
|
export const ONLINE_TILE_LAYER = process.env.NEXT_PUBLIC_ONLINE_TILE_LAYER; //Map von Talas_v5 Server
|
||||||
|
//-----------------------------------
|
||||||
|
//export const ONLINE_TILE_LAYER = "http://10.10.0.13:3000/mapTiles/{z}/{x}/{y}.png"; //Map von Talas_v5 Server
|
||||||
|
// export const PROXY_TARGET = "http://10.10.0.70"; // damit nodejs auf Port 3000 auf dem Server Talas5 auf Port 80 aufgerufen kann, ansonsten gibt CORS Fehler
|
||||||
|
// export const SERVER_URL = "http://10.10.0.70"; //Die Konstante ist in MapComponent.js und useLineData.js verwendet
|
||||||
|
// export const BASE_URL = "http://10.10.0.70/talas5/devices/"; //Station in Tab öffnen
|
||||||
|
// //-----------------------------------
|
||||||
|
/* export const ONLINE_TILE_LAYER = "http://192.168.10.14:3000/mapTiles/{z}/{x}/{y}.png"; //Map von Talas_v5 Server
|
||||||
|
export const PROXY_TARGET = "http://192.168.10.167"; // damit nodejs auf Port 3000 auf dem Server Talas5 auf Port 80 aufgerufen kann, ansonsten gibt CORS Fehler
|
||||||
|
export const SERVER_URL = "http://192.168.10.167"; //Die Konstante ist in MapComponent.js und useLineData.js verwendet
|
||||||
|
export const BASE_URL = "http://192.168.10.167/talas5/devices/"; //Station in Tab öffnen */
|
||||||
|
//-----------------------------------
|
||||||
|
// export const ONLINE_TILE_LAYER = "http://192.168.10.14:3000/mapTiles/{z}/{x}/{y}.png"; //Map von Talas_v5 Server */
|
||||||
|
// export const PROXY_TARGET = "http://localhost"; // damit nodejs auf Port 3000 auf dem Server Talas5 auf Port 80 aufgerufen kann, ansonsten gibt CORS Fehler
|
||||||
|
// export const SERVER_URL = "http://localhost"; //in MapComponent.js wird es verwendet
|
||||||
|
// export const BASE_URL = "http://localhost/talas5/devices/"; //Station in Tab öffnen
|
||||||
|
//-----------------------------------
|
||||||
|
//-----------------------------------
|
||||||
|
// weil ich keine API habe, ansonsten serverURL ist localhost(IP-Adresse) für GisSystemStatic für die Benutzerrechte
|
||||||
|
//const serverURL = `${protocol}//${hostname}`;
|
||||||
|
//const serverURL = `${protocol}//${hostname}${port ? `:${port}` : ""}`;
|
||||||
|
//const serverURL = "http://localhost:3000";
|
||||||
|
//export const SERVER_URL = "http://10.10.0.13";
|
||||||
|
//export const SERVER_URL = "http://10.10.0.70";
|
||||||
|
|
||||||
|
// Online Daten URLs
|
||||||
|
/* export const MAP_GIS_STATIONS_STATIC_DISTRICT_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`; //idMap: 10, idUser: 484
|
||||||
|
export const MAP_GIS_STATIONS_STATUS_DISTRICT_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`;
|
||||||
|
export const MAP_GIS_STATIONS_MEASUREMENTS_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${c}`;
|
||||||
|
export const MAP_GIS_SYSTEM_STATIC_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${c}&idUser=${user}`;
|
||||||
|
export const MAP_DATA_ICON_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`;
|
||||||
|
export const WEBSERVICE_GIS_LINES_STATUS_URL =
|
||||||
|
"http://localhost:3000/api/linesColorApi";
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Access to fetch at 'http://localhost:3000/api/linesColorApi' from origin 'http://10.10.0.13:3000' has been blocked by CORS policy:
|
||||||
|
No 'Access-Control-Allow-Origin' header is present on the requested resource.
|
||||||
|
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
|
||||||
|
*/
|
||||||
47
hooks/talasMarkersLayer.js
Normal file
47
hooks/talasMarkersLayer.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { checkOverlappingMarkers } from "../utils/mapUtils";
|
||||||
|
|
||||||
|
const useTalasMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [talasMarkers, setTalasMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(1, setTalasMarkers, GisSystemStatic, priorityConfig); // TALAS-System
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && talasMarkers.length) {
|
||||||
|
talasMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup beim Überfahren mit der Maus öffnen und schließen
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
// Call the function to check for overlapping markers
|
||||||
|
checkOverlappingMarkers(oms, map);
|
||||||
|
}
|
||||||
|
}, [map, talasMarkers]);
|
||||||
|
|
||||||
|
return talasMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useTalasMarkersLayer;
|
||||||
49
hooks/useCiscoRouterMarkersLayer.js
Normal file
49
hooks/useCiscoRouterMarkersLayer.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// hooks/useCiscoRouterMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { checkOverlappingMarkers } from "../utils/mapUtils";
|
||||||
|
|
||||||
|
const useCiscoRouterMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [ciscoRouterMarkers, setCiscoRouterMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(6, setCiscoRouterMarkers, GisSystemStatic, priorityConfig); // Cisco Router
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && ciscoRouterMarkers.length) {
|
||||||
|
ciscoRouterMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
// Call the function to check for overlapping markers
|
||||||
|
checkOverlappingMarkers(oms, map);
|
||||||
|
}
|
||||||
|
}, [map, ciscoRouterMarkers]);
|
||||||
|
|
||||||
|
return ciscoRouterMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useCiscoRouterMarkersLayer;
|
||||||
45
hooks/useDauzMarkersLayer.js
Normal file
45
hooks/useDauzMarkersLayer.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// hooks/useDauzMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
|
||||||
|
const useDauzMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [dauzMarkers, setDauzMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(110, setDauzMarkers, GisSystemStatic, priorityConfig); // DAUZ
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && dauzMarkers.length) {
|
||||||
|
dauzMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
}
|
||||||
|
}, [map, dauzMarkers, oms]);
|
||||||
|
|
||||||
|
return dauzMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useDauzMarkersLayer;
|
||||||
47
hooks/useEciMarkersLayer.js
Normal file
47
hooks/useEciMarkersLayer.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { checkOverlappingMarkers } from "../utils/mapUtils";
|
||||||
|
|
||||||
|
const useEciMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [eciMarkers, setEciMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(2, setEciMarkers, GisSystemStatic, priorityConfig); // ECI-System
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && eciMarkers.length) {
|
||||||
|
eciMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup beim Überfahren mit der Maus öffnen und schließen
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
// Call the function to check for overlapping markers
|
||||||
|
checkOverlappingMarkers(oms, map);
|
||||||
|
}
|
||||||
|
}, [map, eciMarkers]);
|
||||||
|
|
||||||
|
return eciMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useEciMarkersLayer;
|
||||||
25
hooks/useFetchPoiData.js
Normal file
25
hooks/useFetchPoiData.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// hooks/useFetchPoiData.js
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
const useFetchPoiData = (url) => {
|
||||||
|
const [poiData, setPoiData] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchPoiData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
if (!response.ok) throw new Error("Network response was not ok");
|
||||||
|
const data = await response.json();
|
||||||
|
setPoiData(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der poiData:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchPoiData();
|
||||||
|
}, [url]);
|
||||||
|
|
||||||
|
return poiData;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useFetchPoiData;
|
||||||
63
hooks/useGmaMarkersLayer.js
Normal file
63
hooks/useGmaMarkersLayer.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
|
||||||
|
const useGmaMarkersLayer = (map, gmaMarkers, GisStationsMeasurements, GMA, oms) => {
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && gmaMarkers.length) {
|
||||||
|
const gmaMeasurements = GisStationsMeasurements.filter((m) => m.Gr === "GMA");
|
||||||
|
let area_name = "";
|
||||||
|
let measurements = {};
|
||||||
|
|
||||||
|
gmaMeasurements.forEach((m) => {
|
||||||
|
area_name = m.Area_Name;
|
||||||
|
measurements[m.Na] = m.Val;
|
||||||
|
});
|
||||||
|
|
||||||
|
gmaMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Logging the data to debug
|
||||||
|
//console.log("Marker Data:", { area_name, measurements });
|
||||||
|
|
||||||
|
marker.bindTooltip(
|
||||||
|
`
|
||||||
|
<div class="p-0 rounded-lg bg-white bg-opacity-90">
|
||||||
|
<div class="font-bold text-sm text-black">
|
||||||
|
<span>${area_name}</span>
|
||||||
|
</div>
|
||||||
|
<div class="font-bold text-xxs text-blue-700">
|
||||||
|
<span>LT : ${measurements.LT} °C</span>
|
||||||
|
</div>
|
||||||
|
<div class="font-bold text-xxs text-red-700">
|
||||||
|
<span>FBT : ${measurements.FBT} °C</span>
|
||||||
|
</div>
|
||||||
|
<div class="font-bold text-xxs text-yellow-500">
|
||||||
|
<span>GT : ${measurements.GT === "nicht ermittelbar" ? measurements.GT : `${measurements.GT} °C`}</span>
|
||||||
|
</div>
|
||||||
|
<div class="font-bold text-xxs text-green-700">
|
||||||
|
<span>RLF : ${measurements.RLF} %</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
permanent: true,
|
||||||
|
direction: "auto",
|
||||||
|
offset: [20, 0],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
map.addLayer(GMA);
|
||||||
|
}
|
||||||
|
}, [map, gmaMarkers, GisStationsMeasurements, GMA, oms]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useGmaMarkersLayer;
|
||||||
47
hooks/useGsmModemMarkersLayer.js
Normal file
47
hooks/useGsmModemMarkersLayer.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// hooks/useGsmModemMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { checkOverlappingMarkers } from "../utils/mapUtils";
|
||||||
|
|
||||||
|
const useGsmModemMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [gsmModemMarkers, setGsmModemMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(5, setGsmModemMarkers, GisSystemStatic, priorityConfig); // GSM-Modem
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && gsmModemMarkers.length) {
|
||||||
|
gsmModemMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup beim Überfahren mit der Maus öffnen und schließen
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
// Call the function to check for overlapping markers
|
||||||
|
checkOverlappingMarkers(oms, map);
|
||||||
|
}
|
||||||
|
}, [map, gsmModemMarkers]);
|
||||||
|
|
||||||
|
return gsmModemMarkers;
|
||||||
|
};
|
||||||
|
export default useGsmModemMarkersLayer;
|
||||||
24
hooks/useLayerVisibility.js
Normal file
24
hooks/useLayerVisibility.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// hooks/useLayerVisibility.js
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useRecoilValue } from "recoil";
|
||||||
|
import { mapLayersState } from "../store/atoms/mapLayersState";
|
||||||
|
|
||||||
|
const useLayerVisibility = (map, markers, mapLayersVisibility, layerKey) => {
|
||||||
|
useEffect(() => {
|
||||||
|
if (!map || !markers) return;
|
||||||
|
|
||||||
|
const toggleLayer = (isVisible) => {
|
||||||
|
markers.forEach((marker) => {
|
||||||
|
if (isVisible) {
|
||||||
|
marker.addTo(map);
|
||||||
|
} else {
|
||||||
|
map.removeLayer(marker);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleLayer(mapLayersVisibility[layerKey]);
|
||||||
|
}, [map, markers, mapLayersVisibility, layerKey]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useLayerVisibility;
|
||||||
64
hooks/useLineData - Kopie.js
Normal file
64
hooks/useLineData - Kopie.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
// /hooks/useLineData.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { SERVER_URL } from "../config/urls";
|
||||||
|
|
||||||
|
const useLineData = (webserviceGisLinesStatusUrl, setLineStatusData) => {
|
||||||
|
const [lineColors, setLineColors] = useState({});
|
||||||
|
const [tooltipContents, setTooltipContents] = useState({});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
const response1 = await fetch(webserviceGisLinesStatusUrl);
|
||||||
|
const data1 = await response1.json();
|
||||||
|
const response2 = await fetch(`${SERVER_URL}:3000/api/talas_v5_DB/gisLines/readGisLines`);
|
||||||
|
const data2 = await response2.json();
|
||||||
|
|
||||||
|
const colorsByModule = {};
|
||||||
|
const newTooltipContents = {};
|
||||||
|
const reversedData = data1.Statis ? data1.Statis.reverse() : [];
|
||||||
|
reversedData.forEach((stat) => {
|
||||||
|
const matchingLine = data2.find((item) => item.idLD === stat.IdLD && item.idModul === stat.Modul);
|
||||||
|
if (matchingLine) {
|
||||||
|
// Check if PrioColor is #ffffff and change it to green
|
||||||
|
const prioColor = stat.PrioColor === "#ffffff" ? "green" : stat.PrioColor;
|
||||||
|
|
||||||
|
colorsByModule[matchingLine.idModul] = prioColor;
|
||||||
|
newTooltipContents[matchingLine.idModul] = `
|
||||||
|
<div class="bg-white rounded-lg m-0 p-2 w-[210px]">
|
||||||
|
<span class="text-lg font-semibold text-gray-900">${stat.ModulName || "Unknown"}</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-md font-bold text-gray-800">${stat.ModulTyp || "N/A"}</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-md font-bold text-gray-800">Slot: ${stat.Modul || "N/A"}</span>
|
||||||
|
<br>
|
||||||
|
<div style="max-width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal;">
|
||||||
|
<span class="inline-block w-2 h-2 rounded-full mr-2" style="background-color: ${prioColor || "#000000"};"></span>
|
||||||
|
<span class="inline-block text-gray-800">${stat.Message || "N/A"}</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-gray-800" style="color: ${prioColor || "#000000"};">(${stat.PrioName || "N/A"})</span>
|
||||||
|
<br>
|
||||||
|
<div style="max-width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal;">
|
||||||
|
<span class="inline-block text-gray-800">${stat.DpName || "N/A"}</span>
|
||||||
|
: <span class="inline-block text-gray-800">${stat.Value || "N/A"}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setLineColors(colorsByModule);
|
||||||
|
setTooltipContents(newTooltipContents);
|
||||||
|
setLineStatusData(reversedData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching data:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchData();
|
||||||
|
}, [webserviceGisLinesStatusUrl, setLineStatusData]);
|
||||||
|
|
||||||
|
return { lineColors, tooltipContents };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useLineData;
|
||||||
93
hooks/useLineData - stationname.js
Normal file
93
hooks/useLineData - stationname.js
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// /hooks/useLineData.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { SERVER_URL } from "../config/urls";
|
||||||
|
|
||||||
|
const useLineData = (webserviceGisLinesStatusUrl, setLineStatusData) => {
|
||||||
|
const [lineColors, setLineColors] = useState({});
|
||||||
|
const [tooltipContents, setTooltipContents] = useState({});
|
||||||
|
const [locationDevices, setLocationDevices] = useState([]);
|
||||||
|
|
||||||
|
// Funktion zum Abrufen der Stationsnamen
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchLocationDevices = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}:3000/api/talas_v5_DB/station/getStationNameByIdLD`);
|
||||||
|
const data = await response.json();
|
||||||
|
setLocationDevices(data);
|
||||||
|
console.log("Stationen namen:", data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der Stationen:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchLocationDevices();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
const response1 = await fetch(webserviceGisLinesStatusUrl);
|
||||||
|
const data1 = await response1.json();
|
||||||
|
const response2 = await fetch(`${SERVER_URL}:3000/api/talas_v5_DB/gisLines/readGisLines`);
|
||||||
|
const data2 = await response2.json();
|
||||||
|
|
||||||
|
const colorsByModule = {};
|
||||||
|
const newTooltipContents = {};
|
||||||
|
const reversedData = data1.Statis ? data1.Statis.reverse() : [];
|
||||||
|
|
||||||
|
reversedData.forEach((stat) => {
|
||||||
|
// Finden der passenden Linie
|
||||||
|
const matchingLine = data2.find((item) => item.idLD === stat.IdLD && item.idModul === stat.Modul);
|
||||||
|
|
||||||
|
if (matchingLine) {
|
||||||
|
// Ermitteln der Farbe basierend auf PrioColor
|
||||||
|
const prioColor = stat.PrioColor === "#ffffff" ? "green" : stat.PrioColor;
|
||||||
|
colorsByModule[matchingLine.idModul] = prioColor;
|
||||||
|
|
||||||
|
// Finden des passenden Stationsnamens
|
||||||
|
const locationDevice = locationDevices.find((device) => device.idLD === stat.IdLD);
|
||||||
|
|
||||||
|
newTooltipContents[matchingLine.idModul] = `
|
||||||
|
<div class="bg-white rounded-lg m-0 p-2 w-[210px]">
|
||||||
|
<span class="text-lg font-semibold text-gray-900">${stat.ModulName || "Unknown"}</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-md font-bold text-gray-800">Station: ${locationDevice ? locationDevice.name : "Unbekannt"}</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-md font-bold text-gray-800">${stat.ModulTyp || "N/A"}</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-md font-bold text-gray-800">Slot: ${stat.Modul || "N/A"}</span>
|
||||||
|
<br>
|
||||||
|
<div style="max-width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal;">
|
||||||
|
<span class="inline-block w-2 h-2 rounded-full mr-2" style="background-color: ${prioColor || "#000000"};"></span>
|
||||||
|
<span class="inline-block text-gray-800">${stat.Message || "N/A"}</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-gray-800" style="color: ${prioColor || "#000000"};">(${stat.PrioName || "N/A"})</span>
|
||||||
|
<br>
|
||||||
|
<div style="max-width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal;">
|
||||||
|
<span class="inline-block text-gray-800">${stat.DpName || "N/A"}</span>
|
||||||
|
: <span class="inline-block text-gray-800">${stat.Value || "N/A"}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setLineColors(colorsByModule);
|
||||||
|
setTooltipContents(newTooltipContents);
|
||||||
|
setLineStatusData(reversedData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching data:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchData();
|
||||||
|
|
||||||
|
const interval = setInterval(fetchData, 300000); // 300000 ms = 5 Minuten
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [webserviceGisLinesStatusUrl, setLineStatusData, locationDevices]);
|
||||||
|
|
||||||
|
return { lineColors, tooltipContents };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useLineData;
|
||||||
152
hooks/useLineData.js
Normal file
152
hooks/useLineData.js
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
// /hooks/useLineData.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { SERVER_URL } from "../config/urls";
|
||||||
|
|
||||||
|
const useLineData = (webserviceGisLinesStatusUrl, setLineStatusData) => {
|
||||||
|
const [lineColors, setLineColors] = useState({});
|
||||||
|
const [tooltipContents, setTooltipContents] = useState({});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
console.log("Daten werden abgerufen...");
|
||||||
|
const response1 = await fetch(webserviceGisLinesStatusUrl);
|
||||||
|
const data1 = await response1.json();
|
||||||
|
console.log("Daten vom Webservice:", data1);
|
||||||
|
const response2 = await fetch(`${SERVER_URL}:3000/api/talas_v5_DB/gisLines/readGisLines`);
|
||||||
|
const data2 = await response2.json();
|
||||||
|
console.log("GIS Linien Daten:", data2);
|
||||||
|
|
||||||
|
const colorsByModule = {};
|
||||||
|
const newTooltipContents = {};
|
||||||
|
const valueMap = {};
|
||||||
|
|
||||||
|
// Hier führen wir die Gruppierung durch und loggen sie
|
||||||
|
logGroupedData(data1.Statis);
|
||||||
|
|
||||||
|
data1.Statis.forEach((statis) => {
|
||||||
|
const key = `${statis.IdLD}-${statis.Modul}`;
|
||||||
|
if (!valueMap[key]) {
|
||||||
|
valueMap[key] = {
|
||||||
|
messages: [],
|
||||||
|
messwert: undefined,
|
||||||
|
schleifenwert: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (statis.DpName.includes("_Messwert") && statis.Value !== "True" && valueMap[key].messwert === undefined) {
|
||||||
|
valueMap[key].messwert = statis.Value;
|
||||||
|
}
|
||||||
|
if (statis.DpName.includes("_Schleifenwert") && valueMap[key].schleifenwert === undefined) {
|
||||||
|
valueMap[key].schleifenwert = statis.Value;
|
||||||
|
}
|
||||||
|
if (statis.Message && statis.Message !== "?") {
|
||||||
|
valueMap[key].messages.push(statis.Message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
data1.Statis.reverse().forEach((statis) => {
|
||||||
|
const matchingLine = data2.find((item) => item.idLD === statis.IdLD && item.idModul === statis.Modul);
|
||||||
|
if (matchingLine) {
|
||||||
|
const prioColor = statis.PrioColor === "#ffffff" ? "green" : statis.PrioColor;
|
||||||
|
const key = `${matchingLine.idLD}-${matchingLine.idModul}`;
|
||||||
|
const values = valueMap[key];
|
||||||
|
|
||||||
|
const messageDisplay = values.messages.map((msg) => (msg ? `<span class="inline-block text-gray-800">${msg}</span><br>` : "")).join("");
|
||||||
|
const prioNameDisplay = statis.PrioName && statis.PrioName !== "?" ? `(${statis.PrioName})` : "";
|
||||||
|
|
||||||
|
colorsByModule[matchingLine.idModul] = prioColor;
|
||||||
|
newTooltipContents[matchingLine.idModul] = `
|
||||||
|
<div class="bg-white rounded-lg m-0 p-2 w-[210px]">
|
||||||
|
<span class="text-lg font-semibold text-gray-900">${statis.ModulName || "Unknown"}</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-md font-bold text-gray-800">${statis.ModulTyp || "N/A"}</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-md font-bold text-gray-800">Slot: ${statis.Modul || "N/A"}</span>
|
||||||
|
<br>
|
||||||
|
<div style="max-width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal;">
|
||||||
|
<span class="inline-block w-2 h-2 rounded-full mr-2" style="background-color: ${prioColor || "#000000"};"></span>
|
||||||
|
${messageDisplay}
|
||||||
|
</div>
|
||||||
|
<span class="text-gray-800" style="color: ${prioColor || "#000000"};">${prioNameDisplay}</span>
|
||||||
|
<br>
|
||||||
|
${values.messwert ? `<span class="inline-block text-gray-800">Messwert: ${values.messwert}</span><br>` : ""}
|
||||||
|
${values.schleifenwert ? `<span class="inline-block text-gray-800">Schleifenwert: ${values.schleifenwert}</span>` : ""}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setLineColors(colorsByModule);
|
||||||
|
setTooltipContents(newTooltipContents);
|
||||||
|
setLineStatusData(data1.Statis);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der Daten:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchData();
|
||||||
|
}, [webserviceGisLinesStatusUrl, setLineStatusData]);
|
||||||
|
|
||||||
|
return { lineColors, tooltipContents };
|
||||||
|
};
|
||||||
|
//----------------------------------------------------------
|
||||||
|
// Funktion zum Loggen der gruppierten und aggregierten Daten
|
||||||
|
function logGroupedData(statisList) {
|
||||||
|
const grouped = statisList.reduce((acc, item) => {
|
||||||
|
const { IdLD, Modul, Level, PrioColor, PrioName, ModulName, ModulTyp, Message } = item;
|
||||||
|
|
||||||
|
if (!acc[IdLD]) {
|
||||||
|
acc[IdLD] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acc[IdLD][Modul]) {
|
||||||
|
acc[IdLD][Modul] = {
|
||||||
|
ModulName: ModulName || "Unknown",
|
||||||
|
ModulTyp: ModulTyp || "N/A",
|
||||||
|
TotalLevel: 0,
|
||||||
|
PrioColors: new Set(),
|
||||||
|
PrioNames: new Set(),
|
||||||
|
Messages: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregiere die Level und sammle Prioritätsinformationen und Nachrichten
|
||||||
|
acc[IdLD][Modul].TotalLevel += Level;
|
||||||
|
acc[IdLD][Modul].PrioColors.add(PrioColor);
|
||||||
|
acc[IdLD][Modul].PrioNames.add(PrioName);
|
||||||
|
if (Message && Message !== "?") {
|
||||||
|
acc[IdLD][Modul].Messages.push(Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// Formatierte Ausgabe der gruppierten Daten, Entfernen von Modulen ohne Namen und Stationen mit leeren Arrays
|
||||||
|
const formattedData = {};
|
||||||
|
Object.entries(grouped).forEach(([stationId, modules]) => {
|
||||||
|
const filteredModules = Object.entries(modules)
|
||||||
|
.filter(([modulId, data]) => data.ModulName !== "?")
|
||||||
|
.map(([modulId, data]) => ({
|
||||||
|
Modul: modulId,
|
||||||
|
ModulName: data.ModulName,
|
||||||
|
ModulTyp: data.ModulTyp,
|
||||||
|
TotalLevel: data.TotalLevel,
|
||||||
|
PrioColors: Array.from(data.PrioColors).join(", "),
|
||||||
|
PrioNames: Array.from(data.PrioNames).join(", "),
|
||||||
|
Messages: data.Messages.join(" | "),
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (filteredModules.length > 0) {
|
||||||
|
formattedData[stationId] = filteredModules;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Aggregierte und gruppierte Daten (gefiltert):", formattedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Beispielaufruf der Funktion
|
||||||
|
// const statisList = data1.Statis; // Verwende die Liste aus deinem API-Aufruf
|
||||||
|
// logGroupedData(statisList);
|
||||||
|
|
||||||
|
//----------------------------------------------------------
|
||||||
|
export default useLineData;
|
||||||
28
hooks/useMapComponentState.js
Normal file
28
hooks/useMapComponentState.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// hooks/useMapComponentState.js
|
||||||
|
import { useState, useRef } from "react";
|
||||||
|
import usePoiTypData from "./usePoiTypData";
|
||||||
|
import { useRecoilValue } from "recoil";
|
||||||
|
import { poiLayerVisibleState } from "../store/atoms/poiLayerVisibleState";
|
||||||
|
|
||||||
|
export const useMapComponentState = () => {
|
||||||
|
const { poiTypData, isPoiTypLoaded } = usePoiTypData("/api/talas_v5_DB/poiTyp/readPoiTyp");
|
||||||
|
const [deviceName, setDeviceName] = useState("");
|
||||||
|
const [locationDeviceData, setLocationDeviceData] = useState([]);
|
||||||
|
const [priorityConfig, setPriorityConfig] = useState([]);
|
||||||
|
const [menuItemAdded, setMenuItemAdded] = useState(false);
|
||||||
|
const poiLayerVisible = useRecoilValue(poiLayerVisibleState);
|
||||||
|
|
||||||
|
return {
|
||||||
|
poiTypData,
|
||||||
|
isPoiTypLoaded,
|
||||||
|
deviceName,
|
||||||
|
setDeviceName,
|
||||||
|
locationDeviceData,
|
||||||
|
setLocationDeviceData,
|
||||||
|
priorityConfig,
|
||||||
|
setPriorityConfig,
|
||||||
|
menuItemAdded,
|
||||||
|
setMenuItemAdded,
|
||||||
|
poiLayerVisible,
|
||||||
|
};
|
||||||
|
};
|
||||||
26
hooks/useMarkerLayers.js
Normal file
26
hooks/useMarkerLayers.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// hooks/useMarkerLayers.js
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useRecoilValue } from "recoil";
|
||||||
|
import { mapLayersState } from "../store/atoms/mapLayersState";
|
||||||
|
|
||||||
|
const useMarkerLayers = (map, markers, layerType) => {
|
||||||
|
const mapLayersVisibility = useRecoilValue(mapLayersState);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!map || !markers) return;
|
||||||
|
|
||||||
|
const toggleLayer = (isVisible) => {
|
||||||
|
markers.forEach((marker) => {
|
||||||
|
if (isVisible) {
|
||||||
|
marker.addTo(map);
|
||||||
|
} else {
|
||||||
|
map.removeLayer(marker);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleLayer(mapLayersVisibility[layerType]);
|
||||||
|
}, [map, markers, mapLayersVisibility, layerType]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useMarkerLayers;
|
||||||
37
hooks/useMessstellenMarkersLayer.js
Normal file
37
hooks/useMessstellenMarkersLayer.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
|
||||||
|
const useMessstellenMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [messstellenMarkers, setMessstellenMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(13, setMessstellenMarkers, GisSystemStatic, priorityConfig); // Messstellen
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && messstellenMarkers.length) {
|
||||||
|
messstellenMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [map, messstellenMarkers, oms]);
|
||||||
|
|
||||||
|
return messstellenMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useMessstellenMarkersLayer;
|
||||||
45
hooks/useOtdrMarkersLayer.js
Normal file
45
hooks/useOtdrMarkersLayer.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// hooks/useOtdrMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils"; // Assuming this function is in markerUtils
|
||||||
|
|
||||||
|
const useOtdrMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [otdrMarkers, setOtdrMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(9, setOtdrMarkers, GisSystemStatic, priorityConfig); // OTDR
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && otdrMarkers.length) {
|
||||||
|
otdrMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
}
|
||||||
|
}, [map, otdrMarkers, oms]);
|
||||||
|
|
||||||
|
return otdrMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useOtdrMarkersLayer;
|
||||||
26
hooks/usePoiTypData.js
Normal file
26
hooks/usePoiTypData.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// hooks/usePoiTypData.js
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
const usePoiTypData = (url) => {
|
||||||
|
const [poiTypData, setPoiTypData] = useState([]);
|
||||||
|
const [isPoiTypLoaded, setIsPoiTypLoaded] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchPoiTypData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
const data = await response.json();
|
||||||
|
setPoiTypData(data);
|
||||||
|
setIsPoiTypLoaded(true);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der poiTyp-Daten:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchPoiTypData();
|
||||||
|
}, [url]);
|
||||||
|
|
||||||
|
return { poiTypData, isPoiTypLoaded };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default usePoiTypData;
|
||||||
49
hooks/useSiemensMarkersLayer.js
Normal file
49
hooks/useSiemensMarkersLayer.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// hooks/useSiemensMarkersLayer.js
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
import { checkOverlappingMarkers } from "../utils/mapUtils";
|
||||||
|
|
||||||
|
const useSiemensMarkersLayer = (map, oms, gisSystemStatic, priorityConfig) => {
|
||||||
|
const [siemensMarkers, setSiemensMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (gisSystemStatic && gisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(8, setSiemensMarkers, gisSystemStatic, priorityConfig); // Siemens-System
|
||||||
|
}
|
||||||
|
}, [gisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && siemensMarkers.length) {
|
||||||
|
siemensMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
// Call the function to check for overlapping markers
|
||||||
|
checkOverlappingMarkers(oms, map);
|
||||||
|
}
|
||||||
|
}, [map, siemensMarkers, oms]);
|
||||||
|
|
||||||
|
return siemensMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useSiemensMarkersLayer;
|
||||||
54
hooks/useSmsfunkmodemMarkersLayer.js
Normal file
54
hooks/useSmsfunkmodemMarkersLayer.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// hooks/useSmsfunkmodemMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import "leaflet-contextmenu";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
|
||||||
|
const useSmsfunkmodemMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [smsfunkmodemMarkers, setSmsfunkmodemMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && GisSystemStatic) {
|
||||||
|
const markers = GisSystemStatic.filter((station) => station.System === 111).map((station) => {
|
||||||
|
const marker = L.marker([station.Latitude, station.Longitude], {
|
||||||
|
icon: L.icon({
|
||||||
|
iconUrl: "/img/icons/pois/sms-funkmodem.png",
|
||||||
|
iconSize: [25, 41],
|
||||||
|
iconAnchor: [12, 41],
|
||||||
|
popupAnchor: [1, -34],
|
||||||
|
}),
|
||||||
|
id: station.id,
|
||||||
|
areaName: station.Area_Name,
|
||||||
|
draggable: false,
|
||||||
|
}).bindPopup(`
|
||||||
|
<div>
|
||||||
|
<b class="text-xl text-black-700">${station.Area_Name || "Unbekannt"}</b><br>
|
||||||
|
${station.Description || "No Description"}<br>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
|
||||||
|
return marker;
|
||||||
|
});
|
||||||
|
|
||||||
|
setSmsfunkmodemMarkers(markers);
|
||||||
|
markers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [map, GisSystemStatic, priorityConfig]);
|
||||||
|
|
||||||
|
return smsfunkmodemMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useSmsfunkmodemMarkersLayer;
|
||||||
45
hooks/useSonstigeMarkersLayer.js
Normal file
45
hooks/useSonstigeMarkersLayer.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// hooks/useSonstigeMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
|
||||||
|
const useSonstigeMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [sonstigeMarkers, setSonstigeMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(200, setSonstigeMarkers, GisSystemStatic, priorityConfig); // Sonstige
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && sonstigeMarkers.length) {
|
||||||
|
sonstigeMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
}
|
||||||
|
}, [map, sonstigeMarkers, oms]);
|
||||||
|
|
||||||
|
return sonstigeMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useSonstigeMarkersLayer;
|
||||||
102
hooks/useTalasMarkers.js
Normal file
102
hooks/useTalasMarkers.js
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
// /hooks/useTalasMarkers.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import "leaflet-contextmenu";
|
||||||
|
import { useRecoilValue } from "recoil";
|
||||||
|
import { mapLayersState } from "../store/atoms/mapLayersState.js";
|
||||||
|
import { selectedAreaState } from "../store/atoms/selectedAreaState.js";
|
||||||
|
import { zoomTriggerState } from "../store/atoms/zoomTriggerState.js";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils.js";
|
||||||
|
import { checkOverlappingMarkers } from "../utils/mapUtils.js";
|
||||||
|
import plusRoundIcon from "../components/PlusRoundIcon.js";
|
||||||
|
import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState.js";
|
||||||
|
|
||||||
|
const useTalasMarkers = (map, oms, layers, priorityConfig) => {
|
||||||
|
const [talasMarkers, setTalasMarkers] = useState([]);
|
||||||
|
const mapLayersVisibility = useRecoilValue(mapLayersState);
|
||||||
|
const selectedArea = useRecoilValue(selectedAreaState);
|
||||||
|
const zoomTrigger = useRecoilValue(zoomTriggerState);
|
||||||
|
const GisStationsStaticDistrict = useRecoilValue(gisStationsStaticDistrictState);
|
||||||
|
|
||||||
|
// Funktion zum Erstellen und Setzen der Marker
|
||||||
|
const createAndSetMarkers = (systemId, setMarkers, GisSystemStatic, priorityConfig) => {
|
||||||
|
const markers = GisSystemStatic.filter((station) => station.System === systemId).map((station) => {
|
||||||
|
const marker = L.marker([station.Latitude, station.Longitude], {
|
||||||
|
title: station.Name,
|
||||||
|
contextmenu: true,
|
||||||
|
contextmenuItems: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
marker.bindPopup(`<b>${station.Name}</b><br>${station.Description}`);
|
||||||
|
|
||||||
|
if (priorityConfig.includes(station.Priority)) {
|
||||||
|
marker.setIcon(
|
||||||
|
L.icon({
|
||||||
|
iconUrl: `/icons/priority_${station.Priority}.png`,
|
||||||
|
iconSize: [25, 41],
|
||||||
|
iconAnchor: [12, 41],
|
||||||
|
popupAnchor: [1, -34],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return marker;
|
||||||
|
});
|
||||||
|
|
||||||
|
setMarkers(markers);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && talasMarkers.length) {
|
||||||
|
talasMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
map.addLayer(layers.TALAS);
|
||||||
|
checkOverlappingMarkers(oms, map, plusRoundIcon);
|
||||||
|
}
|
||||||
|
}, [map, talasMarkers]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!map || !talasMarkers) return;
|
||||||
|
|
||||||
|
const toggleLayer = (isVisible) => {
|
||||||
|
if (isVisible) {
|
||||||
|
talasMarkers.forEach((marker) => marker.addTo(map));
|
||||||
|
} else {
|
||||||
|
talasMarkers.forEach((marker) => map.removeLayer(marker));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleLayer(mapLayersVisibility.TALAS);
|
||||||
|
}, [map, talasMarkers, mapLayersVisibility.TALAS]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedArea && map) {
|
||||||
|
const station = GisStationsStaticDistrict.find((s) => s.Area_Name === selectedArea);
|
||||||
|
if (station) {
|
||||||
|
map.flyTo([station.X, station.Y], 14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [selectedArea, map, GisStationsStaticDistrict]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (zoomTrigger && map) {
|
||||||
|
map.flyTo([51.41321407879154, 7.739617925303934], 7);
|
||||||
|
}
|
||||||
|
}, [zoomTrigger, map]);
|
||||||
|
|
||||||
|
return [talasMarkers, setTalasMarkers, createAndSetMarkers];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useTalasMarkers;
|
||||||
45
hooks/useTalasiclMarkersLayer.js
Normal file
45
hooks/useTalasiclMarkersLayer.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// hooks/useTalasiclMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
|
||||||
|
const useTalasiclMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [talasiclMarkers, setTalasiclMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(100, setTalasiclMarkers, GisSystemStatic, priorityConfig); // TALASICL
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && talasiclMarkers.length) {
|
||||||
|
talasiclMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
}
|
||||||
|
}, [map, talasiclMarkers, oms]);
|
||||||
|
|
||||||
|
return talasiclMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useTalasiclMarkersLayer;
|
||||||
76
hooks/useUlafMarkersLayer.js
Normal file
76
hooks/useUlafMarkersLayer.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// hooks/useUlafMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
//import { fetchDeviceNameById } from "../services/apiService";
|
||||||
|
|
||||||
|
const useUlafMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [ulafMarkers, setUlafMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!map || !GisSystemStatic) return;
|
||||||
|
|
||||||
|
const markers = [];
|
||||||
|
GisSystemStatic.forEach((station) => {
|
||||||
|
if (station.System === 0) {
|
||||||
|
// Adjust the condition to match ULAF system identification
|
||||||
|
const marker = L.marker([station.Lat, station.Lon], {
|
||||||
|
icon: L.icon({
|
||||||
|
iconUrl: "/img/icons/ulaf.png",
|
||||||
|
iconSize: [25, 41],
|
||||||
|
iconAnchor: [12, 41],
|
||||||
|
popupAnchor: [1, -34],
|
||||||
|
}),
|
||||||
|
id: station.id,
|
||||||
|
name: station.name,
|
||||||
|
description: station.description,
|
||||||
|
});
|
||||||
|
|
||||||
|
marker.bindPopup(`
|
||||||
|
<div>
|
||||||
|
<b class="text-xl text-black-700">${station.name || "Unbekannt"}</b><br>
|
||||||
|
${station.description || "Keine Beschreibung"}
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
marker.on("click", async () => {
|
||||||
|
//const deviceName = await fetchDeviceNameById(station.idLD);
|
||||||
|
marker
|
||||||
|
.bindPopup(
|
||||||
|
`
|
||||||
|
<div>
|
||||||
|
<b class="text-xl text-black-700">${station.name || "Unbekannt"}</b><br>
|
||||||
|
${deviceName}<br>
|
||||||
|
${station.description || "Keine Beschreibung"}
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
.openPopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
markers.push(marker);
|
||||||
|
if (map) marker.addTo(map);
|
||||||
|
if (oms) oms.addMarker(marker);
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setUlafMarkers(markers);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
markers.forEach((marker) => map.removeLayer(marker));
|
||||||
|
};
|
||||||
|
}, [map, GisSystemStatic, oms, priorityConfig]);
|
||||||
|
|
||||||
|
return ulafMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useUlafMarkersLayer;
|
||||||
49
hooks/useWagoMarkersLayer.js
Normal file
49
hooks/useWagoMarkersLayer.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// hooks/useWagoMarkersLayer.js
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
import { checkOverlappingMarkers } from "../utils/mapUtils";
|
||||||
|
|
||||||
|
const useWagoMarkersLayer = (map, oms, gisSystemStatic, priorityConfig) => {
|
||||||
|
const [wagoMarkers, setWagoMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (gisSystemStatic && gisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(7, setWagoMarkers, gisSystemStatic, priorityConfig); // WAGO-System
|
||||||
|
}
|
||||||
|
}, [gisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && wagoMarkers.length) {
|
||||||
|
wagoMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
// Call the function to check for overlapping markers
|
||||||
|
checkOverlappingMarkers(oms, map);
|
||||||
|
}
|
||||||
|
}, [map, wagoMarkers, oms]);
|
||||||
|
|
||||||
|
return wagoMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useWagoMarkersLayer;
|
||||||
45
hooks/useWdmMarkersLayer.js
Normal file
45
hooks/useWdmMarkersLayer.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// hooks/useWdmMarkersLayer.js
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { addContextMenuToMarker } from "../utils/contextMenuUtils";
|
||||||
|
import { createAndSetMarkers } from "../utils/markerUtils";
|
||||||
|
|
||||||
|
const useWdmMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => {
|
||||||
|
const [wdmMarkers, setWdmMarkers] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (GisSystemStatic && GisSystemStatic.length && map) {
|
||||||
|
createAndSetMarkers(10, setWdmMarkers, GisSystemStatic, priorityConfig); // WDM
|
||||||
|
}
|
||||||
|
}, [GisSystemStatic, map, priorityConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map && wdmMarkers.length) {
|
||||||
|
wdmMarkers.forEach((marker) => {
|
||||||
|
marker.addTo(map);
|
||||||
|
oms.addMarker(marker);
|
||||||
|
|
||||||
|
// Popup on mouseover and mouseout
|
||||||
|
marker.on("mouseover", function () {
|
||||||
|
this.openPopup();
|
||||||
|
});
|
||||||
|
marker.on("mouseout", function () {
|
||||||
|
this.closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
addContextMenuToMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable map context menu
|
||||||
|
map.options.contextmenu = false;
|
||||||
|
map.options.contextmenuItems = [];
|
||||||
|
|
||||||
|
oms.map.options.contextmenu = false;
|
||||||
|
oms.map.options.contextmenuItems = [];
|
||||||
|
}
|
||||||
|
}, [map, wdmMarkers, oms]);
|
||||||
|
|
||||||
|
return wdmMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useWdmMarkersLayer;
|
||||||
11
jest.config.js
Normal file
11
jest.config.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
module.exports = {
|
||||||
|
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
|
||||||
|
testEnvironment: "jest-environment-jsdom",
|
||||||
|
testPathIgnorePatterns: ["<rootDir>/.next/", "<rootDir>/node_modules/"],
|
||||||
|
transform: {
|
||||||
|
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",
|
||||||
|
},
|
||||||
|
moduleNameMapper: {
|
||||||
|
"\\.(css|less|scss|sass)$": "identity-obj-proxy",
|
||||||
|
},
|
||||||
|
};
|
||||||
3
jest.setup.js
Normal file
3
jest.setup.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// jest.setup.js
|
||||||
|
global.fetch = require("jest-fetch-mock");
|
||||||
|
jest.setMock("node-fetch", fetch);
|
||||||
8507
package-lock.json
generated
8507
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
43
package.json
43
package.json
@@ -1,36 +1,43 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^2.1.3",
|
"@heroicons/react": "^2.1.5",
|
||||||
"express": "^4.19.2",
|
"autoprefixer": "^10.4.19",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
"http-proxy-middleware": "^3.0.0",
|
"http-proxy-middleware": "^3.0.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"leaflet-contextmenu": "^1.4.0",
|
"leaflet-contextmenu": "^1.4.0",
|
||||||
"leaflet.smooth_marker_bouncing": "^3.0.3",
|
"leaflet.smooth_marker_bouncing": "^3.1.0",
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"mysql2": "^3.10.1",
|
"mysql2": "^3.11.0",
|
||||||
"next": "^14.2.3",
|
"next": "^14.2.5",
|
||||||
|
"nextjs-cors": "^2.2.0",
|
||||||
"overlapping-marker-spiderfier-leaflet": "^0.2.7",
|
"overlapping-marker-spiderfier-leaflet": "^0.2.7",
|
||||||
"react": "^18.2.0",
|
"postcss": "^8.4.40",
|
||||||
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-leaflet": "^4.2.1",
|
|
||||||
"react-toastify": "^10.0.5",
|
"react-toastify": "^10.0.5",
|
||||||
"recoil": "^0.7.7"
|
"recoil": "^0.7.7",
|
||||||
|
"tailwindcss": "^3.4.7"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"export": "next export"
|
"export": "next export",
|
||||||
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/leaflet": "^1.9.12",
|
"@babel/core": "^7.25.2",
|
||||||
"@types/leaflet-contextmenu": "^1.4.3",
|
"@babel/preset-env": "^7.25.2",
|
||||||
"@types/react": "^18.3.1",
|
"@babel/preset-react": "^7.24.7",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@testing-library/jest-dom": "^6.4.8",
|
||||||
"autoprefixer": "^10.4.19",
|
"@testing-library/react": "^16.0.0",
|
||||||
"postcss": "^8.4.38",
|
"@testing-library/user-event": "^14.5.2",
|
||||||
"prettier": "^3.2.5",
|
"babel-jest": "^29.7.0",
|
||||||
"tailwindcss": "^3.4.3"
|
"identity-obj-proxy": "^3.0.0",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
|
"jest-fetch-mock": "^3.0.3",
|
||||||
|
"node-fetch": "^3.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Pfad: pages/_app.js
|
// Pfad: pages/_app.js
|
||||||
import { RecoilRoot } from 'recoil';
|
import React from "react";
|
||||||
|
import { RecoilRoot } from "recoil";
|
||||||
import "../styles/global.css";
|
import "../styles/global.css";
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }) {
|
function MyApp({ Component, pageProps }) {
|
||||||
|
|||||||
20
pages/api back30/[...path].js
Normal file
20
pages/api back30/[...path].js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// pages/api/[...path].js
|
||||||
|
import { createProxyMiddleware } from "http-proxy-middleware";
|
||||||
|
import { SERVER_URL } from "../config/urls.js";
|
||||||
|
console.log("SERVER_URL:", SERVER_URL); // Debug-Ausgabe
|
||||||
|
|
||||||
|
export default createProxyMiddleware({
|
||||||
|
//target: "http://192.168.10.58:3001",
|
||||||
|
// Stationen bekommen
|
||||||
|
//target: "http://10.10.0.13", // Ziel-URL des Proxys // API Aufruf zum mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl und mapDataIconUrl
|
||||||
|
target: `${SERVER_URL}`, //
|
||||||
|
//target: urls.PROXY_TARGET,
|
||||||
|
//target: "http://localhost:3000", // Ziel-URL des Proxys
|
||||||
|
//target: "http://192.168.10.187:3000", // Ziel-URL des Proxys
|
||||||
|
//target: "http://192.168.10.14",
|
||||||
|
changeOrigin: true,
|
||||||
|
pathRewrite: {
|
||||||
|
"^/api": "/", // Optional: Entfernt /api aus dem Pfad, wenn das Backend dies nicht erfordert
|
||||||
|
},
|
||||||
|
logLevel: "debug", // Setzt das Logging-Level auf "debug" für detaillierte Ausgaben
|
||||||
|
});
|
||||||
20
pages/api back30/get-talasIP.js
Normal file
20
pages/api back30/get-talasIP.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// pages/api/get-talasIP.js
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
// Der x-forwarded-for Header könnte mehrere IP-Adressen enthalten, getrennt durch Kommas
|
||||||
|
let clientIp =
|
||||||
|
req.headers["x-forwarded-for"]?.split(",").map((ip) => ip.trim())[0] ||
|
||||||
|
req.socket.remoteAddress;
|
||||||
|
|
||||||
|
// Entfernen möglicher IPv6 "mapped" IPv4 Adressen
|
||||||
|
if (clientIp?.includes("::ffff:")) {
|
||||||
|
clientIp = clientIp.split("::ffff:")[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nur IPv4 Adressen weitergeben, IPv6 Adressen ausschließen
|
||||||
|
if (clientIp && clientIp.includes(":")) {
|
||||||
|
clientIp = ""; // Dies setzt die IP auf leer, wenn es sich um eine IPv6-Adresse handelt
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({ ip: clientIp });
|
||||||
|
}
|
||||||
34
pages/api back30/gis-proxy.js
Normal file
34
pages/api back30/gis-proxy.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// /pages/api/gis-proxy.js
|
||||||
|
// Importieren der erforderlichen Module
|
||||||
|
import httpProxy from "http-proxy";
|
||||||
|
import Cookies from "cookies";
|
||||||
|
|
||||||
|
// Erstellen eines Proxy-Servers
|
||||||
|
const proxy = httpProxy.createProxyServer();
|
||||||
|
|
||||||
|
export default (req, res) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
// CORS-Headers einstellen
|
||||||
|
res.setHeader("Access-Control-Allow-Credentials", true);
|
||||||
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
// Cookies initialisieren
|
||||||
|
const cookies = new Cookies(req, res);
|
||||||
|
const targetUrl = `${process.env.NEXT_PUBLIC_SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic`;
|
||||||
|
|
||||||
|
// Proxy-Konfiguration und Event-Listener
|
||||||
|
req.on("data", () => {});
|
||||||
|
req.on("end", () => {
|
||||||
|
proxy.web(req, res, { target: targetUrl, changeOrigin: true, selfHandleResponse: false }, (e) => {
|
||||||
|
if (e) {
|
||||||
|
console.error(e);
|
||||||
|
res.status(500).json({ error: "Proxy-Fehler", e });
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Weiterleitung der Headers
|
||||||
|
req.headers.cookie = cookies.get("cookie-name") || "";
|
||||||
|
});
|
||||||
|
};
|
||||||
64
pages/api back30/linesColorApi.js
Normal file
64
pages/api back30/linesColorApi.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
// /pages/api/linesColorApi.js
|
||||||
|
// http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisStationsStatusDistrict
|
||||||
|
//In DB gis_lines idLD und idModul anpassen entsprechend
|
||||||
|
|
||||||
|
// /pages/api/linesColorApi.js
|
||||||
|
import NextCors from "nextjs-cors";
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
// Run the cors middleware
|
||||||
|
await NextCors(req, res, {
|
||||||
|
// Options
|
||||||
|
methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"],
|
||||||
|
origin: "*", // Erlauben Sie alle Ursprünge, oder geben Sie spezifische Ursprünge an
|
||||||
|
optionsSuccessStatus: 200, // Legacy-Browser-Unterstützung für 204
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
Name: "Liste aller Statis der Linien",
|
||||||
|
Zeitstempel: new Date().toISOString(), // Aktuellen Zeitstempel hinzufügen
|
||||||
|
IdMap: "10",
|
||||||
|
Statis: [
|
||||||
|
/* {
|
||||||
|
IdLD: 50922,
|
||||||
|
Modul: 1,
|
||||||
|
DpName: "KUE01_Ausfall",
|
||||||
|
ModulName: "42 Wippershain Sender",
|
||||||
|
// ModulTyp: "nicht vorhanden",
|
||||||
|
ModulTyp: "KÜ705-FO",
|
||||||
|
Message: "KUEG 01: 42 Wippershain Sender Messwerkausfall kommend",
|
||||||
|
Level: 4,
|
||||||
|
PrioColor: "#FFFF00",
|
||||||
|
PrioName: "system",
|
||||||
|
Value: "10 MOhm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IdLD: 25440,
|
||||||
|
Modul: 3,
|
||||||
|
DpName: "KUE03_Ausfall",
|
||||||
|
ModulName: "42 Solz Sender",
|
||||||
|
//ModulTyp: "nicht vorhanden",
|
||||||
|
ModulTyp: "KÜSS V2",
|
||||||
|
Message: "KUEG 03: 42 Solz Sender Messwerkausfall kommend",
|
||||||
|
Level: 4,
|
||||||
|
PrioColor: "#FF0000",
|
||||||
|
PrioName: "system",
|
||||||
|
Value: "10 MOhm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IdLD: 25440,
|
||||||
|
Modul: 4,
|
||||||
|
DpName: "KUE04_Ausfall",
|
||||||
|
ModulName: "42/13 Bad Hersfeld Gaswerk",
|
||||||
|
ModulTyp: "Kue705-FO",
|
||||||
|
Message: "KUEG 04: 42/13 Bad Hersfeld Gaswerk Messwerkausfall kommend",
|
||||||
|
Level: 4,
|
||||||
|
PrioColor: "#FF00FF",
|
||||||
|
PrioName: "system",
|
||||||
|
Value: "10 MOhm",
|
||||||
|
}, */
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
res.status(200).json(response);
|
||||||
|
}
|
||||||
29
pages/api back30/rights.js
Normal file
29
pages/api back30/rights.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// pages/api/rights.js
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
const { idMap, idUser } = req.query;
|
||||||
|
|
||||||
|
// Beispielhafte Rechte, die je nach idMap und idUser variieren können
|
||||||
|
const rights = {
|
||||||
|
'10': [
|
||||||
|
{ IdRight: 1, Name: "Zugriff auf Dashboard" },
|
||||||
|
{ IdRight: 56, Name: "Erweiterte Berechtigungen" }
|
||||||
|
],
|
||||||
|
'2': [
|
||||||
|
{ IdRight: 2, Name: "Zugriff auf Einstellungen" }
|
||||||
|
],
|
||||||
|
'1': [
|
||||||
|
{ IdRight: 10, Name: "Admin-Zugriff" },
|
||||||
|
{ IdRight: 11, Name: "Zugriff auf alle Daten" }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prüfung, ob eine gültige idMap und idUser vorhanden sind
|
||||||
|
if (rights[idMap] && idUser === '484') {
|
||||||
|
// Rückgabe der spezifischen Rechte basierend auf der idMap und idUser
|
||||||
|
res.status(200).json({ Rights: rights[idMap] });
|
||||||
|
} else {
|
||||||
|
// Rückgabe leerer Rechte für ungültige idMap oder andere Benutzer
|
||||||
|
res.status(200).json({ Rights: [] });
|
||||||
|
}
|
||||||
|
}
|
||||||
40
pages/api back30/talas5/area.js
Normal file
40
pages/api back30/talas5/area.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// pages/api/talas_v5/area.js
|
||||||
|
// Lesen von talas_v5 MySQL-Datenbank -> area Tabelle enthält DAUZ Geräte
|
||||||
|
// Wenn gebraucht wird, dann nutzen ansonsten löschen
|
||||||
|
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
//console.log("my dbconfig: ", dbConfig);
|
||||||
|
export default function handler(req, res) {
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
res.status(500).json({ error: "Verbindungsfehler zur Datenbank" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log("Verbunden als ID", connection.threadId);
|
||||||
|
//Fehler weil, existiertdie Tabelle auf localhost:3000 nicht
|
||||||
|
connection.query("SELECT ..., ..., ..., ... FROM ... WHERE ... = ...", (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abrufen der API", error);
|
||||||
|
res.status(500).json({ error: "Fehler bei der Abfrage" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wichtig: Senden Sie die Antwort zurück
|
||||||
|
res.status(200).json(results);
|
||||||
|
|
||||||
|
connection.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
39
pages/api back30/talas5/location_device.js
Normal file
39
pages/api back30/talas5/location_device.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// pages/api/talas_v5/location_device.js
|
||||||
|
// talas_v5 Datenbank -> location_device Tabelle enthält DAUZ Geräte
|
||||||
|
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
//console.log("my dbconfig: ", dbConfig);
|
||||||
|
export default function handler(req, res) {
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
res.status(500).json({ error: "Verbindungsfehler zur Datenbank" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log("Verbunden als ID", connection.threadId);
|
||||||
|
//Fehler weil, existiertdie Tabelle auf localhost:3000 nicht
|
||||||
|
connection.query("SELECT idLD, iddevice, iddevice, name FROM location_device WHERE iddevice = 160", (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abrufen der API", error);
|
||||||
|
res.status(500).json({ error: "Fehler bei der Abfrage" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wichtig: Senden Sie die Antwort zurück
|
||||||
|
res.status(200).json(results);
|
||||||
|
|
||||||
|
connection.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
116
pages/api back30/talas5/webserviceMap/GisStationsMeasurements.js
Normal file
116
pages/api back30/talas5/webserviceMap/GisStationsMeasurements.js
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
// /pages/api/talas5/webserviceMap/GisStationsMeasurements.js
|
||||||
|
const GisStationsMeasurements = {
|
||||||
|
"Name": "Liste aller Messungen der Geraete",
|
||||||
|
"Zeitstempel": "2024-05-31T15:25:32.5047629+02:00",
|
||||||
|
"IdMap": "10",
|
||||||
|
"Statis": [
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 3,
|
||||||
|
"Na": "FBT",
|
||||||
|
"Val": "20.5",
|
||||||
|
"Unit": "°C",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 10,
|
||||||
|
"Na": "GT",
|
||||||
|
"Val": "nicht ermittelbar",
|
||||||
|
"Unit": "°C",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 2,
|
||||||
|
"Na": "LT",
|
||||||
|
"Val": "Datenlücke",
|
||||||
|
"Unit": "°C",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 6,
|
||||||
|
"Na": "RLF",
|
||||||
|
"Val": "100.0",
|
||||||
|
"Unit": "%",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 11,
|
||||||
|
"Na": "TPT",
|
||||||
|
"Val": "8.3",
|
||||||
|
"Unit": "°C",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 12,
|
||||||
|
"Na": "TT1",
|
||||||
|
"Val": "---",
|
||||||
|
"Unit": "°C",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 16,
|
||||||
|
"Na": "WFD",
|
||||||
|
"Val": "0.12",
|
||||||
|
"Unit": "mm",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 8,
|
||||||
|
"Na": "WGM",
|
||||||
|
"Val": "---",
|
||||||
|
"Unit": "m/s",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdLD": 50004,
|
||||||
|
"IdL": 18624,
|
||||||
|
"IdDP": 9,
|
||||||
|
"Na": "WGS",
|
||||||
|
"Val": "---",
|
||||||
|
"Unit": "m/s",
|
||||||
|
"Gr": "GMA",
|
||||||
|
"Area_Name": "Renzenhof (RG)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export an async function handler for the API route.
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
// Initialize an empty params object to store query parameters.
|
||||||
|
const params = {
|
||||||
|
idMap: req.query.idMap,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if the requested ID map and user match certain conditions.
|
||||||
|
if (params.idMap === '10') {
|
||||||
|
// If the conditions are met, return the GisStationsMeasurements object with a 200 status code.
|
||||||
|
res.status(200).json(GisStationsMeasurements);
|
||||||
|
} else {
|
||||||
|
// If not, return a 404 error with the message "Not Found".
|
||||||
|
res.status(404).send('Not Found');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,281 @@
|
|||||||
|
// /pages/api/talas5/webserviceMap/GisStationsStaticDistrict.js
|
||||||
|
const GisStationsStaticDistrict = {
|
||||||
|
"Name": "Liste aller Geraete einer bestimmten Karte",
|
||||||
|
"Zeitstempel": "2024-05-31T15:26:56.9235766+02:00",
|
||||||
|
"IdMap": "10",
|
||||||
|
"Points": [
|
||||||
|
{
|
||||||
|
"LD_Name": "CPL Bentheim",
|
||||||
|
"IdLD": 50017,
|
||||||
|
"Device": "CPL V3.5 mit 16 Kü",
|
||||||
|
"Link": "cpl.aspx?ver=35&kue=16&id=50017",
|
||||||
|
"Location_Name": "Technikraum",
|
||||||
|
"Location_Short": "BEHE",
|
||||||
|
"IdLocation": 17448,
|
||||||
|
"Area_Name": "Bad-Bentheim",
|
||||||
|
"Area_Short": "BEHE--00",
|
||||||
|
"IdArea": 16418,
|
||||||
|
"X": 51.5728,
|
||||||
|
"Y": 9.00056,
|
||||||
|
"Icon": 20,
|
||||||
|
"System": 1,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Drucker",
|
||||||
|
"IdLD": 50084,
|
||||||
|
"Device": "Basisgerät",
|
||||||
|
"Link": "basis.aspx?ver=1&id=50084",
|
||||||
|
"Location_Name": "Technikraum",
|
||||||
|
"Location_Short": "SLUE",
|
||||||
|
"IdLocation": 17776,
|
||||||
|
"Area_Name": "Schlüchtern II",
|
||||||
|
"Area_Short": "SLUE--00",
|
||||||
|
"IdArea": 14688,
|
||||||
|
"X": 53.2455,
|
||||||
|
"Y": 8.1614,
|
||||||
|
"Icon": 14,
|
||||||
|
"System": 200,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Türkontakt",
|
||||||
|
"IdLD": 50666,
|
||||||
|
"Device": "ECI",
|
||||||
|
"Link": "eci.aspx?ver=1&id=50666",
|
||||||
|
"Location_Name": "Technikraum",
|
||||||
|
"Location_Short": "SLUE",
|
||||||
|
"IdLocation": 17776,
|
||||||
|
"Area_Name": "Schlüchtern II",
|
||||||
|
"Area_Short": "SLUE--00",
|
||||||
|
"IdArea": 14688,
|
||||||
|
"X": 53.2455,
|
||||||
|
"Y": 8.1614,
|
||||||
|
"Icon": 17,
|
||||||
|
"System": 2,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Triptis",
|
||||||
|
"IdLD": 50888,
|
||||||
|
"Device": "CPL 200",
|
||||||
|
"Link": "cpl.aspx?ver=30&kue=16&id=50888",
|
||||||
|
"Location_Name": "Technikraum",
|
||||||
|
"Location_Short": "SLUE",
|
||||||
|
"IdLocation": 17776,
|
||||||
|
"Area_Name": "Schlüchtern II",
|
||||||
|
"Area_Short": "SLUE--00",
|
||||||
|
"IdArea": 14688,
|
||||||
|
"X": 53.2455,
|
||||||
|
"Y": 8.1614,
|
||||||
|
"Icon": 20,
|
||||||
|
"System": 1,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Rodaborn I",
|
||||||
|
"IdLD": 50889,
|
||||||
|
"Device": "cpl.mio V>6",
|
||||||
|
"Link": "cplmio.aspx?ver=1&id=50889",
|
||||||
|
"Location_Name": "Technikraum",
|
||||||
|
"Location_Short": "SLUE",
|
||||||
|
"IdLocation": 17776,
|
||||||
|
"Area_Name": "Schlüchtern II",
|
||||||
|
"Area_Short": "SLUE--00",
|
||||||
|
"IdArea": 14688,
|
||||||
|
"X": 53.2455,
|
||||||
|
"Y": 8.1614,
|
||||||
|
"Icon": 20,
|
||||||
|
"System": 1,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Rodaborn II",
|
||||||
|
"IdLD": 50900,
|
||||||
|
"Device": "cpl.mio V>6",
|
||||||
|
"Link": "cplmio.aspx?ver=1&id=50900",
|
||||||
|
"Location_Name": "Technikraum",
|
||||||
|
"Location_Short": "SLUE",
|
||||||
|
"IdLocation": 17776,
|
||||||
|
"Area_Name": "Schlüchtern II",
|
||||||
|
"Area_Short": "SLUE--00",
|
||||||
|
"IdArea": 14688,
|
||||||
|
"X": 53.2455,
|
||||||
|
"Y": 8.1614,
|
||||||
|
"Icon": 20,
|
||||||
|
"System": 1,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Hermsdorf",
|
||||||
|
"IdLD": 50901,
|
||||||
|
"Device": "CPL V3.5 mit 24 Kü",
|
||||||
|
"Link": "cpl.aspx?ver=35&kue=24&id=50901",
|
||||||
|
"Location_Name": "Technikraum",
|
||||||
|
"Location_Short": "SLUE",
|
||||||
|
"IdLocation": 17776,
|
||||||
|
"Area_Name": "Schlüchtern II",
|
||||||
|
"Area_Short": "SLUE--00",
|
||||||
|
"IdArea": 14688,
|
||||||
|
"X": 53.2455,
|
||||||
|
"Y": 8.1614,
|
||||||
|
"Icon": 20,
|
||||||
|
"System": 1,
|
||||||
|
"Active": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "GMA Littwin (TEST)",
|
||||||
|
"IdLD": 50004,
|
||||||
|
"Device": "Glättemeldeanlage",
|
||||||
|
"Link": "gma.aspx?ver=1&id=50004",
|
||||||
|
"Location_Name": "RG Relaisraum",
|
||||||
|
"Location_Short": "REZR",
|
||||||
|
"IdLocation": 18624,
|
||||||
|
"Area_Name": "Renzenhof (RG)",
|
||||||
|
"Area_Short": "REZHRG00",
|
||||||
|
"IdArea": 16570,
|
||||||
|
"X": 53.246036,
|
||||||
|
"Y": 8.163293,
|
||||||
|
"Icon": 1,
|
||||||
|
"System": 11,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "NRS Testserver",
|
||||||
|
"IdLD": 50005,
|
||||||
|
"Device": "Notruf Server",
|
||||||
|
"Link": "nrs_server.aspx?ver=1&id=50005",
|
||||||
|
"Location_Name": "(EV Ammersricht BZR REL)",
|
||||||
|
"Location_Short": "AMME",
|
||||||
|
"IdLocation": 21118,
|
||||||
|
"Area_Name": "Ammersricht BZR (FGN)",
|
||||||
|
"Area_Short": "AMMER--00",
|
||||||
|
"IdArea": 15958,
|
||||||
|
"X": 52.52726,
|
||||||
|
"Y": 12.165488,
|
||||||
|
"Icon": 19,
|
||||||
|
"System": 8,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Gateway 2",
|
||||||
|
"IdLD": 50007,
|
||||||
|
"Device": "Notruf Server",
|
||||||
|
"Link": "nrs_server.aspx?ver=1&id=50007",
|
||||||
|
"Location_Name": "(EV Ammersricht BZR REL)",
|
||||||
|
"Location_Short": "AMME",
|
||||||
|
"IdLocation": 21118,
|
||||||
|
"Area_Name": "Ammersricht BZR (FGN)",
|
||||||
|
"Area_Short": "AMMER--00",
|
||||||
|
"IdArea": 15958,
|
||||||
|
"X": 52.52726,
|
||||||
|
"Y": 12.165488,
|
||||||
|
"Icon": 19,
|
||||||
|
"System": 8,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Basisgerät mit SNMP MVP",
|
||||||
|
"IdLD": 50669,
|
||||||
|
"Device": "Basisgerät + SNMP",
|
||||||
|
"Link": "basisSNMP.aspx?&ver=1&id=50669",
|
||||||
|
"Location_Name": "Mylinghauserstraße Engelbert",
|
||||||
|
"Location_Short": "G-GEVELSBE-1",
|
||||||
|
"IdLocation": 24012,
|
||||||
|
"Area_Name": "Gevelsberg",
|
||||||
|
"Area_Short": "GMA-GEVELSBE",
|
||||||
|
"IdArea": 20919,
|
||||||
|
"X": 51.316799,
|
||||||
|
"Y": 7.33281,
|
||||||
|
"Icon": 14,
|
||||||
|
"System": 200,
|
||||||
|
"Active": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Server 3",
|
||||||
|
"IdLD": 50009,
|
||||||
|
"Device": "Notruf Server",
|
||||||
|
"Link": "nrs_server.aspx?ver=1&id=50009",
|
||||||
|
"Location_Name": "Militärringstraße Militärringstraße",
|
||||||
|
"Location_Short": "G-KÖLN-1",
|
||||||
|
"IdLocation": 24015,
|
||||||
|
"Area_Name": "Köln",
|
||||||
|
"Area_Short": "GMA-KÖLN",
|
||||||
|
"IdArea": 20921,
|
||||||
|
"X": 50.898399,
|
||||||
|
"Y": 6.92278,
|
||||||
|
"Icon": 19,
|
||||||
|
"System": 8,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "ICL Test 5",
|
||||||
|
"IdLD": 50054,
|
||||||
|
"Device": "ICL",
|
||||||
|
"Link": "icl.aspx?ver=1&id=50054",
|
||||||
|
"Location_Name": "Recheder Mühlenweg Dortmund-Ems-Kanal",
|
||||||
|
"Location_Short": "G-OLFEN-SE-1",
|
||||||
|
"IdLocation": 24022,
|
||||||
|
"Area_Name": "Olfen-Selm",
|
||||||
|
"Area_Short": "GMA-OLFEN-SE",
|
||||||
|
"IdArea": 20926,
|
||||||
|
"X": 51.702202,
|
||||||
|
"Y": 7.40822,
|
||||||
|
"Icon": 23,
|
||||||
|
"System": 100,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "ICL Test 3",
|
||||||
|
"IdLD": 50052,
|
||||||
|
"Device": "ICL",
|
||||||
|
"Link": "icl.aspx?ver=1&id=50052",
|
||||||
|
"Location_Name": "Weidenstraße Hestenberg",
|
||||||
|
"Location_Short": "G-PLETTENB-1",
|
||||||
|
"IdLocation": 24024,
|
||||||
|
"Area_Name": "Plettenberg",
|
||||||
|
"Area_Short": "GMA-PLETTENB",
|
||||||
|
"IdArea": 20928,
|
||||||
|
"X": 51.224098,
|
||||||
|
"Y": 7.86969,
|
||||||
|
"Icon": 23,
|
||||||
|
"System": 100,
|
||||||
|
"Active": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LD_Name": "Test Februar Kai",
|
||||||
|
"IdLD": 50912,
|
||||||
|
"Device": "Dauerzählstelle DZ",
|
||||||
|
"Link": "dauz.aspx?ver=1&id=50912",
|
||||||
|
"Location_Name": "In der Hoffnung Kiesberg - BG Ost",
|
||||||
|
"Location_Short": "G-WUPPERTA-4",
|
||||||
|
"IdLocation": 24039,
|
||||||
|
"Area_Name": "Wuppertal",
|
||||||
|
"Area_Short": "GMA-WUPPERTA",
|
||||||
|
"IdArea": 20937,
|
||||||
|
"X": 51.238899,
|
||||||
|
"Y": 7.12715,
|
||||||
|
"Icon": 14,
|
||||||
|
"System": 110,
|
||||||
|
"Active": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export an async function handler for the API route.
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
// Initialize an empty params object to store query parameters.
|
||||||
|
const params = {
|
||||||
|
idMap: req.query.idMap,
|
||||||
|
idUser: req.query.idUser
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if the requested ID map and user match certain conditions.
|
||||||
|
if (params.idMap === '10' && params.idUser === '484') {
|
||||||
|
// If the conditions are met, return the GisStationsStaticDistrict object with a 200 status code.
|
||||||
|
res.status(200).json(GisStationsStaticDistrict);
|
||||||
|
} else {
|
||||||
|
// If not, return a 404 error with the message "Not Found".
|
||||||
|
res.status(404).send('Not Found');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import mysql from "mysql2/promise";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
const { idMap, idUser } = req.query;
|
||||||
|
|
||||||
|
if (!idMap || !idUser) {
|
||||||
|
res.status(400).json({ error: "idMap and idUser are required" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let connection;
|
||||||
|
try {
|
||||||
|
connection = await mysql.createConnection(dbConfig);
|
||||||
|
|
||||||
|
let onlySystem = -1;
|
||||||
|
let districtCounter = 0;
|
||||||
|
|
||||||
|
// Get onlySystem
|
||||||
|
const [mapResult] = await connection.execute(
|
||||||
|
"SELECT idsystem_typ FROM maps WHERE id = ?",
|
||||||
|
[idMap]
|
||||||
|
);
|
||||||
|
if (mapResult.length > 0) {
|
||||||
|
onlySystem = mapResult[0].idsystem_typ ?? -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get districtCounter
|
||||||
|
if (idUser > 0) {
|
||||||
|
const [userLayerResult] = await connection.execute(
|
||||||
|
"SELECT count(*) as count FROM user_User_layer1 WHERE iduser = ?",
|
||||||
|
[idUser]
|
||||||
|
);
|
||||||
|
districtCounter = userLayerResult[0].count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get GisStatusStations
|
||||||
|
let query = `
|
||||||
|
SELECT ld.idLD, dc.message, p.level, p.name, p.color, ld.idDevice, de.isService, dc.idIcon
|
||||||
|
FROM location as l
|
||||||
|
LEFT JOIN location_coordinates AS co ON l.idLocation = co.idLocation and co.idMaps = ?
|
||||||
|
LEFT JOIN location_device AS ld ON ld.idLocation = l.idLocation
|
||||||
|
LEFT JOIN datapoint as d ON d.idLD = ld.idLD
|
||||||
|
LEFT JOIN datapoint_conditions AS dc ON dc.idcondition = d.last_message_condition
|
||||||
|
LEFT JOIN prio AS p ON p.idPrio = dc.idprio
|
||||||
|
LEFT JOIN devices AS de ON de.idDevice = ld.idDevice
|
||||||
|
LEFT JOIN area as a on a.idArea = l.idArea
|
||||||
|
WHERE p.level < 100 AND co.X > 0
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (districtCounter > 0) {
|
||||||
|
query += ` AND a.iddistrict IN (SELECT iddistrict FROM user_user_layer1 WHERE iduser = ?)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onlySystem >= 0) {
|
||||||
|
query += ` AND de.idsystem_typ = ?`;
|
||||||
|
}
|
||||||
|
|
||||||
|
query += ` ORDER BY p.level desc`;
|
||||||
|
|
||||||
|
const queryParams = [idMap];
|
||||||
|
if (districtCounter > 0) {
|
||||||
|
queryParams.push(idUser);
|
||||||
|
}
|
||||||
|
if (onlySystem >= 0) {
|
||||||
|
queryParams.push(onlySystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [results] = await connection.execute(query, queryParams);
|
||||||
|
|
||||||
|
const mpss = {
|
||||||
|
IdMap: idMap.toString(),
|
||||||
|
Statis: results.map((row) => ({
|
||||||
|
IdLD: row.idLD ?? -1,
|
||||||
|
Le: row.level ?? -1,
|
||||||
|
Me: row.message ?? "?",
|
||||||
|
Na: row.name ?? "?",
|
||||||
|
Co: row.color ?? "#ffffff",
|
||||||
|
Feld: row.idDevice ?? -1,
|
||||||
|
Icon: row.idIcon ?? 0,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
res.status(200).json(mpss);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Laden der Daten:", error);
|
||||||
|
res.status(500).json({ error: "Interner Serverfehler" });
|
||||||
|
} finally {
|
||||||
|
if (connection) {
|
||||||
|
await connection.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
273
pages/api back30/talas5/webserviceMap/GisSystemStatic.js
Normal file
273
pages/api back30/talas5/webserviceMap/GisSystemStatic.js
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
// /pages/api/webServiceMap.js
|
||||||
|
const gisSystemStatic = {
|
||||||
|
"Name": "Liste aller angezeigten Systeme",
|
||||||
|
"Zeitstempel": "2024-05-31T15:08:49.8599542+02:00",
|
||||||
|
"IdMap": "10",
|
||||||
|
"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": 5,
|
||||||
|
"Name": "GSM 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 Notrufsystem",
|
||||||
|
"Allow": 0,
|
||||||
|
"Icon": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdSystem": 9,
|
||||||
|
"Name": "OTDR",
|
||||||
|
"Longname": "Glasfaserüberwachung OTU",
|
||||||
|
"Allow": 0,
|
||||||
|
"Icon": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdSystem": 10,
|
||||||
|
"Name": "WDM",
|
||||||
|
"Longname": " Wavelength Division Multiplexing",
|
||||||
|
"Allow": 0,
|
||||||
|
"Icon": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdSystem": 11,
|
||||||
|
"Name": "GMA",
|
||||||
|
"Longname": "Glättemeldeanlagen",
|
||||||
|
"Allow": 1,
|
||||||
|
"Icon": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdSystem": 13,
|
||||||
|
"Name": "Messstellen",
|
||||||
|
"Longname": "Messstellen",
|
||||||
|
"Allow": 0,
|
||||||
|
"Icon": 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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-Funkmodem",
|
||||||
|
"Longname": "SMS-Funkmodem",
|
||||||
|
"Allow": 0,
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export an async function handler for the API route.
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
// Initialize an empty params object to store query parameters.
|
||||||
|
const params = {
|
||||||
|
idMap: req.query.idMap,
|
||||||
|
idUser: req.query.idUser
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if the requested ID map and user match certain conditions.
|
||||||
|
if (params.idMap === '10' && params.idUser === '484') {
|
||||||
|
// If the conditions are met, return the gisSystemStatic object with a 200 status code.
|
||||||
|
res.status(200).json(gisSystemStatic);
|
||||||
|
} else {
|
||||||
|
// If not, return a 404 error with the message "Not Found".
|
||||||
|
res.status(404).send('Not Found');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Database connected successfully.");
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
const idMap = req.query.idMap;
|
||||||
|
if (req.method !== "GET") {
|
||||||
|
return res.status(405).json({ error: "Nur GET Methode erlaubt" });
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.query(`
|
||||||
|
SELECT
|
||||||
|
ld.idLD,
|
||||||
|
dp.idDP,
|
||||||
|
dp.name AS Na,
|
||||||
|
dp.value AS Val,
|
||||||
|
dp.unit AS Unit,
|
||||||
|
mg.name AS Gr,
|
||||||
|
ld.idLocation,
|
||||||
|
area.Name AS Area_Name
|
||||||
|
FROM location_device as ld
|
||||||
|
LEFT JOIN location_coordinates AS co ON ld.idLocation = co.idLocation and co.idMaps = ${idMap}
|
||||||
|
LEFT JOIN devices AS de ON de.idDevice = ld.idDevice
|
||||||
|
LEFT JOIN datapoint AS dp ON ld.idLD = dp.idLD
|
||||||
|
LEFT JOIN message_group AS mg ON dp.idmessage_group = mg.idmessage_group
|
||||||
|
LEFT JOIN location AS loc ON ld.idLocation = loc.idLocation
|
||||||
|
LEFT JOIN area AS area ON loc.idArea = area.idArea
|
||||||
|
WHERE co.X > 0 AND dp.idmessage_group>0 AND length(dp.unit)> 0 AND length(dp.value)> 0
|
||||||
|
`, (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abrufen der gis_lines:", error);
|
||||||
|
return res
|
||||||
|
.status(500)
|
||||||
|
.json({ error: "Fehler beim Abrufen der gis_lines" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
"Name": "Liste aller Messungen der Geraete",
|
||||||
|
"Zeitstempel": new Date().toISOString(),
|
||||||
|
"IdMap":idMap,
|
||||||
|
"Statis": results.map((row) => ({
|
||||||
|
IdLD: row.idLD,
|
||||||
|
IdDP: row.idDP,
|
||||||
|
Na: row.Na,
|
||||||
|
Val: row.Val,
|
||||||
|
Unit: row.Unit,
|
||||||
|
Gr: row.Gr,
|
||||||
|
IdLocation: row.IdLocation,
|
||||||
|
Area_Name: row.Area_Name,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
res.json(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
37
pages/api back30/talas_v5_DB/gisLines/readGisLines.js
Normal file
37
pages/api back30/talas_v5_DB/gisLines/readGisLines.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// /pages/api/talas_v5_DB/gisLines/readGisLines.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//console.log("Database connected successfully.");
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method !== "GET") {
|
||||||
|
return res.status(405).json({ error: "Nur GET Methode erlaubt" });
|
||||||
|
}
|
||||||
|
const query = "SELECT * FROM talas_v5.gis_lines;";
|
||||||
|
connection.query(query, (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abrufen der gis_lines:", error);
|
||||||
|
return res.status(500).json({ error: "Fehler beim Abrufen der gis_lines" });
|
||||||
|
}
|
||||||
|
if (results.length > 0) {
|
||||||
|
res.json(results);
|
||||||
|
} else {
|
||||||
|
res.status(404).json({ error: "Gerät nicht gefunden" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// /pages/api/talas_v5_DB/gisLines/updateLineCoordinates.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//console.log("Database connected successfully.");
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
return res.status(405).json({ error: "Nur POST Methode erlaubt" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { idLD, idModul, newCoordinates } = req.body;
|
||||||
|
if (!idLD || !idModul || !newCoordinates) {
|
||||||
|
return res.status(400).json({ error: "Fehlende Daten" });
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = ?;";
|
||||||
|
|
||||||
|
connection.beginTransaction((err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
connection.query(query, [newLineString, idLD, idModul], (error, results, fields) => {
|
||||||
|
if (error) {
|
||||||
|
return connection.rollback(() => {
|
||||||
|
console.error("Fehler beim Aktualisieren der gis_lines:", error);
|
||||||
|
res.status(500).json({ error: "Fehler beim Aktualisieren der gis_lines" });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.commit((err) => {
|
||||||
|
if (err) {
|
||||||
|
return connection.rollback(() => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log("Transaction Complete.");
|
||||||
|
res.status(200).json({
|
||||||
|
success: "Updated successfully.",
|
||||||
|
affectedRows: results.affectedRows,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
40
pages/api back30/talas_v5_DB/locationDevice/getDeviceId.js
Normal file
40
pages/api back30/talas_v5_DB/locationDevice/getDeviceId.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// API in /api/talas_v5_DB/locationDevice/getDeviceId.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method !== "GET") {
|
||||||
|
return res.status(405).json({ error: "Nur GET Methode erlaubt" });
|
||||||
|
}
|
||||||
|
const { deviceName } = req.query;
|
||||||
|
|
||||||
|
const query = "SELECT idLD FROM location_device WHERE name = ?";
|
||||||
|
connection.query(query, [deviceName], (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abrufen der Geräte-ID:", error);
|
||||||
|
return res
|
||||||
|
.status(500)
|
||||||
|
.json({ error: "Fehler beim Abrufen der Geräte-ID" });
|
||||||
|
}
|
||||||
|
if (results.length > 0) {
|
||||||
|
res.json({ idLD: results[0].idLD });
|
||||||
|
} else {
|
||||||
|
res.status(404).json({ error: "Gerät nicht gefunden" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// API in /api/talas_v5_DB/locationDevice/locationDeviceNameById.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
if (req.method !== "GET") {
|
||||||
|
return res.status(405).json({ error: "Nur GET Methode erlaubt" });
|
||||||
|
}
|
||||||
|
const { idLD } = req.query;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query = "SELECT name FROM location_device WHERE idLD = ?";
|
||||||
|
const [results] = await new Promise((resolve, reject) => {
|
||||||
|
connection.query(query, [idLD], (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
return reject(error);
|
||||||
|
}
|
||||||
|
resolve(results);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (results.length > 0) {
|
||||||
|
res.json({ name: results[0].name });
|
||||||
|
} else {
|
||||||
|
res.status(404).json({ error: "Gerät nicht gefunden", idLD, results });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen des Gerätenamens in locationDeviceNameById.js :", error);
|
||||||
|
res.status(500).json({ error: "Fehler beim Abrufen des Gerätenamens" });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
// API in /api/talas_v5_DB/locationDevice/locationDevices.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method !== "GET") {
|
||||||
|
return res.status(405).json({ error: "Nur GET Methode erlaubt" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = "SELECT * FROM location_device WHERE iddevice = 160";
|
||||||
|
connection.query(query, (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abrufen der Geräteinformationen:", error);
|
||||||
|
return res
|
||||||
|
.status(500)
|
||||||
|
.json({ error: "Fehler beim Abrufen der Geräteinformationen" });
|
||||||
|
}
|
||||||
|
res.json(results);
|
||||||
|
});
|
||||||
|
}
|
||||||
33
pages/api back30/talas_v5_DB/poiTyp/readPoiTyp.js
Normal file
33
pages/api back30/talas_v5_DB/poiTyp/readPoiTyp.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// pages/api/talas_v5_DB/poiTyp/readPoiTyp.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const pool = mysql.createPool({
|
||||||
|
//connectionLimit: 10,
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method === "GET") {
|
||||||
|
const query = "SELECT * FROM poityp";
|
||||||
|
|
||||||
|
pool.query(query, (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abfragen der Datenbank:", error);
|
||||||
|
return res.status(500).json({ error: "Ein Fehler ist aufgetreten" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
return res.status(404).json({ message: "Keine Einträge gefunden" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json(results);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.setHeader("Allow", ["GET"]);
|
||||||
|
res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
38
pages/api back30/talas_v5_DB/pois/addLocation.js
Normal file
38
pages/api back30/talas_v5_DB/pois/addLocation.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// pages/api/talas_v5_DB/pois/addLocation.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method === "POST") {
|
||||||
|
const { name, poiTypeId, latitude, longitude, idLD } = req.body;
|
||||||
|
console.log("Received data:", req.body); // Überprüfen der empfangenen Daten
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
|
||||||
|
const query =
|
||||||
|
"INSERT INTO poi (description, idPoiTyp, position, idLD) VALUES (?, ?, ST_GeomFromText(?),?)";
|
||||||
|
const point = `POINT(${longitude} ${latitude})`;
|
||||||
|
const values = [name, poiTypeId, point, idLD]; // Stellen Sie sicher, dass poiTypeId korrekt ist
|
||||||
|
|
||||||
|
connection.query(query, values, (error, results) => {
|
||||||
|
connection.end();
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Einfügen des Standorts:", error);
|
||||||
|
return res.status(500).json({ error: "Ein Fehler ist aufgetreten" });
|
||||||
|
}
|
||||||
|
res.status(200).json({
|
||||||
|
id: results.insertId,
|
||||||
|
message: "Standort erfolgreich hinzugefügt",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.setHeader("Allow", ["POST"]);
|
||||||
|
res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
45
pages/api back30/talas_v5_DB/pois/deletePoi.js
Normal file
45
pages/api back30/talas_v5_DB/pois/deletePoi.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// pages/api/talas_v5_DB/pois/deletePoi.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
// Datenbankkonfiguration
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Verbunden als ID", connection.threadId);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method !== "DELETE") {
|
||||||
|
return res.status(405).json({ error: "Nur DELETE Methode erlaubt" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id } = req.query; // ID aus der Anfrage holen
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
return res.status(400).json({ error: "POI ID ist erforderlich" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = "DELETE FROM poi WHERE idPoi = ?";
|
||||||
|
connection.query(query, [id], (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Löschen des POI:", error);
|
||||||
|
return res.status(500).json({ error: "Fehler beim Löschen des POI" });
|
||||||
|
}
|
||||||
|
if (results.affectedRows > 0) {
|
||||||
|
res.json({ message: "POI erfolgreich gelöscht" });
|
||||||
|
} else {
|
||||||
|
res.status(404).json({ error: "POI nicht gefunden" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
42
pages/api back30/talas_v5_DB/pois/getPoiById.js
Normal file
42
pages/api back30/talas_v5_DB/pois/getPoiById.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// pages/api/talas_v5_DB/pois/getPoiById.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method === "GET") {
|
||||||
|
const { idPoi } = req.query;
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return res
|
||||||
|
.status(500)
|
||||||
|
.json({ error: "Verbindungsfehler zur Datenbank" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = "SELECT description FROM poi WHERE idPoi = ?";
|
||||||
|
connection.query(query, [idPoi], (error, results) => {
|
||||||
|
connection.end();
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler bei der Abfrage:", error);
|
||||||
|
return res.status(500).json({ error: "Fehler bei der Abfrage" });
|
||||||
|
}
|
||||||
|
if (results.length === 0) {
|
||||||
|
return res.status(404).json({ error: "POI nicht gefunden" });
|
||||||
|
}
|
||||||
|
res.status(200).json(results[0]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.setHeader("Allow", ["GET"]);
|
||||||
|
res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
42
pages/api back30/talas_v5_DB/pois/poi-icons.js
Normal file
42
pages/api back30/talas_v5_DB/pois/poi-icons.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// pages/api/talas_v5_DB/pois/poi-icons.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method !== "GET") {
|
||||||
|
return res.status(405).json({ error: "Nur GET Methode erlaubt" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `SELECT p.idPoi, i.path
|
||||||
|
FROM poi p
|
||||||
|
JOIN poiTyp pt ON p.idPoiTyp = pt.idPoiTyp
|
||||||
|
JOIN poiicons i ON pt.icon = i.idpoiicons;`;
|
||||||
|
|
||||||
|
connection.query(query, (error, results) => {
|
||||||
|
try {
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
res.json(results);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Fehler beim Abrufen der icons:", err);
|
||||||
|
res.status(500).json({ error: "Fehler beim Abrufen der icons" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
42
pages/api back30/talas_v5_DB/pois/readLocations.js
Normal file
42
pages/api back30/talas_v5_DB/pois/readLocations.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// pages/api/talas_v5_DB/pois/readLocations.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
//console.log("my dbconfig: ", dbConfig);
|
||||||
|
export default function handler(req, res) {
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
res.status(500).json({ error: "Verbindungsfehler zur Datenbank" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log("Verbunden als ID", connection.threadId);
|
||||||
|
|
||||||
|
connection.query("SELECT idPoi, description, idPoiTyp, idLD, ST_AsText(position) AS position FROM poi", (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abrufen der API", error);
|
||||||
|
res.status(500).json({ error: "Fehler bei der Abfrage" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wichtig: Senden Sie die Antwort zurück
|
||||||
|
res.status(200).json(results);
|
||||||
|
/* console.log(
|
||||||
|
"--------------- location.js ---------------",
|
||||||
|
"results in location.js : ",
|
||||||
|
results,
|
||||||
|
"---------------------- location.js end ---------------------------"
|
||||||
|
); */
|
||||||
|
connection.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
39
pages/api back30/talas_v5_DB/pois/updateLocation.js
Normal file
39
pages/api back30/talas_v5_DB/pois/updateLocation.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// pages/api/talas_v5_DB/pois/updateLocation.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
import util from "util";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
charset: "utf8mb4",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
res.setHeader("Allow", ["POST"]);
|
||||||
|
return res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id, latitude, longitude } = req.body;
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
// Promisify the query method
|
||||||
|
const query = util.promisify(connection.query).bind(connection);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await query("UPDATE poi SET position = POINT(?, ?) WHERE idPoi = ?", [
|
||||||
|
longitude,
|
||||||
|
latitude,
|
||||||
|
id,
|
||||||
|
]);
|
||||||
|
res.status(200).json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({ error: "Ein Fehler ist aufgetreten" });
|
||||||
|
} finally {
|
||||||
|
connection.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
46
pages/api back30/talas_v5_DB/pois/updatePoi.js
Normal file
46
pages/api back30/talas_v5_DB/pois/updatePoi.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// pages/api/talas_v5_DB/pois/updatePoi.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//console.log("Verbunden als ID", connection.threadId);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
return res.status(405).json({ error: "Nur POST Methode erlaubt" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { idPoi, description, idPoiTyp, idLD } = req.body; // Stellen Sie sicher, dass die Felder korrekt benannt sind
|
||||||
|
|
||||||
|
//console.log("Empfangene Daten:", req.body); // Loggen der empfangenen Daten zur Überprüfung
|
||||||
|
|
||||||
|
if (!idPoi) {
|
||||||
|
return res.status(400).json({ error: "POI ID ist erforderlich" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = "UPDATE talas_v5.poi SET description = ?, idPoiTyp = ?, idLD = ? WHERE idPoi = ?";
|
||||||
|
connection.query(query, [description, idPoiTyp, idLD, idPoi], (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Aktualisieren des POI:", error);
|
||||||
|
return res.status(500).json({ error: "Fehler beim Aktualisieren des POI" });
|
||||||
|
}
|
||||||
|
if (results.affectedRows > 0) {
|
||||||
|
res.json({ message: "POI erfolgreich aktualisiert" });
|
||||||
|
} else {
|
||||||
|
res.status(404).json({ error: "POI nicht gefunden" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
pages/api back30/talas_v5_DB/priorityConfig.js
Normal file
40
pages/api back30/talas_v5_DB/priorityConfig.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// pages/api/talas_v5_DB/priorityConfig.js
|
||||||
|
// in tals5 http://10.10.0.13/talas5/Management/PriorityConfig.aspx beinhaltet die Tabelle prio die Prioritäten der Meldungen (Level 1-4) oder (0-4) je nachdem DB-Design
|
||||||
|
// das ist die API, die die Prioritäten zurückgibt
|
||||||
|
|
||||||
|
import mysql from "mysql";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
};
|
||||||
|
//console.log("my dbconfig: ", dbConfig);
|
||||||
|
export default function handler(req, res) {
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Fehler beim Verbinden:", err.stack);
|
||||||
|
res.status(500).json({ error: "Verbindungsfehler zur Datenbank" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log("Verbunden als ID", connection.threadId);
|
||||||
|
//Fehler weil, existiertdie Tabelle auf localhost:3000 nicht
|
||||||
|
connection.query("SELECT idprio, level, name, color FROM prio ", (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("Fehler beim Abrufen der API", error);
|
||||||
|
res.status(500).json({ error: "Fehler bei der Abfrage" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wichtig: Senden Sie die Antwort zurück
|
||||||
|
res.status(200).json(results);
|
||||||
|
|
||||||
|
connection.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
// pages/api/[...path].js
|
// pages/api/[...path].js
|
||||||
import { createProxyMiddleware } from "http-proxy-middleware";
|
import { createProxyMiddleware } from "http-proxy-middleware";
|
||||||
|
//import { SERVER_URL } from "../config/urls.js";
|
||||||
|
//console.log("SERVER_URL:", SERVER_URL); // Debug-Ausgabe
|
||||||
|
|
||||||
export default createProxyMiddleware({
|
export default createProxyMiddleware({
|
||||||
//target: "http://192.168.10.58:3001",
|
//target: "http://192.168.10.58:3001",
|
||||||
// Stationen bekommen
|
// Stationen bekommen
|
||||||
target: "http://10.10.0.13", // Ziel-URL des Proxys // API Aufruf zum mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl und mapDataIconUrl
|
//target: "http://10.10.0.13", // Ziel-URL des Proxys // API Aufruf zum mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl und mapDataIconUrl
|
||||||
|
target: `${process.env.NEXT_PUBLIC_SERVER_URL}`, //
|
||||||
|
//target: urls.PROXY_TARGET,
|
||||||
//target: "http://localhost:3000", // Ziel-URL des Proxys
|
//target: "http://localhost:3000", // Ziel-URL des Proxys
|
||||||
//target: "http://192.168.10.187:3000", // Ziel-URL des Proxys
|
//target: "http://192.168.10.187:3000", // Ziel-URL des Proxys
|
||||||
//target: "http://192.168.10.14",
|
//target: "http://192.168.10.14",
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user