fix: korrigiere fetchGisLinesStatusService für WebService-Antwort 'Statis'
- ersetzt Zugriff auf json.Lines durch json.Statis - behebt leeren Redux-State bei Linienstatus - Daten aus Webservice fließen jetzt korrekt in gisLinesStatusSlice
This commit is contained in:
20
CHANGELOG.md
20
CHANGELOG.md
@@ -4,6 +4,26 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
|
||||
|
||||
---
|
||||
|
||||
## [1.1.144] – 2025-05-22
|
||||
|
||||
### Fixed
|
||||
|
||||
- ✅ Fehlerhafte Webservice-Antwortstruktur in `fetchGisLinesStatusService.js` korrigiert
|
||||
- Erwartet wurde `json.Lines`, geliefert wurde aber `json.Statis`
|
||||
- Daten landen jetzt korrekt im Redux Slice `gisLinesStatus`
|
||||
|
||||
### Architecture
|
||||
|
||||
- 🔁 Vollständige Redux-Anbindung von Linienstatus über `fetchGisLinesStatusThunk`
|
||||
- 🧠 Daten aus WebService `GisLinesStatus` werden zentral über Redux verwaltet
|
||||
- 💡 Fehlerbehandlung und JSON-Parsing robuster gestaltet
|
||||
|
||||
### Version
|
||||
|
||||
- 📦 Version erhöht auf **1.1.144**
|
||||
|
||||
---
|
||||
|
||||
## [1.1.139] – 2025-05-22
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React, { useState, useEffect, use } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { setPoiMarkers } from "../redux/slices/readPoiMarkersStoreSlice";
|
||||
import { selectGisStationsStaticDistrict } from "../redux/slices/webService/gisStationsStaticDistrictSlice";
|
||||
import { selectGisStationsStaticDistrict } from "../redux/slices/webservice/gisStationsStaticDistrictSlice";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { fetchPoiTypes } from "../redux/slices/database/poiTypesSlice";
|
||||
import { incrementTrigger } from "../redux/slices/poiReadFromDbTriggerSlice";
|
||||
|
||||
@@ -4,8 +4,8 @@ import { setSelectedArea } from "../redux/slices/selectedAreaSlice";
|
||||
import EditModeToggle from "./EditModeToggle";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { selectPolylineVisible, setPolylineVisible } from "../redux/slices/polylineLayerVisibleSlice";
|
||||
import { selectGisSystemStatic } from "../redux/slices/webService/gisSystemStaticSlice";
|
||||
import { selectGisStationsStaticDistrict } from "../redux/slices/webService/gisStationsStaticDistrictSlice";
|
||||
import { selectGisSystemStatic } from "../redux/slices/webservice/gisSystemStaticSlice";
|
||||
import { selectGisStationsStaticDistrict } from "../redux/slices/webservice/gisStationsStaticDistrictSlice";
|
||||
import { selectMapLayersState, setLayerVisibility } from "../redux/slices/mapLayersSlice";
|
||||
import { setVisible } from "../redux/slices/poiLayerVisibleSlice";
|
||||
import { incrementZoomTrigger } from "../redux/slices/zoomTriggerSlice";
|
||||
|
||||
@@ -38,8 +38,8 @@ import CoordinatePopup from "../CoordinatePopup.js";
|
||||
//------------------------Daten aus API--------------------
|
||||
import { fetchPoiDataService } from "../../services/database/fetchPoiDataService.js";
|
||||
import { selectPolylineVisible, setPolylineVisible } from "../../redux/slices/polylineLayerVisibleSlice.js";
|
||||
import { selectGisStationsStaticDistrict } from "../../redux/slices/webService/gisStationsStaticDistrictSlice";
|
||||
import { selectGisSystemStatic, setGisSystemStatic } from "../../redux/slices/webService/gisSystemStaticSlice";
|
||||
import { selectGisStationsStaticDistrict } from "../../redux/slices/webservice/gisStationsStaticDistrictSlice.js";
|
||||
import { selectGisSystemStatic, setGisSystemStatic } from "../../redux/slices/webservice/gisSystemStaticSlice.js";
|
||||
import ShowAddStationPopup from "../AddPOIModal.js";
|
||||
import AddPOIOnPolyline from "../AddPOIOnPolyline";
|
||||
import { enablePolylineEvents, disablePolylineEvents } from "../../utils/polylines/eventHandlers";
|
||||
@@ -62,7 +62,10 @@ import { fetchLocationDevicesThunk } from "../../redux/thunks/database/fetchLoca
|
||||
import { fetchPriorityConfigThunk } from "../../redux/thunks/database/fetchPriorityConfigThunk";
|
||||
import { selectPriorityConfig } from "../../redux/slices/database/priorityConfigSlice";
|
||||
import { fetchGisLinesThunk } from "../../redux/thunks/database/fetchGisLinesThunk";
|
||||
import { fetchGisLinesStatusThunk } from "../../redux/thunks/webservice/fetchGisLinesStatusThunk";
|
||||
import { fetchUserRightsThunk } from "../../redux/thunks/webservice/fetchUserRightsThunk";
|
||||
import { selectGisLines } from "../../redux/slices/database/gisLinesSlice";
|
||||
import { selectGisLinesStatus } from "../../redux/slices/webservice/gisLinesStatusSlice";
|
||||
|
||||
const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
//-------------------------------
|
||||
@@ -90,6 +93,11 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
const linesData = useSelector((state) => state.gisLines.data);
|
||||
const gisLinesStatus = useSelector((state) => state.gisLines.status);
|
||||
|
||||
const { data: gisLinesStatusData, status: statusGisLinesStatus } = useSelector(selectGisLinesStatus);
|
||||
useEffect(() => {
|
||||
console.log("✅ Redux: gisLinesStatusData:", gisLinesStatusData);
|
||||
}, [gisLinesStatusData]);
|
||||
|
||||
//-------------------------------
|
||||
const { deviceName, setDeviceName } = useMapComponentState();
|
||||
const [locationDeviceData, setLocationDeviceData] = useState([]);
|
||||
@@ -228,6 +236,14 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
}
|
||||
}, [gisLinesStatus, dispatch]);
|
||||
//--------------------------------------------------------
|
||||
useEffect(() => {
|
||||
dispatch(fetchGisLinesStatusThunk());
|
||||
}, [dispatch]);
|
||||
//---------------------------------------------------------
|
||||
useEffect(() => {
|
||||
dispatch(fetchUserRightsThunk());
|
||||
}, [dispatch]);
|
||||
//----------------------------------------------------
|
||||
|
||||
useEffect(() => {
|
||||
if (linesData && Array.isArray(linesData)) {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// /config/appVersion
|
||||
export const APP_VERSION = "1.1.143";
|
||||
export const APP_VERSION = "1.1.145";
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
// Datei: /config/config.js
|
||||
import { BASE_URL } from "../config/paths";
|
||||
|
||||
// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte
|
||||
|
||||
const standardSideMenu = true;
|
||||
const fullSideMenu = false;
|
||||
|
||||
// Server-URL aus Umgebungsvariable holen (nur bei echter API benötigt)
|
||||
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
|
||||
|
||||
const serverURL = mode === "dev" ? `${window.location.protocol}//${window.location.hostname}:80` : `${window.location.origin}`;
|
||||
|
||||
if (!serverURL && !isMockMode()) {
|
||||
throw new Error("Die Umgebungsvariable ist nicht gesetzt!");
|
||||
}
|
||||
console.log("%c 1- serverURL in config:", "color: #006400;", serverURL);
|
||||
|
||||
// Initialisieren von Variablen, die später im Browserkontext gesetzt werden
|
||||
let windowHeight, url_string, url, idMap, idUser;
|
||||
let mapGisSystemStaticUrl, mapDataIconUrl, webserviceGisLinesStatusUrl;
|
||||
|
||||
// Prüfen, ob Mock-Modus aktiv ist
|
||||
function isMockMode() {
|
||||
return process.env.NEXT_PUBLIC_USE_MOCK_API === "true";
|
||||
}
|
||||
|
||||
// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte
|
||||
|
||||
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
|
||||
let serverURL = "";
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
serverURL = mode === "dev" ? `${window.location.protocol}//${window.location.hostname}:80` : `${window.location.origin}`;
|
||||
}
|
||||
|
||||
if (typeof window !== "undefined" && !serverURL && !isMockMode()) {
|
||||
throw new Error("Die Umgebungsvariable ist nicht gesetzt!");
|
||||
}
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
console.log("%c 1- serverURL in config:", "color: #006400;", serverURL);
|
||||
}
|
||||
|
||||
// Initialisieren von Variablen, die später im Browserkontext gesetzt werden
|
||||
let windowHeight, url_string, url, idMap, idUser;
|
||||
let webserviceGisLinesStatusUrl;
|
||||
|
||||
// URL-Setup - dynamisch abhängig von Mock oder Echtbetrieb
|
||||
if (typeof window !== "undefined") {
|
||||
windowHeight = window.innerHeight;
|
||||
@@ -39,23 +41,14 @@ if (typeof window !== "undefined") {
|
||||
|
||||
if (isMockMode()) {
|
||||
// Mock-Daten jetzt über API-Endpunkte aus pages/api/mockData/webService/
|
||||
|
||||
mapGisSystemStaticUrl = "/api/mockData/webService/GisSystemStaticMock";
|
||||
mapDataIconUrl = "/api/mockData/webService/GetIconsStaticMock";
|
||||
webserviceGisLinesStatusUrl = "/api/mockData/webService/GisLinesStatusMock";
|
||||
console.log("📡 Mock-Mode aktiv: Daten werden aus /api/mockData/webService geladen.");
|
||||
} else {
|
||||
// Echte URLs zur Webservice-API
|
||||
|
||||
mapGisSystemStaticUrl = `${serverURL}${BASE_URL}/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`;
|
||||
|
||||
mapDataIconUrl = `${serverURL}${BASE_URL}/ClientData/WebserviceMap.asmx/GetIconsStatic`;
|
||||
|
||||
webserviceGisLinesStatusUrl = `${serverURL}${BASE_URL}/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`;
|
||||
|
||||
console.log("🌐 Echt-Mode aktiv: Daten werden von der API geholt.");
|
||||
}
|
||||
}
|
||||
|
||||
// Export der Variablen und URLs
|
||||
export { standardSideMenu, fullSideMenu, serverURL, windowHeight, url_string, url, idMap, idUser, mapGisSystemStaticUrl, mapDataIconUrl, webserviceGisLinesStatusUrl, isMockMode };
|
||||
export { serverURL, windowHeight, url_string, url, idMap, idUser, webserviceGisLinesStatusUrl, isMockMode };
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// /redux/slices/database/gisLinesSlice.js
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import { fetchGisLinesThunk } from "../../thunks/database/fetchGisLinesThunk";
|
||||
|
||||
|
||||
33
redux/slices/webService/gisLinesStatusSlice.js
Normal file
33
redux/slices/webService/gisLinesStatusSlice.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// /redux/slices/webservice/gisLinesStatusSlice.js
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import { fetchGisLinesStatusThunk } from "../../thunks/webservice/fetchGisLinesStatusThunk";
|
||||
|
||||
const initialState = {
|
||||
data: [],
|
||||
status: "idle",
|
||||
error: null,
|
||||
};
|
||||
|
||||
export const gisLinesStatusSlice = createSlice({
|
||||
name: "gisLinesStatus",
|
||||
initialState,
|
||||
reducers: {},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(fetchGisLinesStatusThunk.pending, (state) => {
|
||||
state.status = "loading";
|
||||
})
|
||||
.addCase(fetchGisLinesStatusThunk.fulfilled, (state, action) => {
|
||||
state.status = "succeeded";
|
||||
state.data = action.payload;
|
||||
})
|
||||
.addCase(fetchGisLinesStatusThunk.rejected, (state, action) => {
|
||||
state.status = "failed";
|
||||
state.error = action.payload;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default gisLinesStatusSlice.reducer;
|
||||
|
||||
export const selectGisLinesStatus = (state) => state.gisLinesStatus;
|
||||
34
redux/slices/webService/userRightsSlice.js
Normal file
34
redux/slices/webService/userRightsSlice.js
Normal file
@@ -0,0 +1,34 @@
|
||||
// /redux/slices/webservice/userRightsSlice.js
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import { fetchUserRightsThunk } from "../../thunks/webservice/fetchUserRightsThunk";
|
||||
|
||||
const initialState = {
|
||||
rights: [],
|
||||
status: "idle",
|
||||
error: null,
|
||||
};
|
||||
|
||||
export const userRightsSlice = createSlice({
|
||||
name: "userRights",
|
||||
initialState,
|
||||
reducers: {},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(fetchUserRightsThunk.pending, (state) => {
|
||||
state.status = "loading";
|
||||
})
|
||||
.addCase(fetchUserRightsThunk.fulfilled, (state, action) => {
|
||||
state.status = "succeeded";
|
||||
state.rights = action.payload;
|
||||
})
|
||||
.addCase(fetchUserRightsThunk.rejected, (state, action) => {
|
||||
state.status = "failed";
|
||||
state.error = action.payload;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default userRightsSlice.reducer;
|
||||
|
||||
export const selectUserRights = (state) => state.userRights.rights;
|
||||
export const selectUserRightsStatus = (state) => state.userRights.status;
|
||||
@@ -3,13 +3,6 @@ import { configureStore } from "@reduxjs/toolkit";
|
||||
import lineVisibilityReducer from "./slices/lineVisibilitySlice";
|
||||
import currentPoiReducer from "./slices/currentPoiSlice";
|
||||
import polylineLayerVisibleReducer from "./slices/polylineLayerVisibleSlice";
|
||||
import locationDevicesFromDBReducer from "./slices/database/locationDevicesFromDBSlice";
|
||||
import gisStationsStaticDistrictReducer from "./slices/webService/gisStationsStaticDistrictSlice";
|
||||
import gisStationsStatusDistrictReducer from "./slices/webService/gisStationsStatusDistrictSlice";
|
||||
import gisStationsMeasurementsReducer from "./slices/webService/gisStationsMeasurementsSlice";
|
||||
import gisSystemStaticReducer from "./slices/webService/gisSystemStaticSlice";
|
||||
|
||||
import poiTypesReducer from "./slices/database/poiTypesSlice";
|
||||
import addPoiOnPolylineReducer from "./slices/addPoiOnPolylineSlice";
|
||||
import polylineContextMenuReducer from "./slices/polylineContextMenuSlice";
|
||||
import selectedPoiReducer from "./slices/selectedPoiSlice";
|
||||
@@ -22,8 +15,18 @@ import readPoiMarkersStoreReducer from "./slices/readPoiMarkersStoreSlice";
|
||||
import selectedAreaReducer from "./slices/selectedAreaSlice";
|
||||
import zoomTriggerReducer from "./slices/zoomTriggerSlice";
|
||||
import urlParameterReducer from "./slices/urlParameterSlice";
|
||||
//-----database------------
|
||||
import priorityConfigReducer from "./slices/database/priorityConfigSlice";
|
||||
import gisLinesReducer from "./slices/database/gisLinesSlice";
|
||||
import poiTypesReducer from "./slices/database/poiTypesSlice";
|
||||
import locationDevicesFromDBReducer from "./slices/database/locationDevicesFromDBSlice";
|
||||
//----webservice------------
|
||||
import gisStationsStaticDistrictReducer from "./slices/webservice/gisStationsStaticDistrictSlice";
|
||||
import gisStationsStatusDistrictReducer from "./slices/webservice/gisStationsStatusDistrictSlice";
|
||||
import gisStationsMeasurementsReducer from "./slices/webservice/gisStationsMeasurementsSlice";
|
||||
import gisSystemStaticReducer from "./slices/webservice/gisSystemStaticSlice";
|
||||
import gisLinesStatusReducer from "./slices/webservice/gisLinesStatusSlice";
|
||||
import userRightsReducer from "./slices/webservice/userRightsSlice";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
@@ -50,5 +53,7 @@ export const store = configureStore({
|
||||
urlParameter: urlParameterReducer,
|
||||
priorityConfig: priorityConfigReducer,
|
||||
gisLines: gisLinesReducer,
|
||||
gisLinesStatus: gisLinesStatusReducer,
|
||||
userRights: userRightsReducer,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// /redux/thunks/database/fetchGisLinesThunk.js
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { fetchGisLinesService } from "../../../services/database/fetchGisLinesService";
|
||||
|
||||
|
||||
11
redux/thunks/webservice/fetchGisLinesStatusThunk.js
Normal file
11
redux/thunks/webservice/fetchGisLinesStatusThunk.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// /redux/thunks/webservice/fetchGisLinesStatusThunk.js
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { fetchGisLinesStatusService } from "../../../services/webservice/fetchGisLinesStatusService";
|
||||
|
||||
export const fetchGisLinesStatusThunk = createAsyncThunk("gisLinesStatus/fetch", async (_, thunkAPI) => {
|
||||
try {
|
||||
return await fetchGisLinesStatusService();
|
||||
} catch (error) {
|
||||
return thunkAPI.rejectWithValue(error.message);
|
||||
}
|
||||
});
|
||||
11
redux/thunks/webservice/fetchUserRightsThunk.js
Normal file
11
redux/thunks/webservice/fetchUserRightsThunk.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// /redux/thunks/webservice/fetchUserRightsThunk.js
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { fetchUserRightsService } from "../../../services/webservice/fetchUserRightsService";
|
||||
|
||||
export const fetchUserRightsThunk = createAsyncThunk("userRights/fetch", async (_, thunkAPI) => {
|
||||
try {
|
||||
return await fetchUserRightsService();
|
||||
} catch (error) {
|
||||
return thunkAPI.rejectWithValue(error.message);
|
||||
}
|
||||
});
|
||||
27
services/webservice/fetchGisLinesStatusService.js
Normal file
27
services/webservice/fetchGisLinesStatusService.js
Normal file
@@ -0,0 +1,27 @@
|
||||
// /services/webservice/fetchGisLinesStatusService.js
|
||||
export const fetchGisLinesStatusService = async () => {
|
||||
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
|
||||
const baseUrl = mode === "dev" ? `${window.location.protocol}//${window.location.hostname}:80/talas5/ClientData/WebServiceMap.asmx` : `${window.location.origin}/talas5/ClientData/WebServiceMap.asmx`;
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const idMap = params.get("m");
|
||||
|
||||
const url = `${baseUrl}/GisLinesStatus?idMap=${idMap}`;
|
||||
console.log("📡 fetchGisLinesStatusService URL:", url);
|
||||
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error("Fehler beim Laden der Linienstatusdaten");
|
||||
|
||||
const text = await response.text();
|
||||
|
||||
let json;
|
||||
try {
|
||||
json = JSON.parse(text);
|
||||
} catch (e) {
|
||||
console.error("❌ Fehler beim JSON-Parsing der Antwort:", text);
|
||||
throw new Error("Antwort ist kein gültiges JSON");
|
||||
}
|
||||
|
||||
if (!Array.isArray(json.Statis)) throw new Error("Ungültige Antwortstruktur: Statis fehlt");
|
||||
return json.Statis;
|
||||
};
|
||||
@@ -7,8 +7,8 @@ import { store } from "../../redux/store.js";
|
||||
import { updateLineStatus } from "../../redux/slices/lineVisibilitySlice.js";
|
||||
import { setSelectedDevice, clearSelectedDevice } from "../../redux/slices/selectedDeviceSlice.js";
|
||||
import { addContextMenuToMarker } from "../contextMenuUtils.js";
|
||||
import { selectGisStationsStaticDistrict } from "../../redux/slices/webService/gisStationsStaticDistrictSlice.js";
|
||||
import { selectGisStationsStatusDistrict } from "../../redux/slices/webService/gisStationsStatusDistrictSlice.js";
|
||||
import { selectGisStationsStaticDistrict } from "../../redux/slices/webservice/gisStationsStaticDistrictSlice.js";
|
||||
import { selectGisStationsStatusDistrict } from "../../redux/slices/webservice/gisStationsStatusDistrictSlice.js";
|
||||
|
||||
const determinePriority = (iconPath, priorityConfig) => {
|
||||
for (let priority of priorityConfig) {
|
||||
|
||||
Reference in New Issue
Block a user