defmodule MvWeb.UserLive.Index do @moduledoc """ LiveView for displaying and managing the user list. ## Features - List all users with email and linked member - Sort users by email (default) - Navigate to user details (row click) and edit from details header - Delete only via Danger zone on user show/edit ## Relationships Displays linked member information when a user is connected to a member account. ## Security User deletion requires admin permissions (enforced by Ash policies). """ use MvWeb, :live_view import MvWeb.TableComponents import MvWeb.LiveHelpers, only: [current_actor: 1] require Ash.Query @impl true def mount(_params, _session, socket) do actor = current_actor(socket) users = Mv.Accounts.User |> Ash.Query.filter(email != ^Mv.Helpers.SystemActor.system_user_email()) |> Ash.read!(domain: Mv.Accounts, load: [:member, :role], actor: actor) sorted = Enum.sort_by(users, & &1.email) {:ok, socket |> assign(:page_title, gettext("Listing Users")) |> assign(:sort_field, :email) |> assign(:sort_order, :asc) |> assign(:users, sorted)} end # Sorts the list of users according to a field, when you click on the column header @impl true def handle_event("sort", %{"field" => field_str}, socket) do users = socket.assigns.users field = String.to_existing_atom(field_str) new_order = if socket.assigns.sort_field == field do toggle_order(socket.assigns.sort_order) else :asc end sorted_users = users |> Enum.sort_by(&Map.get(&1, field), sort_fun(new_order)) {:noreply, socket |> assign(:sort_field, field) |> assign(:sort_order, new_order) |> assign(:users, sorted_users)} end defp toggle_order(:asc), do: :desc defp toggle_order(:desc), do: :asc defp sort_fun(:asc), do: &<=/2 defp sort_fun(:desc), do: &>=/2 end