feat: POI-Erstellung, -Bearbeitung und -Löschung vollständig überarbeitet

- POI-Tooltip zeigt jetzt den korrekten Gerätenamen aus Redux (gisStationsStaticDistrict)
- Bearbeitungsmodal (PoiUpdateModal) verwendet Redux-Daten (idLD → Gerätelabel) zur Initialisierung
- Fix: Geräte-Dropdown im Modal zeigt nun den ausgewählten POI korrekt an
- Refactor: `handleUpdatePoi()` nutzt `description` statt `name`
- Fehlerbehandlung im Modal verbessert (alert bei leerem Feld, besseres Logging)
- Redux-Thunk `updatePoiThunk` + `updatePoiService` stabilisiert
- Map aktualisiert POIs nach Bearbeitung automatisch

📦 Version erhöht auf 1.1.253
🗓️ 11.06.2025
This commit is contained in:
ISA
2025-06-11 07:41:10 +02:00
parent 8e5dac82b5
commit 0a97c359d8
11 changed files with 76 additions and 56 deletions

View File

@@ -12,7 +12,7 @@ NEXT_PUBLIC_DEBUG_LOG=false
#auf dem Entwicklungsrechner dev läuft auf Port 3000 und auf dem Server prod auf Port 80, aber der WebService ist immer auf PORT 80
NEXT_PUBLIC_API_PORT_MODE=prod
NEXT_PUBLIC_USE_MOCKS=false
# Der Unterordner talas5 gleich hinter der IP-Adresse (oder Servername) muss konfigurierbar sein.

View File

@@ -4,6 +4,31 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
---
## [1.1.253] 2025-06-11
### ✨ Features
- POIs lassen sich jetzt vollständig erstellen, bearbeiten und löschen
- Tooltip zeigt den korrekten Gerätenamen (aus `gisStationsStaticDistrict`)
- Bearbeitungsdialog lädt initial die richtige Gerätezuteilung (Dropdown)
- Redux-Anbindung für `updatePoiService`, `updatePoiThunk`, `handlers.js` konsolidiert
### 🛠 Fixed
- Fehler beim Aktualisieren behoben (idLD und leeres Name-Feld)
- Dropdown im Modal zeigt jetzt korrekt das zum POI zugehörige Gerät
### 🧠 Architektur
- Kein direkter Zugriff mehr auf Name nur `description` und `idLD`
- Fehlerhandling und Zustandskontrolle über Redux (Status, Error)
### 🔧 Version
- 📦 `appVersion.js` auf Version **1.1.253** erhöht
---
## [1.1.240] 2025-06-06
### ✨ UI-Verbesserung

View File

