feat: WebSocket-Integration mit UI-Reaktivierung für GisStationsStaticDistrict
- WebSocket-Trigger implementiert, der `fetchGisStationsStaticDistrictThunk` ausführt. - Trigger-Mechanismus über `useState` (`triggerUpdate`) sorgt für gezielten UI-Re-Render. - Problem gelöst, dass Redux-Store zwar neue Daten enthielt, aber die UI nicht aktualisiert wurde. - MapComponent.js und useDynamicDeviceLayers.js entsprechend angepasst.
This commit is contained in:
@@ -82,11 +82,14 @@ import { cleanupMarkers } from "@/utils/common/cleanupMarkers";
|
||||
import { monitorHeapAndReload } from "@/utils/common/monitorMemory";
|
||||
import { monitorHeapWithRedux } from "@/utils/common/monitorMemory";
|
||||
import { io } from "socket.io-client";
|
||||
|
||||
import { setGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice.js";
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
//-------------------------------
|
||||
const dispatch = useDispatch();
|
||||
// useDataUpdater();
|
||||
const [triggerUpdate, setTriggerUpdate] = useState(false);
|
||||
|
||||
const countdown = useSelector(state => state.polylineContextMenu.countdown);
|
||||
const countdownActive = useSelector(state => state.polylineContextMenu.countdownActive);
|
||||
@@ -818,9 +821,11 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
socket.on("GisStationsMeasurementsUpdated", data => {
|
||||
dispatch(fetchGisStationsMeasurementsThunk(data));
|
||||
});
|
||||
|
||||
socket.on("GisStationsStaticDistrictUpdated", data => {
|
||||
dispatch(fetchGisStationsStaticDistrictThunk(data));
|
||||
socket.on("GisStationsStaticDistrictUpdated", () => {
|
||||
console.log("🛰 WebSocket-Trigger empfangen → Thunk wird erneut ausgeführt");
|
||||
dispatch(fetchGisStationsStaticDistrictThunk());
|
||||
console.log("🛰 WebSocket-Trigger empfangen → Trigger wird gesetzt");
|
||||
setTriggerUpdate(prev => !prev); // Trigger toggeln
|
||||
});
|
||||
|
||||
socket.on("GisStationsStatusDistrictUpdated", data => {
|
||||
@@ -835,7 +840,12 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
socket.disconnect();
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
//--------------------------------------------
|
||||
useEffect(() => {
|
||||
console.log("📦 Neue Daten empfangen:", GisStationsStaticDistrict);
|
||||
}, [GisStationsStaticDistrict]);
|
||||
const { Points = [] } = useSelector(selectGisStationsStaticDistrict);
|
||||
useEffect(() => {}, [triggerUpdate]);
|
||||
//---------------------------------------------
|
||||
//--------------------------------------------
|
||||
return (
|
||||
|
||||
@@ -178,6 +178,19 @@ function MapLayersControlPanel() {
|
||||
console.log("📌 stationListing aktualisiert:", filteredAreas);
|
||||
}
|
||||
}, [GisStationsStaticDistrict, GisSystemStatic]);
|
||||
//---------------------------
|
||||
useEffect(() => {
|
||||
const next = (GisStationsStaticDistrict.Points || []).map(p => p.Area_Name).join("|");
|
||||
const current = stationListing.map(s => s.name).join("|");
|
||||
if (next !== current) {
|
||||
setStationListing(
|
||||
GisStationsStaticDistrict.Points.map((area, index) => ({
|
||||
id: index + 1,
|
||||
name: area.Area_Name,
|
||||
}))
|
||||
);
|
||||
}
|
||||
}, [GisStationsStaticDistrict]);
|
||||
|
||||
//---------------------------
|
||||
return (
|
||||
@@ -194,9 +207,9 @@ function MapLayersControlPanel() {
|
||||
style={{ minWidth: "150px", maxWidth: "200px" }}
|
||||
>
|
||||
<option value="Station wählen">Station wählen</option>
|
||||
{stationListing.map(station => (
|
||||
<option key={station.id} value={station.id}>
|
||||
{station.name}
|
||||
{(GisStationsStaticDistrict.Points || []).map((item, index) => (
|
||||
<option key={index} value={item.IdLD}>
|
||||
{item.Area_Name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// /config/appVersion
|
||||
export const APP_VERSION = "1.1.247";
|
||||
export const APP_VERSION = "1.1.248";
|
||||
|
||||
@@ -12,8 +12,9 @@ import { fetchGisSystemStaticThunk } from "../redux/thunks/webservice/fetchGisSy
|
||||
|
||||
const REFRESH_INTERVAL = parseInt(process.env.NEXT_PUBLIC_REFRESH_INTERVAL || "10000");
|
||||
|
||||
export default function useDataUpdater() {
|
||||
export const useDataUpdater = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
const updateAll = () => {
|
||||
dispatch(fetchGisLinesStatusThunk());
|
||||
@@ -23,9 +24,17 @@ export default function useDataUpdater() {
|
||||
dispatch(fetchGisSystemStaticThunk());
|
||||
};
|
||||
|
||||
updateAll(); // direkt initial einmal laden
|
||||
const interval = setInterval(updateAll, REFRESH_INTERVAL);
|
||||
|
||||
return () => clearInterval(interval); // Cleanup
|
||||
updateAll();
|
||||
const interval = setInterval(updateAll, 10000);
|
||||
return () => clearInterval(interval);
|
||||
}, [dispatch]);
|
||||
}
|
||||
};
|
||||
|
||||
// Das ist eine normale Funktion
|
||||
export const triggerDataUpdate = dispatch => {
|
||||
dispatch(fetchGisLinesStatusThunk());
|
||||
dispatch(fetchGisStationsMeasurementsThunk());
|
||||
dispatch(fetchGisStationsStaticDistrictThunk());
|
||||
dispatch(fetchGisStationsStatusDistrictThunk());
|
||||
dispatch(fetchGisSystemStaticThunk());
|
||||
};
|
||||
|
||||
@@ -4,6 +4,8 @@ import L from "leaflet";
|
||||
import { createAndSetDevices } from "../utils/devices/createAndSetDevices";
|
||||
import { checkOverlappingMarkers } from "../utils/mapUtils";
|
||||
import plusRoundIcon from "@/components/icons/devices/overlapping/PlusRoundIcon";
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice.js";
|
||||
|
||||
/**
|
||||
* Dynamisch GIS-System-Marker erstellen & Sichtbarkeit steuern.
|
||||
@@ -14,6 +16,7 @@ import plusRoundIcon from "@/components/icons/devices/overlapping/PlusRoundIcon"
|
||||
* @returns {{ markerStates, layerRefs }} Alle Marker und Referenzen
|
||||
*/
|
||||
const useDynamicDeviceLayers = (map, GisSystemStatic, mapLayersVisibility, priorityConfig, oms) => {
|
||||
const staticDistrictData = useSelector(selectGisStationsStaticDistrict);
|
||||
const [markerStates, setMarkerStates] = useState({});
|
||||
const layerRefs = useRef({});
|
||||
|
||||
@@ -54,7 +57,7 @@ const useDynamicDeviceLayers = (map, GisSystemStatic, mapLayersVisibility, prior
|
||||
oms
|
||||
);
|
||||
});
|
||||
}, [map, GisSystemStatic, priorityConfig]);
|
||||
}, [map, GisSystemStatic, priorityConfig, staticDistrictData]);
|
||||
|
||||
// Sichtbarkeit nach Redux-Status steuern
|
||||
useEffect(() => {
|
||||
|
||||
@@ -11,10 +11,23 @@ const slice = createSlice({
|
||||
status: "idle",
|
||||
error: null,
|
||||
},
|
||||
reducers: {},
|
||||
extraReducers: (builder) => {
|
||||
reducers: {
|
||||
setGisStationsStaticDistrict: (state, action) => {
|
||||
// Stelle sicher, dass die Struktur immer gleich bleibt
|
||||
if (Array.isArray(action.payload)) {
|
||||
state.data = { Points: action.payload };
|
||||
} else if (action.payload?.Points) {
|
||||
state.data = { Points: action.payload.Points };
|
||||
} else {
|
||||
state.data = { Points: [] };
|
||||
}
|
||||
state.status = "succeeded";
|
||||
state.lastUpdated = Date.now();
|
||||
},
|
||||
}, // Ende der reducers
|
||||
extraReducers: builder => {
|
||||
builder
|
||||
.addCase(fetchGisStationsStaticDistrictThunk.pending, (state) => {
|
||||
.addCase(fetchGisStationsStaticDistrictThunk.pending, state => {
|
||||
state.status = "loading";
|
||||
})
|
||||
.addCase(fetchGisStationsStaticDistrictThunk.fulfilled, (state, action) => {
|
||||
@@ -28,5 +41,6 @@ const slice = createSlice({
|
||||
},
|
||||
});
|
||||
|
||||
export const selectGisStationsStaticDistrict = (state) => state.gisStationsStaticDistrict.data;
|
||||
export const selectGisStationsStaticDistrict = state => state.gisStationsStaticDistrict.data;
|
||||
export default slice.reducer;
|
||||
export const { setGisStationsStaticDistrict } = slice.actions;
|
||||
|
||||
@@ -35,7 +35,6 @@ app.prepare().then(() => {
|
||||
|
||||
io.on("connection", socket => {
|
||||
const { m: idMap, u: idUser, mode } = socket.handshake.query;
|
||||
const isLiveMode = mode === "live";
|
||||
console.log(`🔌 WebSocket verbunden (idMap=${idMap}, idUser=${idUser}, mode=${mode})`);
|
||||
|
||||
const endpoints = [
|
||||
@@ -80,7 +79,7 @@ app.prepare().then(() => {
|
||||
const jsonStr = fs.readFileSync(mockPath, "utf-8");
|
||||
const json = JSON.parse(jsonStr);
|
||||
statis = extractData(json, name);
|
||||
console.log(`🧪 [Mock] ${name}`);
|
||||
//console.log(`🧪 [Mock] ${name}`);
|
||||
} else {
|
||||
const fetchUrl = `http://localhost/talas5/ClientData/${getUrl()}`;
|
||||
const res = await fetch(fetchUrl);
|
||||
@@ -106,7 +105,7 @@ app.prepare().then(() => {
|
||||
console.log(`✅ Änderung bei ${name} erkannt → gesendet`);
|
||||
writeJsonFile(`${name}.json`, statis);
|
||||
} else {
|
||||
console.log(`🔁 ${name}: Keine Änderung`);
|
||||
// console.log(`🔁 ${name}: Keine Änderung`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`❌ Fehler bei ${name}:`, error.message);
|
||||
@@ -114,14 +113,13 @@ app.prepare().then(() => {
|
||||
}
|
||||
};
|
||||
|
||||
if (isLiveMode) {
|
||||
// fetchData immer ausführen – unabhängig vom Modus
|
||||
fetchData();
|
||||
const interval = setInterval(fetchData, 5000);
|
||||
socket.on("disconnect", () => {
|
||||
clearInterval(interval);
|
||||
console.log("❌ WebSocket getrennt");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(PORT, () => {
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
"IdLD": 50922,
|
||||
"Modul": 8,
|
||||
"DpName": "KUE08_Messwertalarm",
|
||||
"ModulName": "Test12",
|
||||
"ModulName": "Test9",
|
||||
"ModulTyp": "Kü705-FO",
|
||||
"Message": "KÜG 08: Überspannung gehend",
|
||||
"Message": "KÜG 08: Überspannung gehend",
|
||||
"Level": 3,
|
||||
"PrioColor": "#FFFF00",
|
||||
"PrioName": "minor",
|
||||
@@ -17,7 +17,7 @@
|
||||
"DpName": "KUE02_Aderbruch",
|
||||
"ModulName": "Kue 2",
|
||||
"ModulTyp": "Kü705-FO",
|
||||
"Message": "KÜG 02: Aderbruch kommend",
|
||||
"Message": "KÜG 02: Aderbruch kommend",
|
||||
"Level": 1,
|
||||
"PrioColor": "#FF0000",
|
||||
"PrioName": "critical",
|
||||
@@ -29,7 +29,7 @@
|
||||
"DpName": "KUE03_Aderbruch",
|
||||
"ModulName": "Kue 3",
|
||||
"ModulTyp": "Kü705-FO",
|
||||
"Message": "KÜG 03: Aderbruch kommend",
|
||||
"Message": "KÜG 03: Aderbruch kommend",
|
||||
"Level": 1,
|
||||
"PrioColor": "#FF0000",
|
||||
"PrioName": "critical",
|
||||
@@ -1227,7 +1227,7 @@
|
||||
"IdLD": 50922,
|
||||
"Modul": 8,
|
||||
"DpName": "KUE08_Messwert",
|
||||
"ModulName": "Test12",
|
||||
"ModulName": "Test8",
|
||||
"ModulTyp": "Kü705-FO",
|
||||
"Message": "?",
|
||||
"Level": -1,
|
||||
@@ -1335,7 +1335,7 @@
|
||||
"IdLD": 50922,
|
||||
"Modul": 8,
|
||||
"DpName": "KUE08_Schleifenwert",
|
||||
"ModulName": "Test12",
|
||||
"ModulName": "Test8",
|
||||
"ModulTyp": "Kü705-FO",
|
||||
"Message": "?",
|
||||
"Level": -1,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"IdL": 24101,
|
||||
"IdDP": 3,
|
||||
"Na": "FBT",
|
||||
"Val": "6",
|
||||
"Val": "7",
|
||||
"Unit": "°C",
|
||||
"Gr": "GMA",
|
||||
"Area_Name": "Rastede"
|
||||
@@ -105,7 +105,7 @@
|
||||
"IdDP": 7,
|
||||
"Na": "WR",
|
||||
"Val": "180",
|
||||
"Unit": "°",
|
||||
"Unit": "°",
|
||||
"Gr": "GMA",
|
||||
"Area_Name": "Rastede"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"LD_Name": "CPL Ismael",
|
||||
"LD_Name": "CPL Ismail31",
|
||||
"IdLD": 50922,
|
||||
"Device": "CPL V3.5 mit 24 Kü",
|
||||
"Link": "cpl.aspx?ver=35&kue=24&id=50922",
|
||||
@@ -10,8 +10,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 20,
|
||||
"System": 1,
|
||||
"Active": 1
|
||||
@@ -27,8 +27,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 12,
|
||||
"System": 5,
|
||||
"Active": 1
|
||||
@@ -44,8 +44,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 21,
|
||||
"System": 6,
|
||||
"Active": 1
|
||||
@@ -61,8 +61,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 1,
|
||||
"System": 11,
|
||||
"Active": 1
|
||||
@@ -78,8 +78,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 12,
|
||||
"System": 111,
|
||||
"Active": 1
|
||||
@@ -95,8 +95,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 20,
|
||||
"System": 1,
|
||||
"Active": 1
|
||||
@@ -112,8 +112,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 9,
|
||||
"System": 7,
|
||||
"Active": 1
|
||||
@@ -129,8 +129,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 21,
|
||||
"System": 6,
|
||||
"Active": 1
|
||||
@@ -146,8 +146,8 @@
|
||||
"Area_Name": "Rastede",
|
||||
"Area_Short": "",
|
||||
"IdArea": 20998,
|
||||
"X": 53.243954,
|
||||
"Y": 8.160439,
|
||||
"X": 53.242157,
|
||||
"Y": 8.160353,
|
||||
"Icon": 21,
|
||||
"System": 6,
|
||||
"Active": 1
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"Na": "minor",
|
||||
"Le": 3,
|
||||
"Co": "#FFFF00",
|
||||
"Me": "KÜG 08: Überspannung gehend",
|
||||
"Me": "KÜG 08: Überspannung gehend",
|
||||
"Feld": 4,
|
||||
"Icon": 0
|
||||
},
|
||||
@@ -85,7 +85,7 @@
|
||||
"Na": "critical",
|
||||
"Le": 1,
|
||||
"Co": "#FF0000",
|
||||
"Me": "KÜG 02: Aderbruch kommend",
|
||||
"Me": "KÜG 02: Aderbruch kommend",
|
||||
"Feld": 4,
|
||||
"Icon": 0
|
||||
},
|
||||
@@ -94,7 +94,7 @@
|
||||
"Na": "critical",
|
||||
"Le": 1,
|
||||
"Co": "#FF0000",
|
||||
"Me": "KÜG 03: Aderbruch kommend",
|
||||
"Me": "KÜG 03: Aderbruch kommend",
|
||||
"Feld": 4,
|
||||
"Icon": 0
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
{
|
||||
"IdSystem": 2,
|
||||
"Name": "ECI",
|
||||
"Longname": "ECI Geräte",
|
||||
"Longname": "ECI Geräte",
|
||||
"Allow": 1,
|
||||
"Icon": 2
|
||||
},
|
||||
{
|
||||
"IdSystem": 3,
|
||||
"Name": "ULAF",
|
||||
"Longname": "ULAF Geräte",
|
||||
"Longname": "ULAF Geräte",
|
||||
"Allow": 0,
|
||||
"Icon": 3
|
||||
},
|
||||
@@ -51,7 +51,7 @@
|
||||
{
|
||||
"IdSystem": 9,
|
||||
"Name": "OTDR",
|
||||
"Longname": "Glasfaserüberwachung OTU",
|
||||
"Longname": "Glasfaserüberwachung OTU",
|
||||
"Allow": 1,
|
||||
"Icon": 9
|
||||
},
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"IdSystem": 11,
|
||||
"Name": "GMA",
|
||||
"Longname": "Glättemeldeanlagen",
|
||||
"Longname": "Glättemeldeanlagen",
|
||||
"Allow": 1,
|
||||
"Icon": 11
|
||||
},
|
||||
@@ -73,7 +73,7 @@
|
||||
"IdSystem": 13,
|
||||
"Name": "Messstellen",
|
||||
"Longname": "Messstellen",
|
||||
"Allow": 0,
|
||||
"Allow": 1,
|
||||
"Icon": 13
|
||||
},
|
||||
{
|
||||
@@ -93,7 +93,7 @@
|
||||
{
|
||||
"IdSystem": 110,
|
||||
"Name": "DAUZ",
|
||||
"Longname": "Dauerzählstellen",
|
||||
"Longname": "Dauerzählstellen",
|
||||
"Allow": 1,
|
||||
"Icon": 110
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user