defmodule MvWeb.GroupLive.Index do @moduledoc """ LiveView for displaying and managing the groups list. ## Features - List all groups with name, description, and member count - Create new groups - Navigate to group details and edit forms - Delete groups (with confirmation) ## Security - Admin users can create, edit, and delete groups - Read-only users can view groups but not manage them - Non-admin users are redirected """ use MvWeb, :live_view import MvWeb.LiveHelpers, only: [current_actor: 1, ash_actor_opts: 1] import MvWeb.Authorization @impl true def mount(_params, _session, socket) do actor = current_actor(socket) # Check if user can read groups if can?(actor, :read, Mv.Membership.Group) do groups = load_groups(actor) {:ok, socket |> assign(:page_title, gettext("Groups")) |> assign(:groups, groups)} else {:ok, redirect(socket, to: ~p"/members")} end end @impl true def render(assigns) do ~H"""

{gettext("Groups")}

<%= if can?(@current_user, :create, Mv.Membership.Group) do %> <.button navigate={~p"/groups/new"} variant="primary"> <.icon name="hero-plus" class="size-4 mr-2" /> {gettext("Create Group")} <% end %>
<%= if Enum.empty?(@groups) do %>

{gettext("No groups")}

<% else %>
<%= for group <- @groups do %> <% end %>
{gettext("Name")} {gettext("Description")} {gettext("Members")} {gettext("Actions")}
{group.name} <%= if group.description do %> {group.description} <% else %> <% end %> <%= if group.member_count do %> {group.member_count} <% else %> 0 <% end %>
<.link navigate={~p"/groups/#{group.slug}"} class="btn btn-sm btn-ghost"> {gettext("View")} <%= if can?(@current_user, :update, Mv.Membership.Group) do %> <.link navigate={~p"/groups/#{group.slug}/edit"} class="btn btn-sm btn-ghost" > {gettext("Edit")} <% end %>
<% end %>
""" end @spec load_groups(map() | nil) :: [Mv.Membership.Group.t()] defp load_groups(actor) do require Ash.Query query = Mv.Membership.Group |> Ash.Query.load(:member_count) opts = ash_actor_opts(actor) case Ash.read(query, opts) do {:ok, groups} -> Enum.sort_by(groups, & &1.name) {:error, _} -> [] end end end