@@ -86,17 +86,16 @@ umgesetzt.
2. **ZIP-Paket vorbereiten (lokal):**
- Verzeichnis `.next/`
- Verzeichnisse `public/`, `node_modules/` falls nich vorhanden sind oder etwas hinzugefügt wurd
(Bilder oder Bibliothek)
- Dateien `.env.production`, `package.json` falls nich vorhanden sind oder etwas hinzugefügt wurd
(Umgebungsvariablen oder Bibliothek)
- optional: `nssm.exe`, `StartNodeApp.bat`, `Start-Dev.ps1` um Windows Dienst zu erstellen falls
noch nicht vorhanden ist Download:
- Verzeichnisse `public/`, `node_modules/` falls nicht vorhanden sind oder etwas hinzugefügt
wurde (Bilder oder Bibliothek)
- Dateien `.env.production`, `package.json` falls nicht vorhanden sind oder etwas hinzugefügt
wurde (Umgebungsvariablen oder Bibliothek)
- `nssm.exe`, `StartNodeApp.bat`, `Start-Dev.ps1` um Windows Dienst zu erstellen falls noch nicht
vorhanden ist Download:
[nssm](https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&web=1&e=Sm1wwt)
3. **Auf Server kopieren nach:** Ein Ordner temp auf dem Desktop erstellen->ZIP-Paket
einfügen->entpacken->Inhalt in folgende Verzeichnis einfügen, weil verhindert Windows Server
direkt kopieren in folgende Verzeichnis
einfügen->entpacken->Inhalt in folgende Verzeichnis einfügen
```
C:\inetpub\wwwroot\talas5\nodeMap\

View File

@@ -48,5 +48,6 @@
optimiert besser als setInterval, zuerst nur für TALAS.web WebServices erstellen, irgendwann soll
die Daten von DB auch mit WebSocket gelöst werden
- [ ] TODO: POI bearbeiten funktioniert es nicht
- [x] TODO: POI bearbeiten funktioniert es nicht
- [ ] TODO: Linien Links noch mit Port 3000
- [ ] TODO: Checkliste für README.md vorbereiten

View File

@@ -8,7 +8,6 @@ import { selectMapLayersState } from "@/redux/slices/mapLayersSlice";
import { selectPoiTypData, selectPoiTypStatus } from "@/redux/slices/database/pois/poiTypSlice";
import { deletePoiThunk } from "@/redux/thunks/database/pois/deletePoiThunk";
import { updatePoiThunk } from "@/redux/thunks/database/pois/updatePoiThunk";
import { selectSelectedPoi } from "@/redux/slices/database/pois/selectedPoiSlice";
import { handleSubmit } from "@/components/pois/poiUpdateModal/utils/handlers";
import { selectCurrentPoi } from "@/redux/slices/database/pois/currentPoiSlice";
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice";
@@ -56,17 +55,6 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
}
}, [dispatch, poiTypStatus]);
/* useEffect(() => {
console.log("devices in PoiUpdateModal:", devices);
if (poi && devices.length > 0) {
const selectedDevice = devices.find(device => Number(device.idLD) === Number(poi.idLD));
console.log("Selected Device:", selectedDevice);
if (selectedDevice) {
setDeviceName({ value: selectedDevice.idLD, label: selectedDevice.name });
}
}
}, [poi, devices]); */
useEffect(() => {
console.log("poiTypData in PoiUpdateModal:", poiTypData);
if (poi && poiTypData.length > 0) {
@@ -80,13 +68,13 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
useEffect(() => {
console.log("availableDevices in PoiUpdateModal:", availableDevices);
if (poiData && availableDevices.length > 0) {
const selectedDevice = availableDevices.find(device => device.idLD === poiData.idLD);
if (poi && availableDevices.length > 0) {
const selectedDevice = availableDevices.find(device => device.IdLD === poi.idLD);
if (selectedDevice) {
setDeviceName({ value: selectedDevice.idLD, label: selectedDevice.LD_Name }); // ✅ auch hier korrigieren
setDeviceName({ value: selectedDevice.IdLD, label: selectedDevice.LD_Name });
}
}
}, [poiData, availableDevices]);
}, [poi, availableDevices]);
const filterDevices = () => {
const activeSystems = Object.keys(mapLayersVisibility).filter(
@@ -106,7 +94,7 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
: [];
const deviceOptions = availableDevices.map(device => ({
value: device.idLD,
value: device.IdLD,
label: device.LD_Name,
}));
@@ -153,7 +141,22 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
/>
</svg>
</button>
<form onSubmit={handleSubmit} className="m-0 p-2 w-full">
<form
onSubmit={event =>
handleSubmit({
event,
dispatch,
poiId,
name,
description,
poiTypeId,
deviceName,
poi,
onClose,
})
}
className="m-0 p-2 w-full"
>
<div className="flex flex-col mb-4">
<label htmlFor="description" className="block mb-2 font-bold text-sm text-gray-700">
Beschreibung:

View File

@@ -1,8 +1,11 @@
// @/components/pois/poiUpdateModal/utils/handlers.js
import { updatePoiThunk } from "@/redux/thunks/database/pois/updatePoiThunk";
import { deletePoiThunk } from "@/redux/thunks/database/pois/deletePoiThunk";
export const handleSubmit = async ({
event,
dispatch,
poiId,
name,
description,
poiTypeId,
deviceName,
@@ -10,16 +13,18 @@ export const handleSubmit = async ({
onClose,
}) => {
event.preventDefault();
try {
await dispatch(
updatePoiThunk({
const payload = {
idPoi: poiId,
name,
name: description, // 💡 <- Das ist die entscheidende Änderung!
description,
idPoiTyp: poiTypeId?.value ?? poi?.idPoiTyp,
idLD: deviceName?.value,
})
).unwrap();
};
console.log("🔍 POI Update Payload:", payload);
try {
await dispatch(updatePoiThunk(payload)).unwrap();
onClose();
window.location.reload();
} catch (error) {

View File

@@ -1,2 +1,2 @@
// /config/appVersion
export const APP_VERSION = "1.1.253";
export const APP_VERSION = "1.1.254";

View File

@@ -1,10 +1,6 @@
// pages/api/[...path].js
import { createProxyMiddleware } from "http-proxy-middleware";
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
const target = mode === "dev" ? "http://localhost:80" : "http://localhost";
export default createProxyMiddleware({
target,
changeOrigin: true,

View File

@@ -115,7 +115,7 @@ app.prepare().then(() => {
// fetchData immer ausführen unabhängig vom Modus
fetchData();
const interval = setInterval(fetchData, 5000);
const interval = setInterval(fetchData, 12000); // 12 Sekunden ,TALAS.web nutzt auch 12 Sekunden
socket.on("disconnect", () => {
clearInterval(interval);
console.log("❌ WebSocket getrennt");

View File

@@ -1,6 +1,5 @@
// /services/database/updatePoiService.js
export const updatePoiService = async (poi) => {
export const updatePoiService = async poi => {
const response = await fetch("/api/talas_v5_DB/pois/updatePoi", {
method: "POST",
headers: {

View File

@@ -227,11 +227,7 @@ export const setupPolylines = (
callback: e => {
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
const baseUrl =
mode === "dev"
? `${window.location.protocol}//${window.location.hostname}:80${basePath}/`
: `${window.location.origin}${basePath}/`;
const baseUrl = `${window.location.protocol}//${window.location.hostname}:80${basePath}/`;
const link = `${baseUrl}devices/cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`;
window.open(link, "_blank");
@@ -291,11 +287,7 @@ export const setupPolylines = (
polyline.setStyle({ weight: 14 });
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
const baseUrl =
mode === "dev"
? `${window.location.protocol}//${window.location.hostname}:80${basePath}/`
: `${window.location.origin}${basePath}/`;
const baseUrl = `${window.location.protocol}//${window.location.hostname}:80${basePath}/`;
const link = `${baseUrl}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`;
});
// error TypeError: Cannot read properties of null (reading 'contextmenu') wenn der Mas auf die Linie bleibt