feat: conistent danger zone delete flow
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
e5a6003ace
commit
91cf7cca6a
19 changed files with 499 additions and 287 deletions
|
|
@ -101,6 +101,31 @@ defmodule MvWeb.GroupLive.Form do
|
|||
rows="4"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<%!-- Danger zone: canonical pattern (same as member form) --%>
|
||||
<%= if @group && can?(@current_user, :destroy, @group) do %>
|
||||
<section class="mt-8 mb-6" aria-labelledby="danger-zone-heading">
|
||||
<h2 id="danger-zone-heading" class="text-lg font-semibold mb-3 text-error">
|
||||
{gettext("Danger zone")}
|
||||
</h2>
|
||||
<div class="border border-base-300 rounded-lg p-4 bg-base-100">
|
||||
<p class="text-base-content/70 mb-4">
|
||||
{gettext(
|
||||
"Deleting this group cannot be undone. All member-group associations will be permanently removed."
|
||||
)}
|
||||
</p>
|
||||
<.button
|
||||
variant="danger"
|
||||
navigate={~p"/groups/#{@group.slug}?confirm_delete=1"}
|
||||
data-testid="group-form-delete-btn"
|
||||
aria-label={gettext("Delete group %{name}", name: @group.name)}
|
||||
>
|
||||
<.icon name="hero-trash" class="size-4" />
|
||||
{gettext("Delete group")}
|
||||
</.button>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
</div>
|
||||
</.form>
|
||||
</Layouts.app>
|
||||
|
|
|
|||
|
|
@ -77,24 +77,6 @@ defmodule MvWeb.GroupLive.Index do
|
|||
<:col :let={group} label={gettext("Members")} class="text-right">
|
||||
{group.member_count || 0}
|
||||
</:col>
|
||||
<:action :let={group}>
|
||||
<.button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
navigate={~p"/groups/#{group.slug}"}
|
||||
>
|
||||
{gettext("View")}
|
||||
</.button>
|
||||
<%= if can?(@current_user, :update, Mv.Membership.Group) do %>
|
||||
<.button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
navigate={~p"/groups/#{group.slug}/edit"}
|
||||
>
|
||||
{gettext("Edit group")}
|
||||
</.button>
|
||||
<% end %>
|
||||
</:action>
|
||||
</.table>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -39,18 +39,18 @@ defmodule MvWeb.GroupLive.Show do
|
|||
end
|
||||
|
||||
@impl true
|
||||
def handle_params(%{"slug" => slug}, _url, socket) do
|
||||
def handle_params(%{"slug" => slug} = params, _url, socket) do
|
||||
actor = current_actor(socket)
|
||||
|
||||
# Check if user can read groups
|
||||
if can?(actor, :read, Mv.Membership.Group) do
|
||||
load_group_by_slug(socket, slug, actor)
|
||||
load_group_by_slug(socket, slug, actor, params)
|
||||
else
|
||||
{:noreply, redirect(socket, to: ~p"/members")}
|
||||
end
|
||||
end
|
||||
|
||||
defp load_group_by_slug(socket, slug, actor) do
|
||||
defp load_group_by_slug(socket, slug, actor, params \\ %{}) do
|
||||
# Load group with members and member_count
|
||||
# Using explicit load ensures efficient preloading of members relationship
|
||||
require Ash.Query
|
||||
|
|
@ -68,10 +68,16 @@ defmodule MvWeb.GroupLive.Show do
|
|||
|> redirect(to: ~p"/groups")}
|
||||
|
||||
{:ok, group} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(:page_title, group.name)
|
||||
|> assign(:group, group)}
|
||||
open_delete = params["confirm_delete"] == "1" && can?(actor, :destroy, group)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:page_title, group.name)
|
||||
|> assign(:group, group)
|
||||
|> assign(:show_delete_modal, open_delete)
|
||||
|> assign(:name_confirmation, "")
|
||||
|
||||
{:noreply, socket}
|
||||
|
||||
{:error, _error} ->
|
||||
{:noreply,
|
||||
|
|
@ -105,15 +111,6 @@ defmodule MvWeb.GroupLive.Show do
|
|||
{gettext("Edit group")}
|
||||
</.button>
|
||||
<% end %>
|
||||
<%= if can?(@current_user, :destroy, @group) do %>
|
||||
<.button
|
||||
variant="danger"
|
||||
phx-click="open_delete_modal"
|
||||
data-testid="group-show-delete-btn"
|
||||
>
|
||||
{gettext("Delete")}
|
||||
</.button>
|
||||
<% end %>
|
||||
</:actions>
|
||||
</.header>
|
||||
|
||||
|
|
@ -339,6 +336,32 @@ defmodule MvWeb.GroupLive.Show do
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<%!-- Danger zone: canonical pattern (same as member show) --%>
|
||||
<%= if can?(@current_user, :destroy, @group) do %>
|
||||
<section class="mt-8 mb-6" aria-labelledby="danger-zone-heading">
|
||||
<h2 id="danger-zone-heading" class="text-lg font-semibold mb-3 text-error">
|
||||
{gettext("Danger zone")}
|
||||
</h2>
|
||||
<div class="border border-base-300 rounded-lg p-4 bg-base-100">
|
||||
<p class="text-base-content/70 mb-4">
|
||||
{gettext(
|
||||
"Deleting this group cannot be undone. All member-group associations will be permanently removed."
|
||||
)}
|
||||
</p>
|
||||
<.button
|
||||
variant="danger"
|
||||
type="button"
|
||||
phx-click="open_delete_modal"
|
||||
data-testid="group-show-delete-btn"
|
||||
aria-label={gettext("Delete group %{name}", name: @group.name)}
|
||||
>
|
||||
<.icon name="hero-trash" class="size-4" />
|
||||
{gettext("Delete group")}
|
||||
</.button>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
|
||||
<%!-- Delete Confirmation Modal --%>
|
||||
<%= if assigns[:show_delete_modal] do %>
|
||||
<dialog id="delete-group-modal" class="modal modal-open" role="dialog">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue