Skip to content

Commit

Permalink
loa: render tooltip on COPs
Browse files Browse the repository at this point in the history
  • Loading branch information
globin committed Oct 24, 2023
1 parent 1ceeccd commit 35d59ad
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 93 deletions.
10 changes: 8 additions & 2 deletions atciss-frontend/src/components/LoaRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,16 @@ const PositionInformation = ({
: `${sector}${frequency}`
}

export const LoaRow = ({ loa }: { loa: LoaItem }) => {
export const LoaRow = ({
loa,
showCop = true,
}: {
loa: LoaItem
showCop?: boolean
}) => {
return (
<tr>
<td>{loa.cop}</td>
{showCop && <td>{loa.cop}</td>}
<td>
{loa.adep_ades === "ADEP" && <>&#x02197;</>}
{loa.adep_ades === "ADES" && <>&#x02198;</>} {loa.aerodrome}
Expand Down
96 changes: 47 additions & 49 deletions atciss-frontend/src/components/map/AreaLayer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LayerGroup, Polygon, Tooltip } from "react-leaflet"
import { useAppSelector } from "../../app/hooks"
import { selectAreasOnMap, selectLevel } from "../../services/mapSlice"
import { selectLevel } from "../../services/mapSlice"
import { AreaBooking, usePollAreas } from "../../services/areaApi"
import { Box, Text } from "theme-ui"
import { z3 } from "../../app/utils"
Expand All @@ -10,7 +10,6 @@ export const AreaLayer = () => {
const { data: areas } = usePollAreas()

const level = useAppSelector(selectLevel)
const displayAreas = useAppSelector(selectAreasOnMap)

const levelFilter = (a: AreaBooking) =>
(a.lower_limit ?? 0) <= level && level < (a.upper_limit ?? 999)
Expand All @@ -21,54 +20,53 @@ export const AreaLayer = () => {

return (
<LayerGroup>
{displayAreas &&
areas
?.filter(levelFilter)
.filter(isActive)
.map((area) => {
const start = DateTime.fromISO(area.start_datetime).toUTC()
const end = DateTime.fromISO(area.end_datetime).toUTC()
const active = DateTime.utc() >= start
{areas
?.filter(levelFilter)
.filter(isActive)
.map((area) => {
const start = DateTime.fromISO(area.start_datetime).toUTC()
const end = DateTime.fromISO(area.end_datetime).toUTC()
const active = DateTime.utc() >= start

return (
<Polygon
pane="markerPane"
pathOptions={{
color: active ? "#ff0000" : "#ff9900",
weight: 5,
opacity: 1,
fillOpacity: 0.5,
}}
positions={area.polygon}
key={`${area.name}-${area.lower_limit}-${area.upper_limit}`}
>
<Tooltip>
<Box sx={{ fontSize: "1" }}>
<Text variant="label">{area.name}</Text>
</Box>
<Box sx={{ fontSize: "1" }}>
FL{z3(area.lower_limit ?? 0)}-FL
{z3(area.upper_limit ?? 660)}
</Box>
<Box sx={{ fontSize: "1" }}>
<Text
variant="label"
sx={{ color: active ? "#ff0000" : "#ff9900" }}
>
{active
? `Active, deactivates ${end.toRelative()}`
: `Will be active ${start.toRelative()}`}
</Text>{" "}
</Box>
<Box sx={{ fontSize: "1" }}>
{`${start.toFormat("y-MM-dd HH:mm")}-${end.toFormat(
"y-MM-dd HH:mm",
)}`}
</Box>
</Tooltip>
</Polygon>
)
})}
return (
<Polygon
pane="markerPane"
pathOptions={{
color: active ? "#ff0000" : "#ff9900",
weight: 5,
opacity: 1,
fillOpacity: 0.5,
}}
positions={area.polygon}
key={`${area.name}-${area.lower_limit}-${area.upper_limit}`}
>
<Tooltip>
<Box sx={{ fontSize: "1" }}>
<Text variant="label">{area.name}</Text>
</Box>
<Box sx={{ fontSize: "1" }}>
FL{z3(area.lower_limit ?? 0)}-FL
{z3(area.upper_limit ?? 660)}
</Box>
<Box sx={{ fontSize: "1" }}>
<Text
variant="label"
sx={{ color: active ? "#ff0000" : "#ff9900" }}
>
{active
? `Active, deactivates ${end.toRelative()}`
: `Will be active ${start.toRelative()}`}
</Text>{" "}
</Box>
<Box sx={{ fontSize: "1" }}>
{`${start.toFormat("y-MM-dd HH:mm")}-${end.toFormat(
"y-MM-dd HH:mm",
)}`}
</Box>
</Tooltip>
</Polygon>
)
})}
</LayerGroup>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { loaApi, selectLoaCops } from "../../services/loaApi"
import { useAppSelector } from "../../app/hooks"
import { selectOwnedSectors } from "../../services/activePositionSlice"

export const NavaidLayer = () => {
export const LoaNavaidLayer = () => {
const ownedSectors = useAppSelector(selectOwnedSectors)
loaApi.useGetBySectorsQuery(ownedSectors, {
skip: ownedSectors.length == 0,
Expand Down
15 changes: 14 additions & 1 deletion atciss-frontend/src/components/map/MapControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import {
selectAreasOnMap,
selectDFSOnMap,
selectDWDOnMap,
selectLoaOnMap,
selectOpenFlightmapsOnMap,
selectSatelliteOnMap,
selectSectorsOnMap,
setAreas,
setDFS,
setDWD,
setLoa,
setOpenFlightmaps,
setSatellite,
setSectors,
Expand All @@ -29,6 +31,7 @@ export const MapControls = () => {
const satellite = useAppSelector(selectSatelliteOnMap)
const sectors = useAppSelector(selectSectorsOnMap)
const areas = useAppSelector(selectAreasOnMap)
const loa = useAppSelector(selectLoaOnMap)

return (
<>
Expand Down Expand Up @@ -92,7 +95,17 @@ export const MapControls = () => {
Sectors
</Text>
</Box>
{(areas || sectors) && <LevelChoice />}
<Box>
<Text as="label" variant="label">
<input
type="checkbox"
checked={loa}
onChange={(e) => dispatch(setLoa(e.target.checked))}
/>
LOA
</Text>
</Box>
{(areas || sectors || loa) && <LevelChoice />}
{sectors && <SectorControls />}
</>
)
Expand Down
87 changes: 82 additions & 5 deletions atciss-frontend/src/components/map/NavaidMarker.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
/** @jsxImportSource theme-ui */

import L, { LatLngExpression } from "leaflet"
import { Marker } from "react-leaflet"
import { selectLOANavaid } from "../../services/navaidApi"
import { Marker, Tooltip } from "react-leaflet"
import { selectLoaNavaid } from "../../services/navaidApi"
import { useAppSelector } from "../../app/hooks"
import { ReactElement } from "react"
import { createPortal } from "react-dom"
import { Box, Flex, Text } from "theme-ui"
import { LoaRow } from "../LoaRow"
import {
selectEntryLoasByNavaid,
selectExitLoasByNavaid,
} from "../../services/loaApi"

const icons: { [key: string]: ReactElement } = {
rnav: (
Expand Down Expand Up @@ -145,7 +153,13 @@ const icons: { [key: string]: ReactElement } = {
}

export const NavaidMarker = ({ designator }: { designator: string }) => {
const navaid = useAppSelector((store) => selectLOANavaid(store, designator))
const navaid = useAppSelector((store) => selectLoaNavaid(store, designator))
const xloasByNavaid = useAppSelector((store) =>
selectExitLoasByNavaid(store, designator),
)
const nloasByNavaid = useAppSelector((store) =>
selectEntryLoasByNavaid(store, designator),
)

if (!navaid) return <></>

Expand All @@ -162,7 +176,7 @@ export const NavaidMarker = ({ designator }: { designator: string }) => {
>
{icons[navaid.type.toLowerCase()] ?? icons["rnav"]}
</svg>
<div>{navaid.designator}</div>
{navaid.designator}
</>
)

Expand All @@ -178,7 +192,70 @@ export const NavaidMarker = ({ designator }: { designator: string }) => {
return (
<>
{createPortal(icon, element)}
<Marker position={navaid.location as LatLngExpression} icon={divIcon} />
<Marker position={navaid.location as LatLngExpression} icon={divIcon}>
<Tooltip>
<Flex
sx={{ justifyContent: "space-between", alignItems: "baseline" }}
>
<Box>
<Text variant="mapAd">{navaid.designator}</Text>{" "}
{navaid.designator !== navaid.name && `(${navaid.name})`}
</Box>
{(navaid.frequency || navaid.channel) && (
<Box>
{navaid.frequency} {navaid.channel}
</Box>
)}
</Flex>
<table sx={{ width: "100%", fontSize: 2 }}>
<thead>
<tr>
<th>ADEP/ADES</th>
<th>FL</th>
<th>REMARK</th>
<th>FROM</th>
<th>TO</th>
</tr>
</thead>
{!!xloasByNavaid.length && (
<>
<thead>
<tr>
<th>Exit</th>
</tr>
</thead>
<tbody>
{xloasByNavaid.map((loa, idx) => (
<LoaRow
key={`${loa.cop}-${loa.aerodrome}-${loa.adep_ades}-${loa.from_sector}-${loa.to_sector}-${idx}`}
loa={loa}
showCop={false}
/>
))}
</tbody>
</>
)}
{!!nloasByNavaid.length && (
<>
<thead>
<tr>
<th>Entry</th>
</tr>
</thead>
<tbody>
{nloasByNavaid?.map((loa, idx) => (
<LoaRow
key={`${loa.cop}-${loa.aerodrome}-${loa.adep_ades}-${loa.from_sector}-${loa.to_sector}-${idx}`}
loa={loa}
showCop={false}
/>
))}
</tbody>
</>
)}
</table>
</Tooltip>
</Marker>
</>
)
}
7 changes: 3 additions & 4 deletions atciss-frontend/src/components/map/SectorLayer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { LayerGroup } from "react-leaflet"
import { useAppSelector } from "../../app/hooks"
import { selectSectorsOnMap } from "../../services/mapSlice"
import {
sectorApi,
selectAirportICAOs,
Expand All @@ -16,14 +15,14 @@ export const SectorLayer = () => {
sectorApi.useGetQuery()
const sectors = useAppSelector(selectSectorIDs)

const displaySectors = useAppSelector(selectSectorsOnMap)

const airports = useAppSelector(selectAirportICAOs)
usePollAtisByIcaoCodes(airports)

return (
<LayerGroup>
{displaySectors && sectors.map((id) => <Sector key={id} id={id} />)}
{sectors.map((id) => (
<Sector key={id} id={id} />
))}
</LayerGroup>
)
}
18 changes: 18 additions & 0 deletions atciss-frontend/src/services/loaApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,21 @@ export const selectLoaCops = createSelector(
selectRelevantLoas,
(relevantLoas) => [...new Set(relevantLoas.map((loa) => loa.cop))],
)

export const selectExitLoasByNavaid = createCachedSelector(
[
selectRelevantExitLoas,
(_state: RootState, designator: string) => designator,
],
(relevantLoas, designator) =>
relevantLoas.filter((loa) => loa.cop == designator),
)((_state, designator) => designator)

export const selectEntryLoasByNavaid = createCachedSelector(
[
selectRelevantEntryLoas,
(_state: RootState, designator: string) => designator,
],
(relevantLoas, designator) =>
relevantLoas.filter((loa) => loa.cop == designator),
)((_state, designator) => designator)
7 changes: 7 additions & 0 deletions atciss-frontend/src/services/mapSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type MapState = {
satellite: boolean
sectors: boolean
areas: boolean
loa: boolean
}

const mapSlice = createSlice({
Expand All @@ -22,6 +23,7 @@ const mapSlice = createSlice({
satellite: localStorageOrDefault("map.satellite", false),
sectors: localStorageOrDefault("map.sectors", true),
areas: localStorageOrDefault("map.areas", true),
loa: localStorageOrDefault("map.loa", false),
} as MapState,
reducers: {
setLevel(state, { payload: level }: PayloadAction<number>) {
Expand Down Expand Up @@ -57,6 +59,9 @@ const mapSlice = createSlice({
setAreas(state, { payload: active }: PayloadAction<boolean>) {
state.areas = setLocalStorage("map.areas", active)
},
setLoa(state, { payload: active }: PayloadAction<boolean>) {
state.loa = setLocalStorage("map.loa", active)
},
},
})

Expand All @@ -67,6 +72,7 @@ export const selectDWDOnMap = (store: RootState) => store.map.dwd
export const selectSatelliteOnMap = (store: RootState) => store.map.satellite
export const selectSectorsOnMap = (store: RootState) => store.map.sectors
export const selectAreasOnMap = (store: RootState) => store.map.areas
export const selectLoaOnMap = (store: RootState) => store.map.loa

export const {
setLevel,
Expand All @@ -76,5 +82,6 @@ export const {
setSatellite,
setSectors,
setAreas,
setLoa,
} = mapSlice.actions
export const { reducer: mapReducer } = mapSlice
Loading

0 comments on commit 35d59ad

Please sign in to comment.