feat(member): let members tailor overview density and visible columns
The View dropdown drives row density and whether the Member and Address fields render as composite cells or split into their underlying columns; the column manager toggles visibility and resets to the curated default. All choices persist per browser through the URL/session/cookie/global chain, so a saved layout survives reloads without a per-account store.
This commit is contained in:
parent
af2cc2e0d4
commit
dfc616257d
21 changed files with 1643 additions and 263 deletions
73
test/mv_web/member_live/index_density_test.exs
Normal file
73
test/mv_web/member_live/index_density_test.exs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
defmodule MvWeb.MemberLive.IndexDensityTest do
|
||||
@moduledoc """
|
||||
§1.4 — The density toggle switches the table row-spacing token and reflects the
|
||||
active density in the control state.
|
||||
§1.5 — Density persists across reload per browser (session/cookie), with the
|
||||
global default applying when nothing is stored.
|
||||
"""
|
||||
use MvWeb.ConnCase, async: false
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
|
||||
alias Mv.Helpers.SystemActor
|
||||
|
||||
setup %{conn: conn} do
|
||||
{:ok, _} =
|
||||
Mv.Membership.create_member(
|
||||
%{first_name: "Dense", last_name: "Row", email: "dense@example.com"},
|
||||
actor: SystemActor.get_system_actor()
|
||||
)
|
||||
|
||||
%{conn: conn_with_oidc_user(conn)}
|
||||
end
|
||||
|
||||
defp open_view_settings(view) do
|
||||
view |> element("[data-testid='view-settings-button']") |> render_click()
|
||||
view
|
||||
end
|
||||
|
||||
test "defaults to compact when nothing is stored", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/members")
|
||||
|
||||
assert has_element?(view, "[data-testid='members-table-scroll'][data-density='compact']")
|
||||
# The compact-mode toggle reflects the active (compact) state.
|
||||
open_view_settings(view)
|
||||
assert has_element?(view, "[data-testid='view-setting-density'][aria-checked='true']")
|
||||
end
|
||||
|
||||
test "toggle switches the density token and the control state", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/members")
|
||||
|
||||
open_view_settings(view)
|
||||
view |> element("[data-testid='view-setting-density']") |> render_click()
|
||||
|
||||
assert has_element?(view, "[data-testid='members-table-scroll'][data-density='comfortable']")
|
||||
assert has_element?(view, "[data-testid='view-setting-density'][aria-checked='false']")
|
||||
|
||||
# Toggling again returns to compact.
|
||||
view |> element("[data-testid='view-setting-density']") |> render_click()
|
||||
assert has_element?(view, "[data-testid='members-table-scroll'][data-density='compact']")
|
||||
end
|
||||
|
||||
test "restores a persisted density from the session on reload", %{conn: conn} do
|
||||
conn =
|
||||
Plug.Test.init_test_session(conn, %{
|
||||
"member_view_settings" => ~s({"density":"comfortable"})
|
||||
})
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/members")
|
||||
|
||||
assert has_element?(view, "[data-testid='members-table-scroll'][data-density='comfortable']")
|
||||
end
|
||||
|
||||
test "restores a persisted density on the connected mount via connect params", %{conn: conn} do
|
||||
# Faithful reload round-trip: the connected mount cannot read the cookie
|
||||
# (the live socket's connect-info map has no cookies), so the client echoes
|
||||
# the persisted value through connect params. This is the path that was
|
||||
# broken in the R1 accept (cookie written but not restored on mount).
|
||||
conn = put_connect_params(conn, %{"view_settings" => ~s({"density":"comfortable"})})
|
||||
{:ok, view, _html} = live(conn, ~p"/members")
|
||||
|
||||
assert has_element?(view, "[data-testid='members-table-scroll'][data-density='comfortable']")
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue