feat(overview): replace filter panel with add-filter builder and aging column

Swaps the unbounded vertical filter panel for a Polaris-style add-filter
builder (searchable grouped field picker, type-aware value control, applied
chips) and colour-codes the fees column with each member's period-scoped
unpaid-cycle count.
This commit is contained in:
Simon 2026-07-10 16:27:15 +02:00
parent 7d1a71b1fd
commit c547ca19af
35 changed files with 2817 additions and 3149 deletions

View file

@ -103,13 +103,7 @@ defmodule MvWeb.MemberLive.IndexGroupsIntegrationTest do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
view
|> element("button[aria-label='Filter members']")
|> render_click()
view
|> element("[data-testid='member-filter-form']")
|> render_change(%{"group_#{group1.id}" => "in", "payment_filter" => "all"})
apply_group_filter(view, group1.id, "in")
html = render(view)
assert html =~ member1.first_name
@ -174,10 +168,10 @@ defmodule MvWeb.MemberLive.IndexGroupsIntegrationTest do
conn = conn_with_oidc_user(conn)
{:ok, _view, html} =
live(conn, "/members?group_#{group1.id}=in&cycle_status_filter=paid")
live(conn, "/members?group_#{group1.id}=in&pay_filter=fully_paid")
assert html =~ "Members"
# member1 has a group and a paid cycle; page should load with both filters
# member1 has a group and no unpaid cycles; both filters keep it visible.
assert html =~ member1.first_name
end
@ -191,13 +185,7 @@ defmodule MvWeb.MemberLive.IndexGroupsIntegrationTest do
{:ok, view, _html} = live(conn, "/members")
# Apply group filter
view
|> element("button[aria-label='Filter members']")
|> render_click()
view
|> element("[data-testid='member-filter-form']")
|> render_change(%{"group_#{group1.id}" => "in", "payment_filter" => "all"})
apply_group_filter(view, group1.id, "in")
# Apply search (this tests that filter and search work together;
# search form is in SearchBarComponent with phx-submit="search")
@ -242,13 +230,7 @@ defmodule MvWeb.MemberLive.IndexGroupsIntegrationTest do
{:ok, view, _html} = live(conn, "/members")
# Apply group filter
view
|> element("button[aria-label='Filter members']")
|> render_click()
view
|> element("[data-testid='member-filter-form']")
|> render_change(%{"group_#{group1.id}" => "in", "payment_filter" => "all"})
apply_group_filter(view, group1.id, "in")
# Apply sorting
view