From eb86b8407e8069d720ad89164c47ab33173ebcb8 Mon Sep 17 00:00:00 2001 From: nocnico Date: Thu, 22 May 2025 16:31:24 +0200 Subject: [PATCH] Fix Marker Cluster & MissionContent --- .../map/_components/MarkerCluster.tsx | 97 +++----- .../map/_components/MissionMarkerTabs.tsx | 213 ++++++++++-------- 2 files changed, 143 insertions(+), 167 deletions(-) diff --git a/apps/dispatch/app/_components/map/_components/MarkerCluster.tsx b/apps/dispatch/app/_components/map/_components/MarkerCluster.tsx index 8b016c30..6ec6470e 100644 --- a/apps/dispatch/app/_components/map/_components/MarkerCluster.tsx +++ b/apps/dispatch/app/_components/map/_components/MarkerCluster.tsx @@ -1,21 +1,10 @@ -import { - ConnectedAircraft, - HpgValidationState, - Mission, - Station, -} from "@repo/db"; +import { ConnectedAircraft, HpgValidationState, Mission, Station } from "@repo/db"; import { useQuery } from "@tanstack/react-query"; import { SmartPopup, useSmartPopup } from "_components/SmartPopup"; import { useDispatchConnectionStore } from "_store/dispatch/connectionStore"; import { useMapStore } from "_store/mapStore"; -import { - FMS_STATUS_COLORS, - FMS_STATUS_TEXT_COLORS, -} from "_components/map/AircraftMarker"; -import { - MISSION_STATUS_COLORS, - MISSION_STATUS_TEXT_COLORS, -} from "_components/map/MissionMarkers"; +import { FMS_STATUS_COLORS, FMS_STATUS_TEXT_COLORS } from "_components/map/AircraftMarker"; +import { MISSION_STATUS_COLORS, MISSION_STATUS_TEXT_COLORS } from "_components/map/MissionMarkers"; import { cn } from "helpers/cn"; import { checkSimulatorConnected } from "helpers/simulatorConnected"; import { getConnectedAircraftsAPI } from "querys/aircrafts"; @@ -31,9 +20,7 @@ const PopupContent = ({ missions: Mission[]; }) => { const { anchor } = useSmartPopup(); - const { setOpenAircraftMarker, setOpenMissionMarker } = useMapStore( - (state) => state, - ); + const { setOpenAircraftMarker, setOpenMissionMarker } = useMapStore((state) => state); const map = useMap(); let borderColor = ""; @@ -46,9 +33,7 @@ const PopupContent = ({ } } else if (anchor.includes("bottom")) { if (aircrafts.length > 0) { - borderColor = - FMS_STATUS_TEXT_COLORS[aircrafts[aircrafts.length - 1]!.fmsStatus] || - "white"; + borderColor = FMS_STATUS_TEXT_COLORS[aircrafts[aircrafts.length - 1]!.fmsStatus] || "white"; } else if (missions.length > 0) { borderColor = MISSION_STATUS_TEXT_COLORS[missions[0]!.state]; } @@ -64,16 +49,10 @@ const PopupContent = ({ anchor.includes("top") ? "-top-[2px]" : "-bottom-[2px]", )} style={{ - borderLeft: anchor.includes("left") - ? `3px solid ${borderColor}` - : "", - borderRight: anchor.includes("right") - ? `3px solid ${borderColor}` - : "", + borderLeft: anchor.includes("left") ? `3px solid ${borderColor}` : "", + borderRight: anchor.includes("right") ? `3px solid ${borderColor}` : "", borderTop: anchor.includes("top") ? `3px solid ${borderColor}` : "", - borderBottom: anchor.includes("bottom") - ? `3px solid ${borderColor}` - : "", + borderBottom: anchor.includes("bottom") ? `3px solid ${borderColor}` : "", }} /> {missions.map((mission) => { @@ -89,9 +68,7 @@ const PopupContent = ({ return (
{ queryFn: getConnectedAircraftsAPI, }); - const dispatcherConnected = - useDispatchConnectionStore((s) => s.status) === "connected"; + const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected"; const { data: missions = [] } = useQuery({ queryKey: ["missions"], queryFn: () => @@ -183,20 +159,25 @@ export const MarkerCluster = () => { return missions; }, [missions, dispatcherConnected]); - const [cluster, setCluster] = useState< - { + // Track zoom level in state + const [zoom, setZoom] = useState(() => map.getZoom()); + + useEffect(() => { + const handleZoom = () => setZoom(map.getZoom()); + map.on("zoomend", handleZoom); + return () => { + map.off("zoomend", handleZoom); + }; + }, [map]); + + const clusters = useMemo(() => { + if (zoom >= 8) return []; + let newCluster: { aircrafts: (ConnectedAircraft & { Station: Station })[]; missions: Mission[]; lat: number; lng: number; - }[] - >([]); - - // Compute clusters based on zoom and data using useMemo - const clusters = useMemo(() => { - const zoom = map.getZoom(); - if (zoom >= 8) return []; - let newCluster: typeof cluster = []; + }[] = []; aircrafts ?.filter((a) => checkSimulatorConnected(a.lastHeartbeat)) .forEach((aircraft) => { @@ -265,10 +246,8 @@ export const MarkerCluster = () => { const missionPos = c.missions.map((m) => [m.addressLat, m.addressLng]); const allPos = [...aircraftPos, ...missionPos]; - const avgLat = - allPos.reduce((sum, pos) => sum + pos[0]!, 0) / allPos.length; - const avgLng = - allPos.reduce((sum, pos) => sum + pos[1]!, 0) / allPos.length; + const avgLat = allPos.reduce((sum, pos) => sum + pos[0]!, 0) / allPos.length; + const avgLng = allPos.reduce((sum, pos) => sum + pos[1]!, 0) / allPos.length; return { ...c, @@ -278,29 +257,11 @@ export const MarkerCluster = () => { }); return clusterWithAvgPos; - }, [aircrafts, filteredMissions, map]); - - // Update clusters on zoom change - useEffect(() => { - const handleZoom = () => { - const zoom = map.getZoom(); - if (zoom >= 8) { - setCluster([]); - } else { - setCluster(clusters); - } - }; - map.on("zoomend", handleZoom); - // Set initial clusters - handleZoom(); - return () => { - map.off("zoomend", handleZoom); - }; - }, [map, clusters]); + }, [aircrafts, filteredMissions, zoom]); return ( <> - {cluster.map((c, i) => ( + {clusters.map((c, i) => ( )} - {hpgNeedsAttention && ( - - )} + {!ignoreHpg && + hpgNeedsAttention && + mission.hpgValidationState !== HpgValidationState.POSITION_AMANDED && ( + + )} - {mission.hpgValidationState === HpgValidationState.POSITION_AMANDED && ( + {!ignoreHpg && mission.hpgValidationState === HpgValidationState.POSITION_AMANDED && ( -
+ {mission.state !== "draft" && dispatcherConnected && ( +
+
+ +
+
+ )} -
-
- {/* TODO: make it a small multiselect */} - - -
+ {dispatcherConnected && ( +
+
+
+ {/* TODO: make it a small multiselect */} + + +
+
+ )}
); };