persist sort order
This commit is contained in:
parent
e803dbdf8b
commit
36dcf3fbe1
3 changed files with 114 additions and 17 deletions
|
|
@ -39,6 +39,7 @@ defmodule MvWeb.MemberLive.Index do
|
|||
|
||||
Sets up initial assigns for page title, search query, sort configuration,
|
||||
and member selection. Actual data loading happens in `handle_params/3`.
|
||||
Reads sorting preferences from cookies if available.
|
||||
"""
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
|
|
@ -52,12 +53,15 @@ defmodule MvWeb.MemberLive.Index do
|
|||
|> Ash.Query.sort(name: :asc)
|
||||
|> Ash.read!()
|
||||
|
||||
# Read sorting preferences from cookies (sent via connect_params)
|
||||
{sort_field, sort_order} = get_sort_from_cookies(socket)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:page_title, gettext("Members"))
|
||||
|> assign(:query, "")
|
||||
|> assign_new(:sort_field, fn -> :first_name end)
|
||||
|> assign_new(:sort_order, fn -> :asc end)
|
||||
|> assign_new(:sort_field, fn -> sort_field end)
|
||||
|> assign_new(:sort_order, fn -> sort_order end)
|
||||
|> assign(:selected_members, [])
|
||||
|> assign(:custom_fields_visible, custom_fields_visible)
|
||||
|
||||
|
|
@ -139,9 +143,16 @@ defmodule MvWeb.MemberLive.Index do
|
|||
|
||||
{new_field, new_order} = determine_new_sort(field, socket)
|
||||
|
||||
socket
|
||||
|> update_sort_components(socket.assigns.sort_field, new_field, new_order)
|
||||
|> push_sort_url(new_field, new_order)
|
||||
socket =
|
||||
socket
|
||||
|> update_sort_components(socket.assigns.sort_field, new_field, new_order)
|
||||
# Persist sorting to cookie via JavaScript hook
|
||||
|> push_event("persist_sort", %{
|
||||
sort_field: new_field,
|
||||
sort_order: new_order
|
||||
})
|
||||
|
||||
push_sort_url(socket, new_field, new_order)
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
@ -733,4 +744,56 @@ defmodule MvWeb.MemberLive.Index do
|
|||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# Retrieves sorting preferences from cookies.
|
||||
#
|
||||
# Reads the member_sort_field and member_sort_order from connect_params (sent by JavaScript).
|
||||
# Falls back to default values (:first_name, :asc) if cookies are not present or invalid.
|
||||
#
|
||||
# Parameters:
|
||||
# - `socket` - The LiveView socket containing connect_params
|
||||
#
|
||||
# Returns:
|
||||
# - `{field, order}` tuple where field is an atom or string, and order is :asc or :desc
|
||||
defp get_sort_from_cookies(socket) do
|
||||
connect_params = get_connect_params(socket) || %{}
|
||||
|
||||
sort_field_str = connect_params["member_sort_field"]
|
||||
sort_order_str = connect_params["member_sort_order"]
|
||||
|
||||
field = parse_and_validate_field(sort_field_str)
|
||||
order = parse_and_validate_order(sort_order_str)
|
||||
|
||||
{field, order}
|
||||
end
|
||||
|
||||
# Parses and validates a sort field with configurable default.
|
||||
#
|
||||
# Handles both regular member fields (converted to atoms) and custom fields
|
||||
# (kept as strings). Validates against allowed sort fields.
|
||||
#
|
||||
# Parameters:
|
||||
# - `field` - Field to parse (string or nil)
|
||||
# - `default` - Default field to use if parsing fails (default: :first_name)
|
||||
#
|
||||
# Returns a valid sort field (atom or string for custom fields).
|
||||
defp parse_and_validate_field(field, default \\ :first_name)
|
||||
|
||||
defp parse_and_validate_field(field_str, default) when is_binary(field_str) do
|
||||
if valid_sort_field?(field_str), do: field_str, else: default
|
||||
end
|
||||
|
||||
defp parse_and_validate_field(_, default), do: default
|
||||
|
||||
# Parses and validates a sort order with configurable default.
|
||||
#
|
||||
# Ensures the order is either :asc or :desc.
|
||||
#
|
||||
# Parameters:
|
||||
# - `order` - Order to parse, as a string or nil
|
||||
#
|
||||
# Returns `:asc` or `:desc`.
|
||||
defp parse_and_validate_order("asc"), do: :asc
|
||||
defp parse_and_validate_order("desc"), do: :desc
|
||||
defp parse_and_validate_order(_), do: :asc
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.header>
|
||||
{gettext("Members")}
|
||||
<:actions>
|
||||
<.button variant="primary" navigate={~p"/members/new"}>
|
||||
<.icon name="hero-plus" /> {gettext("New Member")}
|
||||
</.button>
|
||||
</:actions>
|
||||
</.header>
|
||||
<div id="member-sort-persistence" phx-hook="MemberSortPersistence">
|
||||
<.header>
|
||||
{gettext("Members")}
|
||||
<:actions>
|
||||
<.button variant="primary" navigate={~p"/members/new"}>
|
||||
<.icon name="hero-plus" /> {gettext("New Member")}
|
||||
</.button>
|
||||
</:actions>
|
||||
</.header>
|
||||
|
||||
<.live_component
|
||||
module={MvWeb.Components.SearchBarComponent}
|
||||
|
|
@ -205,4 +206,5 @@
|
|||
</.link>
|
||||
</:action>
|
||||
</.table>
|
||||
</div>
|
||||
</Layouts.app>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue