feat(weather): ?layer= URL param to deep-link a specific overlay

Adds a `layer` query parameter to `/weather`. Loading
`/weather?layer=temp_700mb` boots straight into that overlay; clicking
a different layer pill push_patches the URL so the active selection is
shareable and survives a refresh. Unknown layer ids fall back to the
default (temperature) instead of crashing.
This commit is contained in:
Graham McIntire 2026-04-25 08:57:39 -05:00
parent 64d4297a88
commit 0e0529cd10
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
2 changed files with 45 additions and 2 deletions

View file

@ -160,6 +160,9 @@ defmodule MicrowavepropWeb.WeatherMapLive do
}
]
@default_layer "temperature"
@valid_layer_ids Enum.map(@layers, & &1.id)
@impl true
def mount(_params, _session, socket) do
_ =
@ -187,7 +190,7 @@ defmodule MicrowavepropWeb.WeatherMapLive do
assign(socket,
page_title: "Weather Map",
layers: @layers,
selected_layer: "temperature",
selected_layer: @default_layer,
initial_data_json: "[]",
valid_time: initial_vt,
valid_times: valid_times,
@ -201,6 +204,16 @@ defmodule MicrowavepropWeb.WeatherMapLive do
)}
end
@impl true
def handle_params(params, _uri, socket) do
selected = pick_layer(params["layer"], socket.assigns[:selected_layer])
{:noreply, assign(socket, :selected_layer, selected)}
end
defp pick_layer(layer, _current) when layer in @valid_layer_ids, do: layer
defp pick_layer(_layer, current) when is_binary(current), do: current
defp pick_layer(_layer, _current), do: @default_layer
defp pick_initial_valid_time([]), do: nil
defp pick_initial_valid_time(valid_times) do
@ -210,7 +223,11 @@ defmodule MicrowavepropWeb.WeatherMapLive do
@impl true
def handle_event("select_layer", %{"layer" => layer_id}, socket) do
{:noreply, assign(socket, :selected_layer, layer_id)}
if layer_id in @valid_layer_ids do
{:noreply, push_patch(socket, to: ~p"/weather?layer=#{layer_id}")}
else
{:noreply, socket}
end
end
def handle_event("toggle_grid", _params, socket) do

View file

@ -163,6 +163,32 @@ defmodule MicrowavepropWeb.WeatherMapLiveTest do
assert html =~ "Minimum refractivity gradient"
assert before =~ "Minimum refractivity gradient"
end
test "updates the URL via push_patch so the active layer is shareable", %{conn: conn} do
{:ok, lv, _html} = live(conn, ~p"/weather")
render_hook(lv, "select_layer", %{"layer" => "pwat"})
assert_patched(lv, ~p"/weather?layer=pwat")
end
end
describe "?layer= URL parameter" do
test "pre-selects the requested layer on initial load", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/weather?layer=pwat")
assert html =~ ~s(data-selected-layer="pwat")
# PWAT description appears in the rendered sidebar (not just the
# JSON-encoded layers attribute), confirming the layer assign was
# actually applied.
assert html =~ "rain fade risk"
end
test "ignores an unknown layer id and falls back to the default", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/weather?layer=bogus_xyz")
assert html =~ ~s(data-selected-layer="temperature")
end
end
describe "toggle_grid + toggle_radar events" do