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:
parent
7d1a71b1fd
commit
c547ca19af
35 changed files with 2817 additions and 3149 deletions
|
|
@ -47,17 +47,10 @@ defmodule MvWeb.MemberLive.Index.OverviewQuery do
|
|||
)
|
||||
|> apply_date_filters(opts[:date_filters])
|
||||
|> apply_custom_date_filters(opts[:date_filters], opts[:date_custom_fields])
|
||||
|> apply_cycle_status_filter(
|
||||
opts[:cycle_status_filter],
|
||||
opts[:show_current_cycle],
|
||||
today(opts)
|
||||
)
|
||||
|> apply_payment_filter(opts[:payment_filter], payment_period(opts))
|
||||
|> apply_sort(opts[:sort_field], opts[:sort_order], opts[:custom_fields] || [])
|
||||
end
|
||||
|
||||
defp today(opts), do: opts[:today] || Date.utc_today()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Search
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -184,55 +177,6 @@ defmodule MvWeb.MemberLive.Index.OverviewQuery do
|
|||
|
||||
defp apply_one_boolean_filter(query, _uuid, _bool), do: query
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Cycle-status filter (paid/unpaid, current or last-completed cycle)
|
||||
#
|
||||
# Backed by the DB cycle-status aggregates (denormalized `cycle_end`). A member
|
||||
# matches only when its selected-cycle status equals the requested status;
|
||||
# members with no matching cycle (nil aggregate) are excluded — exactly as the
|
||||
# previous in-memory classifier behaved.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
defp apply_cycle_status_filter(query, status, _show_current, _today)
|
||||
when status not in [:paid, :unpaid],
|
||||
do: query
|
||||
|
||||
defp apply_cycle_status_filter(query, status, true = _show_current, today) do
|
||||
# Current cycle: contains today; when several would, the one with the latest
|
||||
# cycle_start wins. Keep members whose winning current cycle has `status`.
|
||||
Ash.Query.filter(
|
||||
query,
|
||||
expr(
|
||||
exists(
|
||||
membership_fee_cycles,
|
||||
cycle_start <= ^today and cycle_end >= ^today and status == ^status and
|
||||
not exists(
|
||||
member.membership_fee_cycles,
|
||||
cycle_start <= ^today and cycle_end >= ^today and
|
||||
cycle_start > parent(cycle_start)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
defp apply_cycle_status_filter(query, status, _show_current, today) do
|
||||
# Last completed cycle: most recent cycle that has ended (cycle_end < today).
|
||||
Ash.Query.filter(
|
||||
query,
|
||||
expr(
|
||||
exists(
|
||||
membership_fee_cycles,
|
||||
cycle_end < ^today and status == ^status and
|
||||
not exists(
|
||||
member.membership_fee_cycles,
|
||||
cycle_end < ^today and cycle_start > parent(cycle_start)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Payment aging filter (period-scoped unpaid-cycle count)
|
||||
#
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue