feat(rover): full-bleed layout matching /map and /weather; remove Mode selector
This commit is contained in:
parent
7c506a6453
commit
c13a5f53be
3 changed files with 210 additions and 252 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
defmodule MicrowavepropWeb.RoverLive do
|
defmodule MicrowavepropWeb.RoverLive do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Rover-planning page: enter the fixed stations you want to work, pick a
|
Rover-planning page: enter the fixed stations you want to work, pick a
|
||||||
band/mode/forecast hour, and the map paints a smoothed propagation
|
band and forecast hour, and the map paints a smoothed propagation
|
||||||
quality heatmap with the top 5 ranked drive-to candidates pinned in the
|
quality heatmap with the top 5 ranked drive-to candidates pinned in the
|
||||||
bottom strip.
|
bottom strip.
|
||||||
"""
|
"""
|
||||||
|
|
@ -10,7 +10,6 @@ defmodule MicrowavepropWeb.RoverLive do
|
||||||
|
|
||||||
alias Microwaveprop.Accounts.User
|
alias Microwaveprop.Accounts.User
|
||||||
alias Microwaveprop.Propagation
|
alias Microwaveprop.Propagation
|
||||||
alias Microwaveprop.Propagation.ModeThresholds
|
|
||||||
alias Microwaveprop.Radio.Maidenhead
|
alias Microwaveprop.Radio.Maidenhead
|
||||||
alias Microwaveprop.Repo
|
alias Microwaveprop.Repo
|
||||||
alias Microwaveprop.Rover
|
alias Microwaveprop.Rover
|
||||||
|
|
@ -119,10 +118,6 @@ defmodule MicrowavepropWeb.RoverLive do
|
||||||
{:noreply, assign(socket, band: band)}
|
{:noreply, assign(socket, band: band)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("select_mode", %{"mode" => mode_str}, socket) do
|
|
||||||
{:noreply, assign(socket, mode: parse_mode(mode_str, socket.assigns.mode))}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("set_forecast_hour", %{"value" => v}, socket) do
|
def handle_event("set_forecast_hour", %{"value" => v}, socket) do
|
||||||
hour = v |> parse_int(@default_forecast_hour) |> clamp(0, 18)
|
hour = v |> parse_int(@default_forecast_hour) |> clamp(0, 18)
|
||||||
{:noreply, assign(socket, forecast_hour: hour)}
|
{:noreply, assign(socket, forecast_hour: hour)}
|
||||||
|
|
@ -471,28 +466,12 @@ defmodule MicrowavepropWeb.RoverLive do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp parse_mode(mode_str, fallback) do
|
|
||||||
case mode_str do
|
|
||||||
"ssb" -> :ssb
|
|
||||||
"cw" -> :cw
|
|
||||||
"q65_60a" -> :q65_60a
|
|
||||||
"q65_120b" -> :q65_120b
|
|
||||||
_ -> fallback
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp clamp(v, lo, hi), do: v |> max(lo) |> min(hi)
|
defp clamp(v, lo, hi), do: v |> max(lo) |> min(hi)
|
||||||
|
|
||||||
defp band_label(band) do
|
defp band_label(band) do
|
||||||
Enum.find_value(@bands, "#{band} MHz", fn b -> if b.value == band, do: b.label end)
|
Enum.find_value(@bands, "#{band} MHz", fn b -> if b.value == band, do: b.label end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp mode_label(mode) do
|
|
||||||
Enum.find_value(ModeThresholds.modes(), "#{mode}", fn {atom, label} ->
|
|
||||||
if atom == mode, do: label
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp station_id(%{id: id}), do: to_string(id)
|
defp station_id(%{id: id}), do: to_string(id)
|
||||||
defp station_id(_), do: nil
|
defp station_id(_), do: nil
|
||||||
|
|
||||||
|
|
@ -501,13 +480,12 @@ defmodule MicrowavepropWeb.RoverLive do
|
||||||
@impl true
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_scope={@current_scope} max_width="max-w-full">
|
<div class="flex flex-col w-screen h-screen overflow-hidden">
|
||||||
<div class="flex flex-col h-[calc(100vh-3.5rem)] w-full">
|
|
||||||
<header class="flex items-center justify-between h-11 px-4 bg-base-100 border-b border-base-300 shrink-0">
|
<header class="flex items-center justify-between h-11 px-4 bg-base-100 border-b border-base-300 shrink-0">
|
||||||
<div class="flex flex-col leading-tight">
|
<div class="flex flex-col leading-tight">
|
||||||
<span class="font-semibold text-sm">Rover planning</span>
|
<span class="font-semibold text-sm">Rover planning</span>
|
||||||
<span class="text-xs text-base-content/60">
|
<span class="text-xs text-base-content/60">
|
||||||
{band_label(@band)} · {mode_label(@mode)} · Forecast +{@forecast_hour}h
|
{band_label(@band)} · Forecast +{@forecast_hour}h
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
|
@ -572,18 +550,15 @@ defmodule MicrowavepropWeb.RoverLive do
|
||||||
|
|
||||||
<div class="absolute bottom-[122px] left-4 z-20 bg-base-100/90 rounded-box shadow p-2 text-xs flex flex-col gap-1">
|
<div class="absolute bottom-[122px] left-4 z-20 bg-base-100/90 rounded-box shadow p-2 text-xs flex flex-col gap-1">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="w-3 h-3 rounded-sm" style="background-color: #16a34a; opacity: 0.5">
|
<span class="w-3 h-3 rounded-sm" style="background-color: #16a34a; opacity: 0.5"></span>
|
||||||
</span>
|
|
||||||
<span>Excellent ≥10 dB</span>
|
<span>Excellent ≥10 dB</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="w-3 h-3 rounded-sm" style="background-color: #eab308; opacity: 0.5">
|
<span class="w-3 h-3 rounded-sm" style="background-color: #eab308; opacity: 0.5"></span>
|
||||||
</span>
|
|
||||||
<span>Good 3..10 dB</span>
|
<span>Good 3..10 dB</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="w-3 h-3 rounded-sm" style="background-color: #f97316; opacity: 0.5">
|
<span class="w-3 h-3 rounded-sm" style="background-color: #f97316; opacity: 0.5"></span>
|
||||||
</span>
|
|
||||||
<span>Marginal 0..3 dB</span>
|
<span>Marginal 0..3 dB</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 pt-1 border-t border-base-300/50">
|
<div class="flex items-center gap-2 pt-1 border-t border-base-300/50">
|
||||||
|
|
@ -684,22 +659,6 @@ defmodule MicrowavepropWeb.RoverLive do
|
||||||
</div>
|
</div>
|
||||||
</.sidebar_section>
|
</.sidebar_section>
|
||||||
|
|
||||||
<.sidebar_section title="MODE">
|
|
||||||
<select
|
|
||||||
name="mode"
|
|
||||||
phx-change="select_mode"
|
|
||||||
class="select select-sm select-bordered w-full"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
:for={{atom, label} <- ModeThresholds.modes()}
|
|
||||||
value={Atom.to_string(atom)}
|
|
||||||
selected={atom == @mode}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</.sidebar_section>
|
|
||||||
|
|
||||||
<.sidebar_section title="MAX DRIVE TIME">
|
<.sidebar_section title="MAX DRIVE TIME">
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
|
|
@ -738,7 +697,6 @@ defmodule MicrowavepropWeb.RoverLive do
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layouts.app>
|
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ defmodule Microwaveprop.Rover.ComputeTest do
|
||||||
|
|
||||||
assert is_list(result.cells)
|
assert is_list(result.cells)
|
||||||
assert length(result.top_candidates) <= 5
|
assert length(result.top_candidates) <= 5
|
||||||
assert length(result.top_candidates) > 0
|
refute result.top_candidates == []
|
||||||
|
|
||||||
# Sorted by score desc.
|
# Sorted by score desc.
|
||||||
scores = Enum.map(result.top_candidates, & &1.score)
|
scores = Enum.map(result.top_candidates, & &1.score)
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,15 @@ defmodule MicrowavepropWeb.RoverLiveTest do
|
||||||
assert html =~ "Calculate"
|
assert html =~ "Calculate"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "shows the right-docked sidebar with the six configured sections", %{conn: conn} do
|
test "shows the right-docked sidebar with the configured sections", %{conn: conn} do
|
||||||
{:ok, _view, html} = live(conn, ~p"/rover")
|
{:ok, _view, html} = live(conn, ~p"/rover")
|
||||||
assert html =~ ~s(id="rover-sidebar")
|
assert html =~ ~s(id="rover-sidebar")
|
||||||
assert html =~ "FIXED STATIONS"
|
assert html =~ "FIXED STATIONS"
|
||||||
assert html =~ "FORECAST HOUR"
|
assert html =~ "FORECAST HOUR"
|
||||||
assert html =~ "BAND"
|
assert html =~ "BAND"
|
||||||
assert html =~ "MODE"
|
|
||||||
assert html =~ "MAX DRIVE TIME"
|
assert html =~ "MAX DRIVE TIME"
|
||||||
assert html =~ "MIN ELEV GAIN"
|
assert html =~ "MIN ELEV GAIN"
|
||||||
|
refute html =~ ">MODE<"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "displays the three default NTMS stations", %{conn: conn} do
|
test "displays the three default NTMS stations", %{conn: conn} do
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue