feat: GisStationsStaticDistrict in Redux-Store integriert

- WebService-Endpoint für GisStationsStaticDistrict angebunden
- Daten beim Start der Anwendung automatisch geladen und in Redux gespeichert
- UI (DataSheet) verwendet die Daten direkt aus dem Redux-Store
- Fehlerhandling und Initialzustand in Redux-Slice verbessert
- Alte lokale Fetch-Logik entfernt, zentrale Datenhaltung über Redux
This commit is contained in:
Ismail Ali
2025-03-07 22:20:21 +01:00
parent c57ae7717a
commit 86d8e4924a
11 changed files with 110 additions and 30 deletions

View File

@@ -20,8 +20,7 @@ function DataSheet() {
const [mapLayersVisibility, setMapLayersVisibility] = useRecoilState(mapLayersState); const [mapLayersVisibility, setMapLayersVisibility] = useRecoilState(mapLayersState);
const [stationListing, setStationListing] = useState([]); const [stationListing, setStationListing] = useState([]);
const [systemListing, setSystemListing] = useState([]); const [systemListing, setSystemListing] = useState([]);
//const GisStationsStaticDistrict = useRecoilValue(gisStationsStaticDistrictState); const GisStationsStaticDistrict = useSelector(selectGisStationsStaticDistrict) || [];
const GisStationsStaticDistrict = useSelector(selectGisStationsStaticDistrict);
const GisSystemStatic = useRecoilValue(gisSystemStaticState); const GisSystemStatic = useRecoilValue(gisSystemStaticState);
const setZoomTrigger = useSetRecoilState(zoomTriggerState); const setZoomTrigger = useSetRecoilState(zoomTriggerState);
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -76,13 +75,15 @@ function DataSheet() {
const allowedSystems = new Set(GisSystemStatic.filter((system) => system.Allow === 1).map((system) => system.IdSystem)); const allowedSystems = new Set(GisSystemStatic.filter((system) => system.Allow === 1).map((system) => system.IdSystem));
const seenNames = new Set(); const seenNames = new Set();
const filteredAreas = GisStationsStaticDistrict.filter((item) => { const filteredAreas = Array.isArray(GisStationsStaticDistrict)
const isUnique = !seenNames.has(item.Area_Name) && allowedSystems.has(item.System); ? GisStationsStaticDistrict.filter((item) => {
if (isUnique) { const isUnique = !seenNames.has(item.Area_Name) && allowedSystems.has(item.System);
seenNames.add(item.Area_Name); if (isUnique) {
} seenNames.add(item.Area_Name);
return isUnique; }
}); return isUnique;
})
: [];
setStationListing( setStationListing(
filteredAreas.map((area, index) => ({ filteredAreas.map((area, index) => ({

View File

@@ -1,4 +1,4 @@
// components/MapComponent.js // components/mainComponent/MapComponent.js
import React, { useEffect, useRef, useState, useCallback } from "react"; import React, { useEffect, useRef, useState, useCallback } from "react";
import L from "leaflet"; import L from "leaflet";
import "leaflet/dist/leaflet.css"; import "leaflet/dist/leaflet.css";
@@ -40,12 +40,11 @@ import { updateLocation } from "../../utils/updateBereichUtil.js";
import { initGeocoderFeature } from "../features/GeocoderFeature.js"; import { initGeocoderFeature } from "../features/GeocoderFeature.js";
//-------------------------------------------- //--------------------------------------------
//import { currentPoiState } from "../redux/slices/currentPoiSlice.js"; //import { currentPoiState } from "../redux/slices/currentPoiSlice.js";
import { selectGisStationsStaticDistrict, setGisStationsStaticDistrict } from "../../redux/slices/webService/gisStationsStaticDistrictSlice.js";
import { mapIdState, userIdState } from "../../redux/slices/urlParameterSlice.js"; import { mapIdState, userIdState } from "../../redux/slices/urlParameterSlice.js";
import { poiLayerVisibleState } from "../../redux/slices/poiLayerVisibleSlice.js"; import { poiLayerVisibleState } from "../../redux/slices/poiLayerVisibleSlice.js";
import { selectedPoiState } from "../../redux/slices/selectedPoiSlice.js"; import { selectedPoiState } from "../../redux/slices/selectedPoiSlice.js";
import { poiReadFromDbTriggerAtom } from "../../redux/slices/poiReadFromDbTriggerSlice.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 { gisSystemStaticState } from "../../redux/slices/webService/gisSystemStaticSlice.js";
import { mapLayersState } from "../../redux/slices/mapLayersSlice.js"; import { mapLayersState } from "../../redux/slices/mapLayersSlice.js";
import { selectedAreaState } from "../../redux/slices/selectedAreaSlice.js"; import { selectedAreaState } from "../../redux/slices/selectedAreaSlice.js";
@@ -70,6 +69,8 @@ import { fetchGisSystemStatic } from "../../services/api/fetchGisSystemStatic.js
import { usePolylineTooltipLayer } from "../../hooks/usePolylineTooltipLayer.js"; import { usePolylineTooltipLayer } from "../../hooks/usePolylineTooltipLayer.js";
import { selectPolylineVisible, setPolylineVisible } from "../../redux/slices/polylineLayerVisibleSlice.js"; import { selectPolylineVisible, setPolylineVisible } from "../../redux/slices/polylineLayerVisibleSlice.js";
import { useInitLocationDevices } from "./hooks/useInitLocationDevices"; import { useInitLocationDevices } from "./hooks/useInitLocationDevices";
import { useInitGisStationsStaticDistrict } from "./hooks/useInitGisStationsStaticDistrict";
import { selectGisStationsStaticDistrict } from "../../redux/slices/webService/gisStationsStaticDistrictSlice";
const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -999,7 +1000,12 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
//---------------------------------------------- //----------------------------------------------
// speichere location devices in redux store // speichere location devices in redux store
useInitLocationDevices(); useInitLocationDevices();
useInitGisStationsStaticDistrict();
//-------------------------------------- //--------------------------------------
useEffect(() => {
console.log("GisStationsStaticDistrict aus Redux:", GisStationsStaticDistrict);
}, [GisStationsStaticDistrict]);
//---------------------------------------
return ( return (
<> <>

View File

@@ -0,0 +1,38 @@
// components/mainComponent/hooks/useAutoRefreshLocationDevices.js
/*
Das ist erstmal nur so da, falls es gebraucht wird
Diese datei ist zum automatischen aktualisieren der LocationDevices gedacht
jeder 20 Sekunden wird die Funktion fetchLocationDevicesFromDB() aufgerufen
Daten werden dann in der Redux State gespeichert
*/
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { fetchLocationDevicesFromDB } from "../../../redux/slices/db/locationDevicesFromDBSlice";
export const useAutoRefreshLocationDevices = (interval = 20000) => {
// alle 20 Sekunden
const dispatch = useDispatch();
useEffect(() => {
const fetchData = () => {
dispatch(fetchLocationDevicesFromDB());
};
fetchData(); // Sofort beim Start holen
const intervalId = setInterval(fetchData, interval);
return () => clearInterval(intervalId); // Cleanup beim Unmount
}, [dispatch, interval]);
};
/*
In MapComponent.js einbinden
import { useAutoRefreshLocationDevices } from "./hooks/useAutoRefreshLocationDevices";
const MapComponent = () => {
useAutoRefreshLocationDevices();
*/

View File

@@ -0,0 +1,12 @@
// /components/mainComponent/hooks/useInitGisStationsStaticDistrict.js
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { fetchGisStationsStaticDistrictFromWebService } from "../../../redux/slices/webService/gisStationsStaticDistrictSlice";
export const useInitGisStationsStaticDistrict = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchGisStationsStaticDistrictFromWebService());
}, [dispatch]);
};

View File

@@ -1,3 +1,4 @@
// /components/mainComponent/hooks/useInitLocationDevices.js
import { useEffect } from "react"; import { useEffect } from "react";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { fetchLocationDevicesFromDB } from "../../../redux/slices/db/locationDevicesFromDBSlice"; import { fetchLocationDevicesFromDB } from "../../../redux/slices/db/locationDevicesFromDBSlice";

View File

@@ -1,2 +1,2 @@
// /config/appVersion // /config/appVersion
export const APP_VERSION = "1.1.23"; export const APP_VERSION = "1.1.24";

View File

@@ -1,4 +1,4 @@
// /redux/api/fromDB/locationDevicesLoader.js // /redux/api/fromDB/fetchLocationDevices.js
export const fetchLocationDevices = async () => { export const fetchLocationDevices = async () => {
const response = await fetch("/api/talas_v5_DB/locationDevice/locationDevices"); const response = await fetch("/api/talas_v5_DB/locationDevice/locationDevices");
if (!response.ok) { if (!response.ok) {

View File

@@ -0,0 +1,10 @@
// /redux/api/fromWebService/fetchGisStationsStaticDistrict.js
import { mapGisStationsStaticDistrictUrl } from "../../../config/config";
export const fetchGisStationsStaticDistrict = async () => {
const response = await fetch(mapGisStationsStaticDistrictUrl);
if (!response.ok) {
throw new Error("GisStationsStaticDistrict konnte nicht geladen werden");
}
return await response.json();
};

View File

@@ -1,6 +1,6 @@
// /redux/slices/db/locationDevicesFromDBSlice.js // /redux/slices/db/locationDevicesFromDBSlice.js
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { fetchLocationDevices } from "../../api/fromDB/locationDevicesLoader"; import { fetchLocationDevices } from "../../api/fromDB/fetchLocationDevices";
export const fetchLocationDevicesFromDB = createAsyncThunk("locationDevicesFromDB/fetchLocationDevicesFromDB", async () => { export const fetchLocationDevicesFromDB = createAsyncThunk("locationDevicesFromDB/fetchLocationDevicesFromDB", async () => {
return fetchLocationDevices(); return fetchLocationDevices();

View File

@@ -1,23 +1,35 @@
// /redux/slices/webService/gisStationsStaticDistrictSlice.js // /redux/slices/webService/gisStationsStaticDistrictSlice.js
import { createSlice } from "@reduxjs/toolkit"; import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { fetchGisStationsStaticDistrict } from "../../api/fromWebService/fetchGisStationsStaticDistrict";
const initialState = []; export const fetchGisStationsStaticDistrictFromWebService = createAsyncThunk("gisStationsStaticDistrict/fetchGisStationsStaticDistrictFromWebService", async () => {
return fetchGisStationsStaticDistrict();
});
const gisStationsStaticDistrictSlice = createSlice({ const gisStationsStaticDistrictSlice = createSlice({
name: "gisStationsStaticDistrict", name: "gisStationsStaticDistrict",
initialState, initialState: {
reducers: { data: [],
setGisStationsStaticDistrict: (state, action) => { status: "idle",
return action.payload; error: null,
}, },
clearGisStationsStaticDistrict: () => { reducers: {},
return []; extraReducers: (builder) => {
}, builder
.addCase(fetchGisStationsStaticDistrictFromWebService.pending, (state) => {
state.status = "loading";
})
.addCase(fetchGisStationsStaticDistrictFromWebService.fulfilled, (state, action) => {
state.status = "succeeded";
state.data = action.payload;
})
.addCase(fetchGisStationsStaticDistrictFromWebService.rejected, (state, action) => {
state.status = "failed";
state.error = action.error.message;
});
}, },
}); });
export const { setGisStationsStaticDistrict, clearGisStationsStaticDistrict } = gisStationsStaticDistrictSlice.actions; export const selectGisStationsStaticDistrict = (state) => state.gisStationsStaticDistrict.data;
export const selectGisStationsStaticDistrict = (state) => state.gisStationsStaticDistrict;
export default gisStationsStaticDistrictSlice.reducer; export default gisStationsStaticDistrictSlice.reducer;

View File

@@ -1,16 +1,16 @@
import { configureStore } from "@reduxjs/toolkit"; import { configureStore } from "@reduxjs/toolkit";
import lineVisibilityReducer from "./slices/lineVisibilitySlice"; import lineVisibilityReducer from "./slices/lineVisibilitySlice";
import currentPoiReducer from "./slices/currentPoiSlice"; import currentPoiReducer from "./slices/currentPoiSlice";
import gisStationsStaticDistrictReducer from "./slices/webService/gisStationsStaticDistrictSlice";
import polylineLayerVisibleReducer from "./slices/polylineLayerVisibleSlice"; import polylineLayerVisibleReducer from "./slices/polylineLayerVisibleSlice";
import locationDevicesFromDBReducer from "./slices/db/locationDevicesFromDBSlice"; import locationDevicesFromDBReducer from "./slices/db/locationDevicesFromDBSlice";
import gisStationsStaticDistrictReducer from "./slices/webService/gisStationsStaticDistrictSlice";
export const store = configureStore({ export const store = configureStore({
reducer: { reducer: {
lineVisibility: lineVisibilityReducer, lineVisibility: lineVisibilityReducer,
currentPoi: currentPoiReducer, currentPoi: currentPoiReducer,
gisStationsStaticDistrict: gisStationsStaticDistrictReducer,
polylineLayerVisible: polylineLayerVisibleReducer, polylineLayerVisible: polylineLayerVisibleReducer,
locationDevicesFromDB: locationDevicesFromDBReducer, locationDevicesFromDB: locationDevicesFromDBReducer,
gisStationsStaticDistrict: gisStationsStaticDistrictReducer,
}, },
}); });