feat(rover-planning): inline per-group delete, drop standalone site list
The 'Rover sites' card no longer renders the long list of every site — each rover-location now appears once as a path-profile group heading, which carries its own delete button next to the n/m progress text. The add-site form stays in place.
This commit is contained in:
parent
c2a23d1840
commit
327b4fc561
2 changed files with 42 additions and 43 deletions
|
|
@ -374,55 +374,17 @@ defmodule MicrowavepropWeb.RoverPlanningLive.Show do
|
||||||
|
|
||||||
<div class="card bg-base-100 border border-base-300 p-4 mb-4">
|
<div class="card bg-base-100 border border-base-300 p-4 mb-4">
|
||||||
<div class="flex items-center justify-between mb-2 gap-2 flex-wrap">
|
<div class="flex items-center justify-between mb-2 gap-2 flex-wrap">
|
||||||
<h3 class="font-semibold">Rover sites</h3>
|
<h3 class="font-semibold">Add rover site</h3>
|
||||||
<span class="text-xs text-base-content/60">
|
<span class="text-xs text-base-content/60">
|
||||||
{length(@rover_sites)} site(s) — paths recompute on add/remove
|
{length(@rover_sites)} site(s) — paths recompute on add/remove
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul :if={@rover_sites != []} class="text-sm space-y-1 mb-3">
|
|
||||||
<%!--
|
|
||||||
`flex` (no `flex-wrap`) + `min-w-0` on the row, plus `shrink-0`
|
|
||||||
on the identifier columns and `truncate flex-1 min-w-0` on the
|
|
||||||
notes cell, keeps the row to a single line: long notes get
|
|
||||||
ellipsised instead of pushing the trash button onto a new line.
|
|
||||||
`title={site.notes}` preserves the full text on hover.
|
|
||||||
--%>
|
|
||||||
<li :for={site <- @rover_sites} class="flex items-center gap-2 min-w-0">
|
|
||||||
<span class="font-mono shrink-0">
|
|
||||||
{Maidenhead.from_latlon(site.lat, site.lon, 10)}
|
|
||||||
</span>
|
|
||||||
<span class="text-base-content/60 font-mono text-xs shrink-0">
|
|
||||||
({Float.round(site.lat, 4)}, {Float.round(site.lon, 4)})
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
:if={site.notes && site.notes != ""}
|
|
||||||
class="text-base-content/60 text-xs truncate min-w-0 flex-1"
|
|
||||||
title={site.notes}
|
|
||||||
>
|
|
||||||
· {site.notes}
|
|
||||||
</span>
|
|
||||||
<button
|
|
||||||
:if={can_delete_site?(assigns, site)}
|
|
||||||
type="button"
|
|
||||||
phx-click="delete_rover_site"
|
|
||||||
phx-value-id={site.id}
|
|
||||||
data-confirm="Remove this rover site? This affects every mission that uses it."
|
|
||||||
class="btn btn-ghost btn-xs text-error ml-auto shrink-0"
|
|
||||||
title="Remove rover site"
|
|
||||||
>
|
|
||||||
<.icon name="hero-trash" class="w-4 h-4" />
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p :if={@rover_sites == []} class="text-sm text-base-content/60 mb-3">
|
|
||||||
No rover sites match this mission's scope yet — add one below.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<%!--
|
<%!--
|
||||||
The add form takes the same flexible input the station inputs use:
|
The add form takes the same flexible input the station inputs use:
|
||||||
callsign, Maidenhead grid, or `lat, lon`. Sign-in required.
|
callsign, Maidenhead grid, or `lat, lon`. Sign-in required.
|
||||||
|
The site list itself is rendered inline as path-profile group
|
||||||
|
headings below — each heading carries its own delete button.
|
||||||
--%>
|
--%>
|
||||||
<form
|
<form
|
||||||
:if={@current_scope && @current_scope.user}
|
:if={@current_scope && @current_scope.user}
|
||||||
|
|
@ -489,8 +451,21 @@ defmodule MicrowavepropWeb.RoverPlanningLive.Show do
|
||||||
· {location.notes}
|
· {location.notes}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs text-base-content/70">
|
<div class="flex items-center gap-2">
|
||||||
{group_progress(group_paths)}
|
<span class="text-xs text-base-content/70">
|
||||||
|
{group_progress(group_paths)}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
:if={location && location.id && can_delete_site?(assigns, location)}
|
||||||
|
type="button"
|
||||||
|
phx-click="delete_rover_site"
|
||||||
|
phx-value-id={location.id}
|
||||||
|
data-confirm="Remove this rover site? This affects every mission that uses it."
|
||||||
|
class="btn btn-ghost btn-xs text-error"
|
||||||
|
title="Remove rover site"
|
||||||
|
>
|
||||||
|
<.icon name="hero-trash" class="w-4 h-4" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -398,6 +398,30 @@ defmodule MicrowavepropWeb.RoverPlanningLiveTest do
|
||||||
assert Repo.aggregate(Location, :count) == 0
|
assert Repo.aggregate(Location, :count) == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "delete button lives inside the path-profile group heading, not above it",
|
||||||
|
%{conn: conn} do
|
||||||
|
user = AccountsFixtures.user_fixture()
|
||||||
|
mission = create_mission(user, "Per-group delete mission")
|
||||||
|
conn = log_in_user(conn, user)
|
||||||
|
|
||||||
|
[site] = Repo.all(Location)
|
||||||
|
|
||||||
|
{:ok, lv, html} = live(conn, ~p"/rover-planning/#{mission.id}")
|
||||||
|
|
||||||
|
# The standalone "Rover sites" list is gone — the heading now reads
|
||||||
|
# "Add rover site" (still the form). Each path-profile group
|
||||||
|
# heading carries its own per-location delete button. Asserting on
|
||||||
|
# the structural ancestor (`[data-rover-group]`) ensures the button
|
||||||
|
# is INSIDE the grouping, not in some legacy list above it.
|
||||||
|
refute html =~ "Rover sites</h3>"
|
||||||
|
assert html =~ "Add rover site</h3>"
|
||||||
|
|
||||||
|
assert has_element?(
|
||||||
|
lv,
|
||||||
|
"[data-rover-group] button[phx-click='delete_rover_site'][phx-value-id='#{site.id}']"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
test "add_rover_site rejects whitespace-only input with a flash error",
|
test "add_rover_site rejects whitespace-only input with a flash error",
|
||||||
%{conn: conn} do
|
%{conn: conn} do
|
||||||
user = AccountsFixtures.user_fixture()
|
user = AccountsFixtures.user_fixture()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue