feat: Die Alarmanzeige ist jetzt als eigene Komponente (AlarmIndicator.js) im Verzeichnis uiWidgets erstellt und in MapComponent.js eingebunden.

Wenn ein Alarm mit AlarmLink vorhanden ist, wird das Alarm-Icon angezeigt und öffnet beim Klick den Link in einem neuen Tab.
This commit is contained in:
ISA
2025-09-17 07:44:49 +02:00
parent f22bb4b232
commit 13ca1cece0
6 changed files with 54 additions and 20 deletions

View File

@@ -23,4 +23,4 @@ NEXT_PUBLIC_USE_MOCKS=true
# z.B. http://10.10.0.13/xyz/index.aspx -> basePath in config.json auf /xyz setzen # z.B. http://10.10.0.13/xyz/index.aspx -> basePath in config.json auf /xyz setzen
# basePath wird jetzt in public/config.json gepflegt # basePath wird jetzt in public/config.json gepflegt
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.1.383 NEXT_PUBLIC_APP_VERSION=1.1.384

View File

@@ -24,4 +24,4 @@ NEXT_PUBLIC_USE_MOCKS=false
# basePath wird jetzt in public/config.json gepflegt # basePath wird jetzt in public/config.json gepflegt
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.1.383 NEXT_PUBLIC_APP_VERSION=1.1.384

View File

@@ -34,6 +34,7 @@ import { useMapComponentState } from "@/components/hooks/useMapComponentState.js
import CoordinatePopup from "@/components/contextmenu/CoordinatePopup.js"; import CoordinatePopup from "@/components/contextmenu/CoordinatePopup.js";
//----------Ui Widgets---------------- //----------Ui Widgets----------------
import MapLayersControlPanel from "@/components/uiWidgets/mapLayersControlPanel/MapLayersControlPanel.js"; import MapLayersControlPanel from "@/components/uiWidgets/mapLayersControlPanel/MapLayersControlPanel.js";
import AlarmIndicator from "@/components/uiWidgets/AlarmIndicator";
import CoordinateInput from "@/components/uiWidgets/CoordinateInput.js"; import CoordinateInput from "@/components/uiWidgets/CoordinateInput.js";
import VersionInfoModal from "@/components/uiWidgets/VersionInfoModal.js"; import VersionInfoModal from "@/components/uiWidgets/VersionInfoModal.js";
import AreaDropdown from "@/components/uiWidgets/AreaDropdown"; import AreaDropdown from "@/components/uiWidgets/AreaDropdown";
@@ -143,12 +144,25 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
selectGisLinesStatusFromWebservice selectGisLinesStatusFromWebservice
); );
// Alarm Status aus GisStationsStatusDistrict // Alarm Status und Link aus GisStationsStatusDistrict
const gisStationsStatusDistrict = useSelector(state => state.gisStationsStatusDistrict.data); const gisStationsStatusDistrict = useSelector(state => state.gisStationsStatusDistrict.data);
// Unterstützt sowohl Array-Shape (Statis[]) als auch Objekt mit Statis-Array // Unterstützt sowohl Array-Shape (Statis[]) als auch Objekt mit Statis-Array
const hasActiveAlarm = Array.isArray(gisStationsStatusDistrict) let hasActiveAlarm = false;
? gisStationsStatusDistrict.some(item => item?.Alarm === 1) let alarmLink = "";
: gisStationsStatusDistrict?.Statis?.some(item => item?.Alarm === 1) || false; let alarmText = "";
if (Array.isArray(gisStationsStatusDistrict)) {
const alarmObj = gisStationsStatusDistrict.find(item => item?.Alarm === 1 && item?.AlarmLink);
hasActiveAlarm = !!alarmObj;
alarmLink = alarmObj?.AlarmLink || "";
alarmText = alarmObj?.Me || "Alarm aktiv";
} else if (gisStationsStatusDistrict?.Statis) {
const alarmObj = gisStationsStatusDistrict.Statis.find(
item => item?.Alarm === 1 && item?.AlarmLink
);
hasActiveAlarm = !!alarmObj;
alarmLink = alarmObj?.AlarmLink || "";
alarmText = alarmObj?.Me || "Alarm aktiv";
}
const poiIconsData = useSelector(selectPoiIconsData); const poiIconsData = useSelector(selectPoiIconsData);
const poiIconsStatus = useSelector(selectPoiIconsStatus); const poiIconsStatus = useSelector(selectPoiIconsStatus);
const poiTypData = useSelector(selectPoiTypData); const poiTypData = useSelector(selectPoiTypData);
@@ -1185,17 +1199,8 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
<div id="map" ref={mapRef} className="z-0" style={{ height: "100vh", width: "100vw" }}></div> <div id="map" ref={mapRef} className="z-0" style={{ height: "100vh", width: "100vw" }}></div>
{/* Top-right controls: layers, info, expand, edit, and base map stack */} {/* Top-right controls: layers, info, expand, edit, and base map stack */}
<div className="absolute top-3 right-3 z-50 pointer-events-auto flex items-center gap-2"> <div className="absolute top-3 right-3 z-50 pointer-events-auto flex items-center gap-2">
{/* Alarm-Icon - nur anzeigen wenn Alarm aktiv */} {/* Alarm-Icon - nur anzeigen wenn Alarm aktiv und Link vorhanden */}
{hasActiveAlarm && ( <AlarmIndicator hasAlarm={hasActiveAlarm} alarmLink={alarmLink} alarmText={alarmText} />
<button
onClick={() => {}}
aria-label="Alarm aktiv"
className="rounded-full bg-white/90 hover:bg-white shadow p-1"
title="Alarm aktiv"
>
<AlarmIcon className="h-8 w-8 animate-pulse text-red-500" />
</button>
)}
{/* Marker-Icon (line-md) */} {/* Marker-Icon (line-md) */}
<button <button
onClick={() => setOverlay(prev => (prev === "area" ? null : "area"))} onClick={() => setOverlay(prev => (prev === "area" ? null : "area"))}

View File

@@ -0,0 +1,29 @@
import React from "react";
import AlarmIcon from "@/components/icons/material-symbols/AlarmIcon";
import Tooltip from "@mui/material/Tooltip";
/**
* AlarmIndicator zeigt ein Alarm-Icon, das bei Klick den AlarmLink in neuem Tab öffnet.
* @param {boolean} hasAlarm - Ob ein Alarm aktiv ist
* @param {string} alarmLink - Link zur Alarm-Detailseite
* @param {string} [alarmText] - Optionaler Tooltip-Text
*/
const AlarmIndicator = ({ hasAlarm, alarmLink, alarmText }) => {
if (!hasAlarm || !alarmLink) return null;
return (
<Tooltip title={alarmText || "Alarm aktiv"}>
<span
style={{ cursor: "pointer", color: "red" }}
onClick={e => {
e.stopPropagation();
window.open(alarmLink, "_blank");
}}
aria-label="Alarm aktiv"
>
<AlarmIcon className="h-8 w-8 animate-pulse text-red-500" />
</span>
</Tooltip>
);
};
export default AlarmIndicator;

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "nodemap", "name": "nodemap",
"version": "1.1.383", "version": "1.1.384",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "nodemap", "name": "nodemap",
"version": "1.1.383", "version": "1.1.384",
"dependencies": { "dependencies": {
"@emotion/react": "^11.13.3", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0", "@emotion/styled": "^11.13.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "nodemap", "name": "nodemap",
"version": "1.1.383", "version": "1.1.384",
"dependencies": { "dependencies": {
"@emotion/react": "^11.13.3", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0", "@emotion/styled": "^11.13.0",