refactor: improve groups LiveView based on code review feedback
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
3eb4cde0b7
commit
ddc8335cc0
8 changed files with 109 additions and 104 deletions
|
|
@ -23,78 +23,29 @@ defmodule MvWeb.GroupLive.Form do
|
|||
def mount(params, _session, socket) do
|
||||
actor = current_actor(socket)
|
||||
|
||||
# Check authorization
|
||||
# Check authorization based on whether we are creating or updating
|
||||
action = if params["slug"], do: :update, else: :create
|
||||
resource = Mv.Membership.Group
|
||||
|
||||
if can?(actor, action, resource) do
|
||||
case load_group_for_form(socket, params, actor) do
|
||||
{:redirect, socket} ->
|
||||
{:ok, socket}
|
||||
|
||||
{:ok, socket} ->
|
||||
{:ok, assign_form(socket)}
|
||||
end
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(:actor, actor)
|
||||
|> assign(:group, nil)
|
||||
|> assign(:page_title, page_title_for_params(params))
|
||||
|> assign(:return_to, return_to_for_params(params))}
|
||||
else
|
||||
{:ok, redirect(socket, to: ~p"/groups")}
|
||||
end
|
||||
end
|
||||
|
||||
defp load_group_for_form(socket, params, actor) do
|
||||
case params["slug"] do
|
||||
nil ->
|
||||
# New group
|
||||
socket =
|
||||
socket
|
||||
|> assign(:group, nil)
|
||||
|> assign(:page_title, gettext("Create Group"))
|
||||
|> assign(:return_to, "index")
|
||||
|
||||
{:ok, socket}
|
||||
|
||||
slug ->
|
||||
# Edit existing group
|
||||
load_existing_group(socket, slug, actor)
|
||||
end
|
||||
end
|
||||
|
||||
defp load_existing_group(socket, slug, actor) do
|
||||
case Membership.get_group_by_slug(slug, actor: actor) do
|
||||
{:ok, nil} ->
|
||||
socket =
|
||||
socket
|
||||
|> put_flash(:error, gettext("Group not found."))
|
||||
|> redirect(to: ~p"/groups")
|
||||
|
||||
{:redirect, socket}
|
||||
|
||||
{:ok, group} ->
|
||||
socket =
|
||||
socket
|
||||
|> assign(:group, group)
|
||||
|> assign(:page_title, gettext("Edit Group"))
|
||||
|> assign(:return_to, "show")
|
||||
|
||||
{:ok, socket}
|
||||
|
||||
{:error, _error} ->
|
||||
socket =
|
||||
socket
|
||||
|> put_flash(:error, gettext("Failed to load group."))
|
||||
|> redirect(to: ~p"/groups")
|
||||
|
||||
{:redirect, socket}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_params(params, _url, socket) do
|
||||
# Handle slug-based routing for edit
|
||||
actor = socket.assigns.actor
|
||||
|
||||
case params do
|
||||
%{"slug" => slug} when is_binary(slug) ->
|
||||
actor = current_actor(socket)
|
||||
|
||||
case Membership.get_group_by_slug(slug, actor: actor) do
|
||||
case Membership.get_group_by_slug(slug, actor: actor, load: []) do
|
||||
{:ok, nil} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|
|
@ -106,8 +57,8 @@ defmodule MvWeb.GroupLive.Form do
|
|||
socket
|
||||
|> assign(:group, group)
|
||||
|> assign(:page_title, gettext("Edit Group"))
|
||||
|> assign(:return_to, "show")
|
||||
|> assign_form()}
|
||||
|> assign(:return_to, :show)
|
||||
|> assign_form(actor)}
|
||||
|
||||
{:error, _error} ->
|
||||
{:noreply,
|
||||
|
|
@ -117,7 +68,8 @@ defmodule MvWeb.GroupLive.Form do
|
|||
end
|
||||
|
||||
_ ->
|
||||
{:noreply, socket}
|
||||
# New group - ensure form is initialized for create
|
||||
{:noreply, assign_form(socket, actor)}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -163,17 +115,16 @@ defmodule MvWeb.GroupLive.Form do
|
|||
end
|
||||
|
||||
def handle_event("save", %{"group" => group_params}, socket) do
|
||||
actor = current_actor(socket)
|
||||
actor = socket.assigns.actor
|
||||
|
||||
case submit_form(socket.assigns.form, group_params, actor) do
|
||||
{:ok, group} ->
|
||||
notify_parent({:saved, group})
|
||||
|
||||
redirect_path =
|
||||
if socket.assigns.return_to == "show" do
|
||||
~p"/groups/#{group.slug}"
|
||||
else
|
||||
~p"/groups"
|
||||
case socket.assigns.return_to do
|
||||
:show -> ~p"/groups/#{group.slug}"
|
||||
_ -> ~p"/groups"
|
||||
end
|
||||
|
||||
socket =
|
||||
|
|
@ -190,9 +141,8 @@ defmodule MvWeb.GroupLive.Form do
|
|||
|
||||
defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
|
||||
|
||||
defp assign_form(%{assigns: assigns} = socket) do
|
||||
defp assign_form(%{assigns: assigns} = socket, actor) do
|
||||
group = Map.get(assigns, :group)
|
||||
actor = assigns.current_user
|
||||
|
||||
form =
|
||||
if group do
|
||||
|
|
@ -216,9 +166,19 @@ defmodule MvWeb.GroupLive.Form do
|
|||
assign(socket, form: to_form(form))
|
||||
end
|
||||
|
||||
defp return_path("index", _group), do: ~p"/groups"
|
||||
defp return_path("show", group) when not is_nil(group), do: ~p"/groups/#{group.slug}"
|
||||
defp return_path("show", _group), do: ~p"/groups"
|
||||
defp page_title_for_params(%{"slug" => _slug}), do: gettext("Edit Group")
|
||||
defp page_title_for_params(_params), do: gettext("Create Group")
|
||||
|
||||
defp return_to_for_params(%{"slug" => _slug}), do: :show
|
||||
defp return_to_for_params(_params), do: :index
|
||||
|
||||
defp return_path(:index, _group), do: ~p"/groups"
|
||||
|
||||
defp return_path(:show, group) when not is_nil(group), do: ~p"/groups/#{group.slug}"
|
||||
|
||||
defp return_path(:show, _group), do: ~p"/groups"
|
||||
|
||||
defp return_path(_, group) when not is_nil(group), do: ~p"/groups/#{group.slug}"
|
||||
|
||||
defp return_path(_, _group), do: ~p"/groups"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -116,14 +116,17 @@ defmodule MvWeb.GroupLive.Index do
|
|||
query =
|
||||
Mv.Membership.Group
|
||||
|> Ash.Query.load(:member_count)
|
||||
|> Ash.Query.sort(:name)
|
||||
|
||||
opts = ash_actor_opts(actor)
|
||||
|
||||
case Ash.read(query, opts) do
|
||||
{:ok, groups} ->
|
||||
Enum.sort_by(groups, & &1.name)
|
||||
groups
|
||||
|
||||
{:error, _} ->
|
||||
{:error, _error} ->
|
||||
require Logger
|
||||
Logger.warning("Failed to load groups in GroupLive.Index")
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ defmodule MvWeb.GroupLive.Show do
|
|||
<div class="p-2 mb-2 font-mono text-lg font-bold break-all rounded bg-base-200">
|
||||
{@group.name}
|
||||
</div>
|
||||
<form phx-change="update_name_confirmation">
|
||||
<form phx-change="update_name_confirmation" phx-debounce="200">
|
||||
<input
|
||||
id="group-name-confirmation"
|
||||
name="name"
|
||||
|
|
@ -244,21 +244,29 @@ defmodule MvWeb.GroupLive.Show do
|
|||
def handle_event("confirm_delete", %{"slug" => slug}, socket) do
|
||||
actor = current_actor(socket)
|
||||
|
||||
case Membership.get_group_by_slug(slug, actor: actor) do
|
||||
{:ok, nil} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, gettext("Group not found."))
|
||||
|> redirect(to: ~p"/groups")}
|
||||
# Server-side authorization check to prevent unauthorized delete attempts
|
||||
if can?(actor, :destroy, Mv.Membership.Group) do
|
||||
case Membership.get_group_by_slug(slug, actor: actor, load: []) do
|
||||
{:ok, nil} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, gettext("Group not found."))
|
||||
|> redirect(to: ~p"/groups")}
|
||||
|
||||
{:ok, group} ->
|
||||
handle_delete_confirmation(socket, group, actor)
|
||||
{:ok, group} ->
|
||||
handle_delete_confirmation(socket, group, actor)
|
||||
|
||||
{:error, _error} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, gettext("Failed to load group."))
|
||||
|> redirect(to: ~p"/groups")}
|
||||
{:error, _error} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, gettext("Failed to load group."))
|
||||
|> redirect(to: ~p"/groups")}
|
||||
end
|
||||
else
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, gettext("Not authorized."))
|
||||
|> redirect(to: ~p"/groups")}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -269,8 +277,7 @@ defmodule MvWeb.GroupLive.Show do
|
|||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, gettext("Group name does not match."))
|
||||
|> assign(:show_delete_modal, false)
|
||||
|> assign(:name_confirmation, "")}
|
||||
|> assign(:show_delete_modal, true)}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue