diff --git a/lib/mv_web/live/member_live/index.ex b/lib/mv_web/live/member_live/index.ex index 51d2bd2..c4c0d97 100644 --- a/lib/mv_web/live/member_live/index.ex +++ b/lib/mv_web/live/member_live/index.ex @@ -207,46 +207,70 @@ defmodule MvWeb.MemberLive.Index do # Function to sort the column if needed defp maybe_sort(query, nil, _), do: query - defp maybe_sort(query, field, :asc) when not is_nil(field), do: Ash.Query.sort(query, [{field, :asc}]) - defp maybe_sort(query, field, :desc) when not is_nil(field), do: Ash.Query.sort(query, [{field, :desc}]) + + defp maybe_sort(query, field, :asc) when not is_nil(field), + do: Ash.Query.sort(query, [{field, :asc}]) + + defp maybe_sort(query, field, :desc) when not is_nil(field), + do: Ash.Query.sort(query, [{field, :desc}]) + defp maybe_sort(query, _, _), do: query # Validate that a field is sortable defp valid_sort_field?(field) when is_atom(field) do valid_fields = [ - :first_name, :last_name, :email, :street, :house_number, - :postal_code, :city, :phone_number, :join_date + :first_name, + :last_name, + :email, + :street, + :house_number, + :postal_code, + :city, + :phone_number, + :join_date ] + field in valid_fields end + defp valid_sort_field?(_), do: false # Function to maybe update the sort defp maybe_update_sort(socket, %{"sort_field" => sf, "sort_order" => so}) do # Handle empty strings and nil values - field = case sf do - "" -> socket.assigns.sort_field - nil -> socket.assigns.sort_field - sf when is_binary(sf) -> - try do - String.to_existing_atom(sf) - rescue - ArgumentError -> socket.assigns.sort_field - end - sf when is_atom(sf) -> sf - _ -> socket.assigns.sort_field - end + field = + case sf do + "" -> + socket.assigns.sort_field + + nil -> + socket.assigns.sort_field + + sf when is_binary(sf) -> + try do + String.to_existing_atom(sf) + rescue + ArgumentError -> socket.assigns.sort_field + end + + sf when is_atom(sf) -> + sf + + _ -> + socket.assigns.sort_field + end # Validate that the field is actually sortable field = if valid_sort_field?(field), do: field, else: socket.assigns.sort_field # Handle empty strings and nil values for sort order - order = case so do - "" -> socket.assigns.sort_order - nil -> socket.assigns.sort_order - so when so in ["asc", "desc"] -> String.to_atom(so) - _ -> socket.assigns.sort_order - end + order = + case so do + "" -> socket.assigns.sort_order + nil -> socket.assigns.sort_order + so when so in ["asc", "desc"] -> String.to_atom(so) + _ -> socket.assigns.sort_order + end socket |> assign(:sort_field, field) diff --git a/test/mv_web/components/sort_header_component_test.exs b/test/mv_web/components/sort_header_component_test.exs index 55c3f00..c4b45dd 100644 --- a/test/mv_web/components/sort_header_component_test.exs +++ b/test/mv_web/components/sort_header_component_test.exs @@ -17,7 +17,16 @@ defmodule MvWeb.Components.SortHeaderComponentTest do conn = conn_with_oidc_user(conn) {:ok, view, _html} = live(conn, "/members") - sortable_fields = [:first_name, :email, :street, :house_number, :postal_code, :city, :phone_number, :join_date] + sortable_fields = [ + :first_name, + :email, + :street, + :house_number, + :postal_code, + :city, + :phone_number, + :join_date + ] for field <- sortable_fields do assert has_element?(view, "button[phx-value-field='#{field}']") @@ -65,7 +74,8 @@ defmodule MvWeb.Components.SortHeaderComponentTest do # Count occurrences to ensure only one ascending icon up_count = html |> String.split("hero-chevron-up ") |> length() |> Kernel.-(1) - assert up_count == 1 # Should be exactly one chevron-up icon + # Should be exactly one chevron-up icon + assert up_count == 1 end test "shows descending icon for specific field when sorted descending", %{conn: conn} do @@ -74,7 +84,8 @@ defmodule MvWeb.Components.SortHeaderComponentTest do # Count occurrences to ensure only one descending icon down_count = html |> String.split("hero-chevron-down ") |> length() |> Kernel.-(1) - assert down_count == 1 # Should be exactly one chevron-down icon + # Should be exactly one chevron-down icon + assert down_count == 1 end test "multiple fields can have different icon states", %{conn: conn} do @@ -146,7 +157,9 @@ defmodule MvWeb.Components.SortHeaderComponentTest do {:ok, _view, html_neutral} = live(conn, "/members") # Count neutral icons (should be 7 - one for each field) - neutral_count = html_neutral |> String.split("hero-chevron-up-down") |> length() |> Kernel.-(1) + neutral_count = + html_neutral |> String.split("hero-chevron-up-down") |> length() |> Kernel.-(1) + assert neutral_count == 7 # Count active icons (should be 1) @@ -209,7 +222,12 @@ defmodule MvWeb.Components.SortHeaderComponentTest do # Test aria-labels for different fields assert has_element?(view, "button[phx-value-field='email'][aria-label='descending']") - assert has_element?(view, "button[phx-value-field='first_name'][aria-label='Click to sort']") + + assert has_element?( + view, + "button[phx-value-field='first_name'][aria-label='Click to sort']" + ) + assert has_element?(view, "button[phx-value-field='city'][aria-label='Click to sort']") end end diff --git a/test/mv_web/member_live/index_test.exs b/test/mv_web/member_live/index_test.exs index a32d967..0668202 100644 --- a/test/mv_web/member_live/index_test.exs +++ b/test/mv_web/member_live/index_test.exs @@ -115,7 +115,15 @@ defmodule MvWeb.MemberLive.IndexTest do # default ascending sorting with first name assert has_element?(view, "[data-testid='first_name'][aria-label='ascending']") - sortable_fields = [:email, :street, :house_number, :postal_code, :city, :phone_number, :join_date] + sortable_fields = [ + :email, + :street, + :house_number, + :postal_code, + :city, + :phone_number, + :join_date + ] for field <- sortable_fields do view