All checks were successful
continuous-integration/drone/push Build is passing
116 lines
3.1 KiB
Elixir
116 lines
3.1 KiB
Elixir
defmodule MvWeb.MemberLive.Index do
|
|
use MvWeb, :live_view
|
|
import Ash.Expr
|
|
import Ash.Query
|
|
import MvWeb.TableComponents
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
members = Ash.read!(Mv.Membership.Member)
|
|
sorted = Enum.sort_by(members, & &1.first_name)
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:page_title, gettext("Members"))
|
|
|> assign(:query, "")
|
|
|> assign(:sort_field, :first_name)
|
|
|> assign(:sort_order, :asc)
|
|
|> assign(:members, sorted)
|
|
|> assign(:selected_members, [])}
|
|
end
|
|
|
|
# -----------------------------------------------------------------
|
|
# Receive messages from any toolbar component
|
|
# -----------------------------------------------------------------
|
|
|
|
# Function to handle search
|
|
@impl true
|
|
def handle_info({:search_changed, q}, socket) do
|
|
members =
|
|
if String.trim(q) == "" do
|
|
Ash.read!(Mv.Membership.Member)
|
|
else
|
|
Mv.Membership.Member
|
|
|> filter(expr(fragment("search_vector @@ plainto_tsquery('simple', ?)", ^q)))
|
|
|> Ash.read!()
|
|
end
|
|
|
|
{:noreply,
|
|
socket
|
|
|> assign(:query, q)
|
|
|> assign(:members, members)}
|
|
end
|
|
|
|
# -----------------------------------------------------------------
|
|
# Handle Events
|
|
# -----------------------------------------------------------------
|
|
|
|
@impl true
|
|
def handle_event("delete", %{"id" => id}, socket) do
|
|
member = Ash.get!(Mv.Membership.Member, id)
|
|
Ash.destroy!(member)
|
|
|
|
updated_members = Enum.reject(socket.assigns.members, &(&1.id == id))
|
|
{:noreply, assign(socket, :members, updated_members)}
|
|
end
|
|
|
|
# Selects one member in the list of members
|
|
@impl true
|
|
def handle_event("select_member", %{"id" => id}, socket) do
|
|
selected =
|
|
if id in socket.assigns.selected_members do
|
|
List.delete(socket.assigns.selected_members, id)
|
|
else
|
|
[id | socket.assigns.selected_members]
|
|
end
|
|
|
|
{:noreply, assign(socket, :selected_members, selected)}
|
|
end
|
|
|
|
# Sorts the list of members according to a field, when you click on the column header
|
|
@impl true
|
|
def handle_event("sort", %{"field" => field_str}, socket) do
|
|
members = socket.assigns.members
|
|
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_members =
|
|
members
|
|
|> Enum.sort_by(&Map.get(&1, field), sort_fun(new_order))
|
|
|
|
{:noreply,
|
|
socket
|
|
|> assign(:sort_field, field)
|
|
|> assign(:sort_order, new_order)
|
|
|> assign(:members, sorted_members)}
|
|
end
|
|
|
|
# Selects all members in the list of members
|
|
|
|
@impl true
|
|
def handle_event("select_all", _params, socket) do
|
|
members = socket.assigns.members
|
|
|
|
all_ids = Enum.map(members, & &1.id)
|
|
|
|
selected =
|
|
if Enum.sort(socket.assigns.selected_members) == Enum.sort(all_ids) do
|
|
[]
|
|
else
|
|
all_ids
|
|
end
|
|
|
|
{:noreply, assign(socket, :selected_members, selected)}
|
|
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
|