diff --git a/lib/plausible/teams/memberships/remove.ex b/lib/plausible/teams/memberships/remove.ex index 9aa1562e2c43..7ba440884d8e 100644 --- a/lib/plausible/teams/memberships/remove.ex +++ b/lib/plausible/teams/memberships/remove.ex @@ -8,14 +8,17 @@ defmodule Plausible.Teams.Memberships.Remove do def remove(nil, _, _), do: {:error, :permission_denied} - def remove(team, user_id, current_user) do + def remove(team, user_id, current_user, opts \\ []) do with {:ok, team_membership} <- Memberships.get_team_membership(team, user_id), {:ok, current_user_role} <- Memberships.team_role(team, current_user), :ok <- check_can_remove_membership(current_user_role, team_membership.role), :ok <- check_owner_can_get_removed(team, team_membership.role) do team_membership = Repo.preload(team_membership, [:team, :user]) Repo.delete!(team_membership) - send_team_member_removed_email(team_membership) + + if Keyword.get(opts, :send_email?, true) do + send_team_member_removed_email(team_membership) + end {:ok, team_membership} end @@ -35,7 +38,7 @@ defmodule Plausible.Teams.Memberships.Remove do defp check_owner_can_get_removed(_team, _role), do: :ok - defp send_team_member_removed_email(team_membership) do + def send_team_member_removed_email(team_membership) do team_membership |> PlausibleWeb.Email.team_member_removed() |> Plausible.Mailer.send() diff --git a/lib/plausible_web/live/team_management.ex b/lib/plausible_web/live/team_management.ex index b5991254b9e2..9b61bfb8cd08 100644 --- a/lib/plausible_web/live/team_management.ex +++ b/lib/plausible_web/live/team_management.ex @@ -15,6 +15,8 @@ defmodule PlausibleWeb.Live.TeamManagement do all_members = Teams.Memberships.all_members(my_team) invitations_pending = [] + invitations_to_delete = [] + memberships_to_delete = [] socket = assign(socket, @@ -22,7 +24,9 @@ defmodule PlausibleWeb.Live.TeamManagement do invitations_pending: invitations_pending, invitations_sent: Plausible.Teams.Invitations.find_team_invitations(my_team), selected_invitation_role: :admin, - team_layout_changed?: false + team_layout_changed?: false, + invitations_to_delete: invitations_to_delete, + memberships_to_delete: memberships_to_delete ) {:ok, socket} @@ -122,6 +126,31 @@ defmodule PlausibleWeb.Live.TeamManagement do result = Repo.transaction(fn -> + Enum.each(socket.assigns.invitations_to_delete, fn invitation -> + Plausible.Teams.Invitations.Remove.remove( + socket.assigns.my_team, + invitation.invitation_id, + socket.assigns.current_user + ) + end) + + memberships_removed = + Enum.map(socket.assigns.memberships_to_delete, fn membership -> + {:ok, membership} = + Plausible.Teams.Memberships.Remove.remove( + socket.assigns.my_team, + membership.id, + socket.assigns.current_user, + send_email?: false + ) + + membership + end) + + Enum.each(memberships_removed, fn team_membership -> + Plausible.Teams.Memberships.Remove.send_team_member_removed_email(team_membership) + end) + Enum.map(socket.assigns.invitations_pending, fn %{email: email, role: role} -> invite_fn.(email, role) end) @@ -137,7 +166,16 @@ defmodule PlausibleWeb.Live.TeamManagement do socket |> put_live_flash(:success, "Invitations sent successfully") - |> assign(team_layout_changed?: false) + |> assign( + team_layout_changed?: false, + all_members: Teams.Memberships.all_members(socket.assigns.my_team), + invitations_sent: + Plausible.Teams.Invitations.find_team_invitations(socket.assigns.my_team), + invitations_to_delete: [], + memberships_to_delete: [], + invitations_pending: [], + team_layout_changed?: false + ) # XXX: refresh here @@ -154,38 +192,35 @@ defmodule PlausibleWeb.Live.TeamManagement do def handle_event("remove-member", %{"email" => email}, socket) do invitations_pending = Enum.reject(socket.assigns.invitations_pending, &(&1.email == email)) + + socket = assign(socket, invitations_pending: invitations_pending) + invitation_to_delete = Enum.find(socket.assigns.invitations_sent, &(&1.email == email)) - invitations_sent = + socket = if invitation_to_delete do - Repo.delete!(invitation_to_delete) - Plausible.Teams.Invitations.find_team_invitations(socket.assigns.my_team) + assign(socket, + invitations_to_delete: [invitation_to_delete | socket.assigns.invitations_to_delete], + invitations_sent: Enum.reject(socket.assigns.invitations_sent, &(&1.email == email)), + team_layout_changed?: true + ) else - socket.assigns.invitations_sent + socket end - member_to_remove = Enum.find(socket.assigns.all_members, &(&1.user.email == email)) + member_to_delete = Enum.find(socket.assigns.all_members, &(&1.user.email == email)) - all_members = - if member_to_remove do - Plausible.Teams.Memberships.Remove.remove( - socket.assigns.my_team, - member_to_remove.id, - socket.assigns.current_user + socket = + if member_to_delete do + assign(socket, + memberships_to_delete: [member_to_delete | socket.assigns.memberships_to_delete], + all_members: Enum.reject(socket.assigns.all_members, &(&1.user.email == email)), + team_layout_changed?: true ) - - Teams.Memberships.all_members(socket.assigns.my_team) else - socket.assigns.all_members + socket end - socket = - assign(socket, - all_members: all_members, - invitations_sent: invitations_sent, - invitations_pending: invitations_pending - ) - {:noreply, socket} end