chore: moved component and added mix_quiet to justfile

This commit is contained in:
carla 2025-12-03 14:56:01 +01:00
parent 8d1d04fa05
commit c3b33b55a5
2 changed files with 3 additions and 0 deletions

View file

@ -1,172 +0,0 @@
defmodule MvWeb.Components.FieldVisibilityDropdownComponent do
@moduledoc """
LiveComponent for managing field visibility in the member overview.
Provides an accessible dropdown menu where users can select/deselect
which member fields and custom fields are visible in the table.
## Props
- `:all_fields` - List of all available fields
- `:custom_fields` - List of CustomField resources
- `:selected_fields` - Map field_name boolean
- `:id` - Component ID
## Events sent to parent:
- `{:field_toggled, field, value}`
- `{:fields_selected, map}`
"""
use MvWeb, :live_component
# ---------------------------------------------------------------------------
# UPDATE
# ---------------------------------------------------------------------------
@impl true
def update(assigns, socket) do
socket =
socket
|> assign(assigns)
|> assign_new(:open, fn -> false end)
|> assign_new(:all_fields, fn -> [] end)
|> assign_new(:custom_fields, fn -> [] end)
|> assign_new(:selected_fields, fn -> %{} end)
{:ok, socket}
end
# ---------------------------------------------------------------------------
# RENDER
# ---------------------------------------------------------------------------
@impl true
def render(assigns) do
all_fields = assigns.all_fields || []
custom_fields = assigns.custom_fields || []
all_items =
Enum.map(member_fields(all_fields), fn field ->
%{
value: field_to_string(field),
label: format_field_label(field)
}
end) ++
Enum.map(custom_fields(all_fields), fn field ->
%{
value: field,
label: format_custom_field_label(field, custom_fields)
}
end)
assigns = assign(assigns, :all_items, all_items)
# LiveComponents require a static HTML element as root, not a function component
~H"""
<div>
<.dropdown_menu
id="field-visibility-menu"
icon="hero-adjustments-horizontal"
button_label={gettext("Columns")}
items={@all_items}
checkboxes={true}
selected={@selected_fields}
open={@open}
show_select_buttons={true}
phx_target={@myself}
/>
</div>
"""
end
# ---------------------------------------------------------------------------
# EVENTS (matching the Core Component API)
# ---------------------------------------------------------------------------
@impl true
def handle_event("toggle_dropdown", _params, socket) do
{:noreply, assign(socket, :open, !socket.assigns.open)}
end
def handle_event("close_dropdown", _params, socket) do
{:noreply, assign(socket, :open, false)}
end
# toggle single item
def handle_event("select_item", %{"item" => item}, socket) do
current = Map.get(socket.assigns.selected_fields, item, true)
updated = Map.put(socket.assigns.selected_fields, item, !current)
send(self(), {:field_toggled, item, !current})
{:noreply, assign(socket, :selected_fields, updated)}
end
# select all
def handle_event("select_all", _params, socket) do
all =
socket.assigns.all_fields
|> Enum.map(&field_to_string/1)
|> Enum.map(&{&1, true})
|> Enum.into(%{})
send(self(), {:fields_selected, all})
{:noreply, assign(socket, :selected_fields, all)}
end
# select none
def handle_event("select_none", _params, socket) do
none =
socket.assigns.all_fields
|> Enum.map(&field_to_string/1)
|> Enum.map(&{&1, false})
|> Enum.into(%{})
send(self(), {:fields_selected, none})
{:noreply, assign(socket, :selected_fields, none)}
end
# ---------------------------------------------------------------------------
# HELPERS (with defensive nil guards)
# ---------------------------------------------------------------------------
defp member_fields(nil), do: []
defp member_fields(fields) do
Enum.filter(fields, fn field ->
is_atom(field) ||
(is_binary(field) && not String.starts_with?(field, "custom_field_"))
end)
end
defp custom_fields(nil), do: []
defp custom_fields(fields) do
Enum.filter(fields, fn field ->
is_binary(field) && String.starts_with?(field, "custom_field_")
end)
end
defp field_to_string(field) when is_atom(field), do: Atom.to_string(field)
defp field_to_string(field) when is_binary(field), do: field
defp format_field_label(field) do
field
|> field_to_string()
|> String.replace("_", " ")
|> String.split()
|> Enum.map(&String.capitalize/1)
|> Enum.join(" ")
end
defp format_custom_field_label(field_string, custom_fields) do
case String.trim_leading(field_string, "custom_field_") do
"" ->
field_string
id ->
case Enum.find(custom_fields, fn cf -> to_string(cf.id) == id end) do
nil -> gettext("Custom Field %{id}", id: id)
custom_field -> custom_field.name
end
end
end
end