feat(member-live): sort the composite Member column by first or last name
This commit is contained in:
parent
ca2aaa069c
commit
f7005f395f
11 changed files with 443 additions and 34 deletions
|
|
@ -172,7 +172,7 @@ defmodule MvWeb.MemberLive.Index do
|
|||
socket
|
||||
|> Layouts.assign_page_title(gettext("Members"))
|
||||
|> assign(:query, "")
|
||||
|> assign_new(:sort_field, fn -> :first_name end)
|
||||
|> assign_new(:sort_field, fn -> :last_name end)
|
||||
|> assign_new(:sort_order, fn -> :asc end)
|
||||
|> assign(:cycle_status_filter, nil)
|
||||
|> assign(:group_filters, %{})
|
||||
|
|
@ -379,6 +379,22 @@ defmodule MvWeb.MemberLive.Index do
|
|||
end
|
||||
|
||||
{new_field, new_order} = determine_new_sort(field, socket)
|
||||
{:noreply, apply_sort_change(socket, new_field, new_order)}
|
||||
end
|
||||
|
||||
# The composite "Member" column's sub-field menu (first name / last name) always
|
||||
# sorts ascending by the chosen field: it switches the sort key rather than
|
||||
# toggling direction (a click on the header itself toggles direction).
|
||||
def handle_event("sort_composite", %{"field" => field_str}, socket) do
|
||||
field = String.to_existing_atom(field_str)
|
||||
{:noreply, apply_sort_change(socket, field, :asc)}
|
||||
end
|
||||
|
||||
# Applies a resolved (field, order) sort: updates assigns and the sort-header
|
||||
# components, reloads the keyset stream from page 1, scrolls to top, and syncs
|
||||
# the URL. Shared by the header-click ("sort") and sub-field menu
|
||||
# ("sort_composite") paths.
|
||||
defp apply_sort_change(socket, new_field, new_order) do
|
||||
old_field = socket.assigns.sort_field
|
||||
|
||||
socket =
|
||||
|
|
@ -394,8 +410,8 @@ defmodule MvWeb.MemberLive.Index do
|
|||
query_params =
|
||||
build_query_params(
|
||||
opts_for_query_params(socket, %{
|
||||
sort_field: ExportPayload.sort_field(socket.assigns.sort_field),
|
||||
sort_order: ExportPayload.sort_order(socket.assigns.sort_order)
|
||||
sort_field: ExportPayload.sort_field(new_field),
|
||||
sort_order: ExportPayload.sort_order(new_order)
|
||||
})
|
||||
)
|
||||
|> maybe_add_field_selection(
|
||||
|
|
@ -403,7 +419,7 @@ defmodule MvWeb.MemberLive.Index do
|
|||
socket.assigns[:fields_in_url?] || false
|
||||
)
|
||||
|
||||
{:noreply, push_reload(socket, ~p"/members?#{query_params}")}
|
||||
push_reload(socket, ~p"/members?#{query_params}")
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
|
|
@ -1488,9 +1504,11 @@ defmodule MvWeb.MemberLive.Index do
|
|||
defp determine_field(default, nil), do: default
|
||||
|
||||
# Computed/pseudo fields that are nonetheless sortable (they resolve to DB
|
||||
# sort keys in OverviewQuery): groups aggregate and the composite Name/Address
|
||||
# columns. Other computed fields (e.g. membership_fee_status) are not sortable.
|
||||
@sortable_computed_fields [:groups, :name, :address]
|
||||
# sort keys in OverviewQuery): the groups aggregate and the composite Address
|
||||
# column. The composite Member column sorts by its real first/last-name
|
||||
# sub-fields (chosen via its sub-field menu), so it needs no pseudo token here.
|
||||
# Other computed fields (e.g. membership_fee_status) are not sortable.
|
||||
@sortable_computed_fields [:groups, :address]
|
||||
|
||||
defp determine_field(default, sf) when is_binary(sf) do
|
||||
sortable_strings = Enum.map(@sortable_computed_fields, &Atom.to_string/1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue