fix: pr comments
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Simon 2026-02-12 15:08:40 +01:00
parent e4671e816b
commit 900f322422
Signed by: simon
GPG key ID: 40E7A58C4AA1EDB2
11 changed files with 161 additions and 80 deletions

View file

@ -15,6 +15,8 @@ defmodule MvWeb.GroupLive.Show do
"""
use MvWeb, :live_view
require Logger
import MvWeb.LiveHelpers, only: [current_actor: 1]
import MvWeb.Authorization
@ -162,7 +164,7 @@ defmodule MvWeb.GroupLive.Show do
phx-hook="ComboBox"
phx-focus="show_member_dropdown"
phx-debounce="300"
phx-window-keydown="member_dropdown_keydown"
phx-keydown="member_dropdown_keydown"
phx-mounted={JS.focus()}
value={@member_search_query}
placeholder={
@ -231,6 +233,14 @@ defmodule MvWeb.GroupLive.Show do
>
<.icon name="hero-plus" class="size-5" />
</button>
<button
type="button"
class="btn join-item"
phx-click="hide_add_member_input"
aria-label={gettext("Cancel")}
>
{gettext("Cancel")}
</button>
</div>
<% else %>
<.button
@ -439,12 +449,7 @@ defmodule MvWeb.GroupLive.Show do
@impl true
def handle_event("show_member_dropdown", _params, socket) do
# Reload group to ensure we have the latest members list before filtering
actor = current_actor(socket)
group = socket.assigns.group
socket = reload_group(socket, group.slug, actor)
# Load available members with empty query when input is focused
# Use existing group.members for filtering; reload only on add/remove
socket =
socket
|> load_available_members("")
@ -454,6 +459,19 @@ defmodule MvWeb.GroupLive.Show do
{:noreply, socket}
end
@impl true
def handle_event("hide_add_member_input", _params, socket) do
{:noreply,
socket
|> assign(:show_add_member_input, false)
|> assign(:member_search_query, "")
|> assign(:available_members, [])
|> assign(:selected_member_ids, [])
|> assign(:selected_members, [])
|> assign(:show_member_dropdown, false)
|> assign(:focused_member_index, nil)}
end
@impl true
def handle_event("hide_member_dropdown", _params, socket) do
{:noreply, assign(socket, show_member_dropdown: false, focused_member_index: nil)}
@ -514,11 +532,7 @@ defmodule MvWeb.GroupLive.Show do
@impl true
def handle_event("search_members", %{"member_search" => query}, socket) do
# Reload group to ensure we have the latest members list before filtering
actor = current_actor(socket)
group = socket.assigns.group
socket = reload_group(socket, group.slug, actor)
# Use existing group.members for filtering; reload only on add/remove
socket =
socket
|> assign(:member_search_query, query)
@ -574,7 +588,8 @@ defmodule MvWeb.GroupLive.Show do
# Server-side authorization check
if can?(actor, :update, group) do
perform_add_members(socket, group, socket.assigns.selected_member_ids, actor)
member_ids = Enum.uniq(socket.assigns.selected_member_ids)
perform_add_members(socket, group, member_ids, actor)
else
{:noreply,
socket
@ -648,23 +663,29 @@ defmodule MvWeb.GroupLive.Show do
defp load_available_members(socket, query) do
require Ash.Query
current_member_ids = group_member_ids_set(socket.assigns.group)
base_query = available_members_base_query(query)
limited_query = Ash.Query.limit(base_query, 10)
# Fetch more than 10, then exclude already-in-group and take 10 (avoids empty dropdown when first N are all in group)
fetch_limit = 50
limited_query = Ash.Query.limit(base_query, fetch_limit)
actor = current_actor(socket)
case Ash.read(limited_query, actor: actor, domain: Mv.Membership) do
{:ok, members} ->
current_member_ids = group_member_ids_set(socket.assigns.group)
available =
members
|> Enum.reject(fn m -> MapSet.member?(current_member_ids, m.id) end)
|> Enum.take(10)
filtered_members =
Enum.reject(members, fn member ->
MapSet.member?(current_member_ids, member.id)
end)
assign(socket, available_members: available)
assign(socket, available_members: filtered_members)
{:error, error} ->
Logger.warning("Failed to load available members for group: #{inspect(error)}")
{:error, _} ->
assign(socket, available_members: [])
socket
|> put_flash(:error, gettext("Could not load member search. Please try again."))
|> assign(:available_members, [])
end
end
@ -681,18 +702,8 @@ defmodule MvWeb.GroupLive.Show do
end
defp group_member_ids_set(group) do
cond do
is_list(group.members) and group.members != [] ->
group.members
|> Enum.map(& &1.id)
|> MapSet.new()
is_list(group.members) ->
MapSet.new()
true ->
MapSet.new()
end
members = group.members || []
members |> Enum.map(& &1.id) |> MapSet.new()
end
defp perform_add_members(socket, group, member_ids, actor) when is_list(member_ids) do