feat(rover-planning): show callsign + grid (no bare coords) in stationary list
The Stationary-stations summary was rendering whatever the user typed
verbatim ('aa5c 33.1889, -96.4517'). Switch to a pair of helpers that
uppercase the callsign (covering legacy mixed-case rows) and synthesize
a 6-char Maidenhead grid from lat/lon when no grid was stored. Bare
coordinates no longer appear in this list — the grid carries the same
location info in a more amateur-radio-native form.
This commit is contained in:
parent
210e941db8
commit
39c4c287a5
2 changed files with 54 additions and 4 deletions
|
|
@ -253,6 +253,27 @@ defmodule MicrowavepropWeb.RoverPlanningLive.Show do
|
||||||
|
|
||||||
defp station_grid(_), do: nil
|
defp station_grid(_), do: nil
|
||||||
|
|
||||||
|
# Inline label for the "Stationary stations" summary list. Prefers the
|
||||||
|
# callsign (uppercased — legacy data was stored mixed-case), then the
|
||||||
|
# grid, then the input string when neither is set. Bare lat/lon
|
||||||
|
# coordinates are intentionally NOT used as a label here — the grid
|
||||||
|
# half (via `stationary_grid/1`) carries that location info.
|
||||||
|
defp stationary_label(%{callsign: c}) when is_binary(c) and c != "", do: String.upcase(c)
|
||||||
|
defp stationary_label(%{grid: g}) when is_binary(g) and g != "", do: g
|
||||||
|
|
||||||
|
defp stationary_label(%{input: i}) when is_binary(i) and i != "" do
|
||||||
|
if LocationResolver.coordinate_pair?(i), do: nil, else: String.upcase(i)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp stationary_label(_), do: nil
|
||||||
|
|
||||||
|
defp stationary_grid(%{grid: g}) when is_binary(g) and g != "", do: g
|
||||||
|
|
||||||
|
defp stationary_grid(%{lat: lat, lon: lon}) when is_number(lat) and is_number(lon),
|
||||||
|
do: Maidenhead.from_latlon(lat, lon, 6)
|
||||||
|
|
||||||
|
defp stationary_grid(_), do: nil
|
||||||
|
|
||||||
# Endpoint string used for /path?destination=…. Prefers callsign, then
|
# Endpoint string used for /path?destination=…. Prefers callsign, then
|
||||||
# any stored or derived grid (PathLive's LocationResolver re-resolves
|
# any stored or derived grid (PathLive's LocationResolver re-resolves
|
||||||
# both back to the same point), falling back to bare coordinates only
|
# both back to the same point), falling back to bare coordinates only
|
||||||
|
|
@ -331,10 +352,11 @@ defmodule MicrowavepropWeb.RoverPlanningLive.Show do
|
||||||
<h3 class="font-semibold mb-2">Stationary stations</h3>
|
<h3 class="font-semibold mb-2">Stationary stations</h3>
|
||||||
<ul class="text-sm space-y-1">
|
<ul class="text-sm space-y-1">
|
||||||
<li :for={station <- @mission.stations} class="flex flex-wrap gap-2">
|
<li :for={station <- @mission.stations} class="flex flex-wrap gap-2">
|
||||||
<span class="font-mono">{station.callsign || station.grid || station.input}</span>
|
<span :if={stationary_label(station)} class="font-mono">
|
||||||
<span :if={station.grid} class="text-base-content/60">grid {station.grid}</span>
|
{stationary_label(station)}
|
||||||
<span class="text-base-content/60 font-mono">
|
</span>
|
||||||
{Float.round(station.lat, 4)}, {Float.round(station.lon, 4)}
|
<span :if={stationary_grid(station)} class="text-base-content/60 font-mono">
|
||||||
|
{stationary_grid(station)}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,34 @@ defmodule MicrowavepropWeb.RoverPlanningLiveTest do
|
||||||
assert html =~ "Propagation"
|
assert html =~ "Propagation"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "stationary stations list shows uppercase callsign + grid, not bare lat/lon", %{conn: conn} do
|
||||||
|
import Ecto.Query, only: [from: 2]
|
||||||
|
|
||||||
|
user = AccountsFixtures.user_fixture()
|
||||||
|
mission = create_mission(user, "Stationary label mission")
|
||||||
|
|
||||||
|
# Backdate the station to mimic legacy data: callsign persisted in
|
||||||
|
# lowercase, no stored grid. The display should still render the
|
||||||
|
# callsign uppercase and synthesize a grid from lat/lon.
|
||||||
|
mission_id = mission.id
|
||||||
|
|
||||||
|
[s1] =
|
||||||
|
Repo.all(from s in Microwaveprop.RoverPlanning.Station, where: s.mission_id == ^mission_id)
|
||||||
|
|
||||||
|
{:ok, _} =
|
||||||
|
s1
|
||||||
|
|> Ecto.Changeset.change(%{callsign: "aa5c", grid: nil, lat: 33.1889, lon: -96.4517})
|
||||||
|
|> Repo.update()
|
||||||
|
|
||||||
|
{:ok, _lv, html} = live(conn, ~p"/rover-planning/#{mission.id}")
|
||||||
|
|
||||||
|
assert html =~ "AA5C"
|
||||||
|
# Bare lat/lon must not appear in the stationary-stations list.
|
||||||
|
refute html =~ "33.1889, -96.4517"
|
||||||
|
# A grid (derived from lat/lon when none is stored) IS shown.
|
||||||
|
assert html =~ Maidenhead.from_latlon(33.1889, -96.4517, 6)
|
||||||
|
end
|
||||||
|
|
||||||
test "rover-location group heading links to /rover-locations/:id", %{conn: conn} do
|
test "rover-location group heading links to /rover-locations/:id", %{conn: conn} do
|
||||||
user = AccountsFixtures.user_fixture()
|
user = AccountsFixtures.user_fixture()
|
||||||
mission = create_mission(user, "Linked heading mission")
|
mission = create_mission(user, "Linked heading mission")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue