feat: disable email buttons instead hide them

This commit is contained in:
carla 2025-12-15 08:44:24 +01:00
parent 6c38d7455f
commit b0daf8f28c
3 changed files with 33 additions and 13 deletions

View file

@ -95,9 +95,11 @@ defmodule MvWeb.CoreComponents do
<.button>Send!</.button> <.button>Send!</.button>
<.button phx-click="go" variant="primary">Send!</.button> <.button phx-click="go" variant="primary">Send!</.button>
<.button navigate={~p"/"}>Home</.button> <.button navigate={~p"/"}>Home</.button>
<.button disabled={true}>Disabled</.button>
""" """
attr :rest, :global, include: ~w(href navigate patch method) attr :rest, :global, include: ~w(href navigate patch method)
attr :variant, :string, values: ~w(primary) attr :variant, :string, values: ~w(primary)
attr :disabled, :boolean, default: false, doc: "Whether the button is disabled"
slot :inner_block, required: true slot :inner_block, required: true
def button(%{rest: rest} = assigns) do def button(%{rest: rest} = assigns) do
@ -105,14 +107,34 @@ defmodule MvWeb.CoreComponents do
assigns = assign(assigns, :class, Map.fetch!(variants, assigns[:variant])) assigns = assign(assigns, :class, Map.fetch!(variants, assigns[:variant]))
if rest[:href] || rest[:navigate] || rest[:patch] do if rest[:href] || rest[:navigate] || rest[:patch] do
# For links, we can't use disabled attribute, so we use btn-disabled class
# DaisyUI's btn-disabled provides the same styling as :disabled on buttons
link_class =
if assigns[:disabled],
do: ["btn", assigns.class, "btn-disabled"],
else: ["btn", assigns.class]
# Prevent interaction when disabled
link_attrs =
if assigns[:disabled] do
Map.merge(rest, %{tabindex: "-1", "aria-disabled": "true"})
else
rest
end
assigns =
assigns
|> assign(:link_class, link_class)
|> assign(:link_attrs, link_attrs)
~H""" ~H"""
<.link class={["btn", @class]} {@rest}> <.link class={@link_class} {@link_attrs}>
{render_slot(@inner_block)} {render_slot(@inner_block)}
</.link> </.link>
""" """
else else
~H""" ~H"""
<button class={["btn", @class]} {@rest}> <button class={["btn", @class]} disabled={@disabled} {@rest}>
{render_slot(@inner_block)} {render_slot(@inner_block)}
</button> </button>
""" """

View file

@ -3,23 +3,29 @@
{gettext("Members")} {gettext("Members")}
<:actions> <:actions>
<.button <.button
:if={Enum.any?(@members, &MapSet.member?(@selected_members, &1.id))} class="secondary"
id="copy-emails-btn" id="copy-emails-btn"
phx-hook="CopyToClipboard" phx-hook="CopyToClipboard"
phx-click="copy_emails" phx-click="copy_emails"
disabled={not Enum.any?(@members, &MapSet.member?(@selected_members, &1.id))}
aria-label={gettext("Copy email addresses of selected members")} aria-label={gettext("Copy email addresses of selected members")}
> >
<.icon name="hero-clipboard-document" /> <.icon name="hero-clipboard-document" />
{gettext("Copy emails")} ({Enum.count(@members, &MapSet.member?(@selected_members, &1.id))}) {gettext("Copy email addresses")} ({Enum.count(
@members,
&MapSet.member?(@selected_members, &1.id)
)})
</.button> </.button>
<.button <.button
:if={Enum.any?(@members, &MapSet.member?(@selected_members, &1.id))} class="secondary"
id="open-email-btn"
href={ href={
"mailto:?bcc=" <> "mailto:?bcc=" <>
(MvWeb.MemberLive.Index.format_selected_member_emails(@members, @selected_members) (MvWeb.MemberLive.Index.format_selected_member_emails(@members, @selected_members)
|> Enum.join(", ") |> Enum.join(", ")
|> URI.encode()) |> URI.encode())
} }
disabled={not Enum.any?(@members, &MapSet.member?(@selected_members, &1.id))}
aria-label={gettext("Open email program with BCC recipients")} aria-label={gettext("Open email program with BCC recipients")}
> >
<.icon name="hero-envelope" /> <.icon name="hero-envelope" />

View file

@ -410,14 +410,6 @@ defmodule MvWeb.MemberLive.IndexTest do
assert render(view) =~ "1" assert render(view) =~ "1"
end end
test "copy button is not visible when no members are selected", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# Ensure no members are selected (default state)
refute has_element?(view, "#copy-emails-btn")
end
test "copy button is visible when members are selected", %{ test "copy button is visible when members are selected", %{
conn: conn, conn: conn,
member1: member1 member1: member1