feat: Geräte-Daten aus Redux-Store in POI-Bearbeiten-Modal integriert
- Geräte-Liste wird jetzt direkt aus dem Redux-Store (locationDevicesFromDB) verwendet. - Dropdown-Menü zeigt alle verfügbaren Geräte aus der Datenbank. - Beim Öffnen des Modals wird der vorher zugewiesene Gerätname automatisch ausgewählt (Pre-Selection). - Cleanup und Optimierung: Keine separaten API-Calls mehr im Modal. - Struktur verbessert durch Auslagerung der Lade-Logik in useInitLocationDevices Hook.
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
// pages/api/poiUpdateModal.js
|
||||
//
|
||||
// /components/PoiUpdateModal.js
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { selectedPoiState } from "../redux/slices/selectedPoiSlice";
|
||||
import { currentPoiState } from "../redux/slices/currentPoiSlice";
|
||||
import { fetchLocationDevicesFromDB } from "../redux/slices/db/locationDevicesFromDBSlice";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
const dispatch = useDispatch();
|
||||
const devices = useSelector((state) => state.locationDevicesFromDB.devices);
|
||||
|
||||
const currentPoi = useRecoilValue(currentPoiState);
|
||||
const selectedPoi = useRecoilValue(selectedPoiState);
|
||||
const [poiId, setPoiId] = useState(poiData ? poiData.idPoi : "");
|
||||
@@ -19,6 +23,10 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
|
||||
const [description, setDescription] = useState(poiData ? poiData.description : "");
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchLocationDevicesFromDB());
|
||||
}, [dispatch]);
|
||||
|
||||
// Log the initial POI data
|
||||
useEffect(() => {
|
||||
if (poiData) {
|
||||
@@ -117,28 +125,6 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
fetchPoiTypData();
|
||||
}, [selectedPoi]);
|
||||
|
||||
// Fetch device data um den Gerät Namen in den dropdown menu anzuzeigen also erstmal die Liste der Geräte abrufen
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// const response = await fetch("/api/talas_v5/location_device"); //"/api/talas_v5_DB/locationDevice/location_device"
|
||||
const response = await fetch("/api/talas_v5_DB/locationDevice/locationDevices");
|
||||
const data = await response.json();
|
||||
//console.log("Standort- und Gerätedaten:", data);
|
||||
setLocationDeviceData(data);
|
||||
console.log("Standort- und Gerätedaten poiData:", poiData);
|
||||
if (poiData && poiData.idLD) {
|
||||
const selectedDevice = data.find((device) => device.id === poiData.idLD);
|
||||
setDeviceName(selectedDevice ? selectedDevice.id : data[0].id); // Hier wird die ID als initialer Zustand gesetzt
|
||||
console.log("Selected Device:", selectedDevice);
|
||||
console.log("Selected devciceName:", deviceName);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der Standort- und Gerätedaten:", error);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// Fetch device name basierend auf der Geräte-ID
|
||||
|
||||
|
||||
@@ -4,71 +4,72 @@ import L from "leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
|
||||
import "leaflet-contextmenu";
|
||||
import * as config from "../config/config.js";
|
||||
import * as config from "../../config/config.js";
|
||||
import "leaflet.smooth_marker_bouncing";
|
||||
import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; //sieht deaktiviert aber ist das nicht so und wird benötigt
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import DataSheet from "./DataSheet.js";
|
||||
import DataSheet from "../DataSheet.js";
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||
import AddPoiModalWindow from "./pois/AddPoiModalWindow.js";
|
||||
import AddPoiModalWindow from "../pois/AddPoiModalWindow.js";
|
||||
import { InformationCircleIcon } from "@heroicons/react/20/solid";
|
||||
import PoiUpdateModal from "./pois/PoiUpdateModal.js";
|
||||
import PoiUpdateModal from "../pois/PoiUpdateModal.js";
|
||||
import { ToastContainer, toast } from "react-toastify";
|
||||
import plusRoundIcon from "./PlusRoundIcon.js";
|
||||
import { createAndSetDevices } from "../utils/createAndSetDevices.js";
|
||||
import { restoreMapSettings, checkOverlappingMarkers } from "../utils/mapUtils.js";
|
||||
import { APP_VERSION } from "../config/appVersion";
|
||||
import * as layers from "../config/layers.js";
|
||||
import { initializeMap } from "../utils/initializeMap.js";
|
||||
import addItemsToMapContextMenu from "./useMapContextMenu.js";
|
||||
import useGmaMarkersLayer from "../hooks/layers/useGmaMarkersLayer.js"; // Import the custom hook
|
||||
import useSmsfunkmodemMarkersLayer from "../hooks/layers/useSmsfunkmodemMarkersLayer.js";
|
||||
import useBereicheMarkersLayer from "../hooks/layers/useBereicheMarkersLayer.js";
|
||||
import { setupPolylines } from "../utils/setupPolylines.js";
|
||||
import { setupPOIs } from "../utils/setupPOIs.js";
|
||||
import VersionInfoModal from "./VersionInfoModal.js";
|
||||
import useDrawLines from "../hooks/layers/useDrawLines";
|
||||
import useFetchPoiData from "../hooks/useFetchPoiData";
|
||||
import usePoiTypData from "../hooks/usePoiTypData";
|
||||
import useLayerVisibility from "../hooks/useLayerVisibility";
|
||||
import useLineData from "../hooks/useLineData.js";
|
||||
import plusRoundIcon from "../PlusRoundIcon.js";
|
||||
import { createAndSetDevices } from "../../utils/createAndSetDevices.js";
|
||||
import { restoreMapSettings, checkOverlappingMarkers } from "../../utils/mapUtils.js";
|
||||
import { APP_VERSION } from "../../config/appVersion.js";
|
||||
import * as layers from "../../config/layers.js";
|
||||
import { initializeMap } from "../../utils/initializeMap.js";
|
||||
import addItemsToMapContextMenu from "../useMapContextMenu.js";
|
||||
import useGmaMarkersLayer from "../../hooks/layers/useGmaMarkersLayer.js"; // Import the custom hook
|
||||
import useSmsfunkmodemMarkersLayer from "../../hooks/layers/useSmsfunkmodemMarkersLayer.js";
|
||||
import useBereicheMarkersLayer from "../../hooks/layers/useBereicheMarkersLayer.js";
|
||||
import { setupPolylines } from "../../utils/setupPolylines.js";
|
||||
import { setupPOIs } from "../../utils/setupPOIs.js";
|
||||
import VersionInfoModal from "../VersionInfoModal.js";
|
||||
import useDrawLines from "../../hooks/layers/useDrawLines.js";
|
||||
import useFetchPoiData from "../../hooks/useFetchPoiData.js";
|
||||
import usePoiTypData from "../../hooks/usePoiTypData.js";
|
||||
import useLayerVisibility from "../../hooks/useLayerVisibility.js";
|
||||
import useLineData from "../../hooks/useLineData.js";
|
||||
|
||||
//import { useCreateAndSetDevices } from "../hooks/useCreateAndSetDevices";
|
||||
import { useMapComponentState } from "../hooks/useMapComponentState";
|
||||
import { disablePolylineEvents, enablePolylineEvents } from "../utils/setupPolylines";
|
||||
import { updateLocation } from "../utils/updateBereichUtil";
|
||||
import { initGeocoderFeature } from "../components/features/GeocoderFeature";
|
||||
import { useMapComponentState } from "../../hooks/useMapComponentState.js";
|
||||
import { disablePolylineEvents, enablePolylineEvents } from "../../utils/setupPolylines.js";
|
||||
import { updateLocation } from "../../utils/updateBereichUtil.js";
|
||||
import { initGeocoderFeature } from "../features/GeocoderFeature.js";
|
||||
//--------------------------------------------
|
||||
//import { currentPoiState } from "../redux/slices/currentPoiSlice.js";
|
||||
import { selectGisStationsStaticDistrict, setGisStationsStaticDistrict } from "../redux/slices/webService/gisStationsStaticDistrictSlice";
|
||||
import { mapIdState, userIdState } from "../redux/slices/urlParameterSlice.js";
|
||||
import { poiLayerVisibleState } from "../redux/slices/poiLayerVisibleSlice.js";
|
||||
import { selectedPoiState } from "../redux/slices/selectedPoiSlice.js";
|
||||
import { poiReadFromDbTriggerAtom } from "../redux/slices/poiReadFromDbTriggerSlice";
|
||||
import { gisStationsStaticDistrictState } from "../redux/slices/webService/gisStationsStaticDistrictSlice";
|
||||
import { gisSystemStaticState } from "../redux/slices/webService/gisSystemStaticSlice";
|
||||
import { mapLayersState } from "../redux/slices/mapLayersSlice";
|
||||
import { selectedAreaState } from "../redux/slices/selectedAreaSlice";
|
||||
import { zoomTriggerState } from "../redux/slices/zoomTriggerSlice.js";
|
||||
import { polylineEventsDisabledState } from "../redux/slices/polylineEventsDisabledSlice";
|
||||
import { polylineLayerVisibleState } from "../redux/slices/polylineLayerVisibleSlice";
|
||||
import { selectGisStationsStaticDistrict, setGisStationsStaticDistrict } from "../../redux/slices/webService/gisStationsStaticDistrictSlice.js";
|
||||
import { mapIdState, userIdState } from "../../redux/slices/urlParameterSlice.js";
|
||||
import { poiLayerVisibleState } from "../../redux/slices/poiLayerVisibleSlice.js";
|
||||
import { selectedPoiState } from "../../redux/slices/selectedPoiSlice.js";
|
||||
import { poiReadFromDbTriggerAtom } from "../../redux/slices/poiReadFromDbTriggerSlice.js";
|
||||
import { gisStationsStaticDistrictState } from "../../redux/slices/webService/gisStationsStaticDistrictSlice.js";
|
||||
import { gisSystemStaticState } from "../../redux/slices/webService/gisSystemStaticSlice.js";
|
||||
import { mapLayersState } from "../../redux/slices/mapLayersSlice.js";
|
||||
import { selectedAreaState } from "../../redux/slices/selectedAreaSlice.js";
|
||||
import { zoomTriggerState } from "../../redux/slices/zoomTriggerSlice.js";
|
||||
import { polylineEventsDisabledState } from "../../redux/slices/polylineEventsDisabledSlice.js";
|
||||
import { polylineLayerVisibleState } from "../../redux/slices/polylineLayerVisibleSlice.js";
|
||||
//--------------------------------------------
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { selectCurrentPoi, setCurrentPoi, clearCurrentPoi } from "../redux/slices/currentPoiSlice";
|
||||
import CoordinateInput from "./CoordinateInput";
|
||||
import CoordinateModal from "./CoordinateModal";
|
||||
import CoordinatePopup from "./CoordinatePopup";
|
||||
import { selectCurrentPoi, setCurrentPoi, clearCurrentPoi } from "../../redux/slices/currentPoiSlice.js";
|
||||
import CoordinateInput from "../CoordinateInput.js";
|
||||
import CoordinateModal from "../CoordinateModal.js";
|
||||
import CoordinatePopup from "../CoordinatePopup.js";
|
||||
//------------------------Daten aus API--------------------
|
||||
import { fetchUserRights } from "../services/api/fetchUserRights.js";
|
||||
import { fetchPoiData } from "../services/api/fetchPoiData.js";
|
||||
import { fetchGisStationsStaticDistrict } from "../services/api/fetchGisStationsStaticDistrict.js";
|
||||
import { fetchUserRights } from "../../services/api/fetchUserRights.js";
|
||||
import { fetchPoiData } from "../../services/api/fetchPoiData.js";
|
||||
import { fetchGisStationsStaticDistrict } from "../../services/api/fetchGisStationsStaticDistrict.js";
|
||||
|
||||
import { fetchGisStationsStatusDistrict } from "../services/api/fetchGisStationsStatusDistrict.js";
|
||||
import { fetchGisStationsStatusDistrict } from "../../services/api/fetchGisStationsStatusDistrict.js";
|
||||
|
||||
import { fetchGisStationsMeasurements } from "../services/api/fetchGisStationsMeasurements.js";
|
||||
import { fetchGisSystemStatic } from "../services/api/fetchGisSystemStatic.js";
|
||||
import { usePolylineTooltipLayer } from "../hooks/usePolylineTooltipLayer";
|
||||
import { selectPolylineVisible, setPolylineVisible } from "../redux/slices/polylineLayerVisibleSlice";
|
||||
import { fetchGisStationsMeasurements } from "../../services/api/fetchGisStationsMeasurements.js";
|
||||
import { fetchGisSystemStatic } from "../../services/api/fetchGisSystemStatic.js";
|
||||
import { usePolylineTooltipLayer } from "../../hooks/usePolylineTooltipLayer.js";
|
||||
import { selectPolylineVisible, setPolylineVisible } from "../../redux/slices/polylineLayerVisibleSlice.js";
|
||||
import { useInitLocationDevices } from "./hooks/useInitLocationDevices";
|
||||
|
||||
const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -996,6 +997,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
}, [dispatch]);
|
||||
|
||||
//----------------------------------------------
|
||||
// speichere location devices in redux store
|
||||
useInitLocationDevices();
|
||||
//--------------------------------------
|
||||
|
||||
return (
|
||||
<>
|
||||
11
components/mainComponent/hooks/useInitLocationDevices.js
Normal file
11
components/mainComponent/hooks/useInitLocationDevices.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { useEffect } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { fetchLocationDevicesFromDB } from "../../../redux/slices/db/locationDevicesFromDBSlice";
|
||||
|
||||
export const useInitLocationDevices = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchLocationDevicesFromDB());
|
||||
}, [dispatch]);
|
||||
};
|
||||
@@ -5,10 +5,13 @@ import { useRecoilState } from "recoil";
|
||||
import { selectedPoiState } from "../../redux/slices/selectedPoiSlice";
|
||||
import { currentPoiState } from "../../redux/slices/currentPoiSlice";
|
||||
import { mapLayersState } from "../../redux/slices/mapLayersSlice";
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectCurrentPoi } from "../../redux/slices/currentPoiSlice";
|
||||
import { fetchLocationDevicesFromDB } from "../../redux/slices/db/locationDevicesFromDBSlice";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
|
||||
const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const currentPoi = useSelector(selectCurrentPoi);
|
||||
const selectedPoi = useRecoilState(selectedPoiState);
|
||||
const [mapLayersVisibility] = useRecoilState(mapLayersState);
|
||||
@@ -43,6 +46,12 @@ const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => {
|
||||
Basisgerät: 200,
|
||||
};
|
||||
|
||||
const devices = useSelector((state) => state.locationDevicesFromDB.devices);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchLocationDevicesFromDB());
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (poiData) {
|
||||
setPoiId(poiData.idPoi);
|
||||
@@ -86,23 +95,10 @@ const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => {
|
||||
|
||||
// Fetch location devices and pre-select the current device
|
||||
useEffect(() => {
|
||||
const fetchLocationDevices = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/talas5/location_device");
|
||||
const data = await response.json();
|
||||
setLocationDeviceData(data);
|
||||
filterDevices(data);
|
||||
|
||||
if (poiData && poiData.idLD) {
|
||||
const selectedDevice = data.find((device) => device.idLD === poiData.idLD);
|
||||
setDeviceName(selectedDevice ? { value: selectedDevice.name, label: selectedDevice.name } : null);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der Standort- und Gerätedaten:", error);
|
||||
}
|
||||
};
|
||||
fetchLocationDevices();
|
||||
}, [poiData]);
|
||||
if (devices.length > 0) {
|
||||
filterDevices(devices); // <-- Filter direkt die Redux-Devices
|
||||
}
|
||||
}, [devices]);
|
||||
|
||||
// Funktion zum Filtern der Geräte basierend auf den aktiven Systemen (Layern)
|
||||
const filterDevices = (devices) => {
|
||||
@@ -177,10 +173,18 @@ const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => {
|
||||
}))
|
||||
: []; // Falls kein Array, dann leeres Array zurückgeben
|
||||
|
||||
const deviceOptions = filteredDevices.map((device) => ({
|
||||
value: device.name,
|
||||
label: device.name,
|
||||
const deviceOptions = devices.map((device) => ({
|
||||
value: device.idLD, // idLD ist die eindeutige ID des Geräts
|
||||
label: device.name, // name ist der Anzeigename im Dropdown
|
||||
}));
|
||||
useEffect(() => {
|
||||
if (poiData && devices.length > 0) {
|
||||
const selectedDevice = devices.find((device) => device.idLD === poiData.idLD);
|
||||
if (selectedDevice) {
|
||||
setDeviceName({ value: selectedDevice.idLD, label: selectedDevice.name });
|
||||
}
|
||||
}
|
||||
}, [poiData, devices]);
|
||||
|
||||
// Custom styles for react-select
|
||||
const customStyles = {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// /config/appVersion
|
||||
export const APP_VERSION = "1.1.22";
|
||||
export const APP_VERSION = "1.1.23";
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useRecoilState, useRecoilValue } from "recoil";
|
||||
import { readPoiMarkersStore } from "../redux/slices/readPoiMarkersStoreSlice.js";
|
||||
import { poiReadFromDbTriggerAtom } from "../redux/slices/poiReadFromDbTriggerSlice";
|
||||
|
||||
const MapComponentWithNoSSR = dynamic(() => import("../components/MapComponent"), { ssr: false });
|
||||
const MapComponentWithNoSSR = dynamic(() => import("../components/mainComponent/MapComponent"), { ssr: false });
|
||||
const TestScriptWithNoSSR = dynamic(() => import("../components/TestScript"), { ssr: false });
|
||||
|
||||
export default function Home() {
|
||||
|
||||
8
redux/api/fromDB/locationDevicesLoader.js
Normal file
8
redux/api/fromDB/locationDevicesLoader.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// /redux/api/fromDB/locationDevicesLoader.js
|
||||
export const fetchLocationDevices = async () => {
|
||||
const response = await fetch("/api/talas_v5_DB/locationDevice/locationDevices");
|
||||
if (!response.ok) {
|
||||
throw new Error("Geräteliste konnte nicht geladen werden");
|
||||
}
|
||||
return await response.json();
|
||||
};
|
||||
0
redux/api/fromDB/poiTypLoader.js
Normal file
0
redux/api/fromDB/poiTypLoader.js
Normal file
0
redux/api/fromWebService/userSessionLoader.js
Normal file
0
redux/api/fromWebService/userSessionLoader.js
Normal file
33
redux/slices/db/locationDevicesFromDBSlice.js
Normal file
33
redux/slices/db/locationDevicesFromDBSlice.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// /redux/slices/db/locationDevicesFromDBSlice.js
|
||||
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { fetchLocationDevices } from "../../api/fromDB/locationDevicesLoader";
|
||||
|
||||
export const fetchLocationDevicesFromDB = createAsyncThunk("locationDevicesFromDB/fetchLocationDevicesFromDB", async () => {
|
||||
return fetchLocationDevices();
|
||||
});
|
||||
|
||||
const locationDevicesFromDBSlice = createSlice({
|
||||
name: "locationDevicesFromDB",
|
||||
initialState: {
|
||||
devices: [],
|
||||
status: "idle",
|
||||
error: null,
|
||||
},
|
||||
reducers: {},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(fetchLocationDevicesFromDB.pending, (state) => {
|
||||
state.status = "loading";
|
||||
})
|
||||
.addCase(fetchLocationDevicesFromDB.fulfilled, (state, action) => {
|
||||
state.status = "succeeded";
|
||||
state.devices = action.payload; // <-- Hier landen die Daten
|
||||
})
|
||||
.addCase(fetchLocationDevicesFromDB.rejected, (state, action) => {
|
||||
state.status = "failed";
|
||||
state.error = action.error.message;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default locationDevicesFromDBSlice.reducer;
|
||||
@@ -3,6 +3,7 @@ import lineVisibilityReducer from "./slices/lineVisibilitySlice";
|
||||
import currentPoiReducer from "./slices/currentPoiSlice";
|
||||
import gisStationsStaticDistrictReducer from "./slices/webService/gisStationsStaticDistrictSlice";
|
||||
import polylineLayerVisibleReducer from "./slices/polylineLayerVisibleSlice";
|
||||
import locationDevicesFromDBReducer from "./slices/db/locationDevicesFromDBSlice";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
@@ -10,5 +11,6 @@ export const store = configureStore({
|
||||
currentPoi: currentPoiReducer,
|
||||
gisStationsStaticDistrict: gisStationsStaticDistrictReducer,
|
||||
polylineLayerVisible: polylineLayerVisibleReducer,
|
||||
locationDevicesFromDB: locationDevicesFromDBReducer,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user