From 8e4f1ba674162388557ec525a83666b252a1531c Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 3 Dec 2025 14:24:10 +0100 Subject: [PATCH 1/4] feat: add col_click attribute to table component for checkbox column - Add col_click slot attribute to table component that overrides row_click - Clicking anywhere in the checkbox column now toggles the checkbox - Clicking other columns still navigates to member details Closes #223 --- lib/mv_web/components/core_components.ex | 8 +++-- lib/mv_web/live/member_live/index.ex | 10 ++++++ lib/mv_web/live/member_live/index.html.heex | 5 +-- priv/gettext/de/LC_MESSAGES/default.po | 36 ++++++++++----------- priv/gettext/default.pot | 36 ++++++++++----------- priv/gettext/en/LC_MESSAGES/default.po | 36 ++++++++++----------- 6 files changed, 71 insertions(+), 60 deletions(-) diff --git a/lib/mv_web/components/core_components.ex b/lib/mv_web/components/core_components.ex index 54a5a64..a432652 100644 --- a/lib/mv_web/components/core_components.ex +++ b/lib/mv_web/components/core_components.ex @@ -357,6 +357,7 @@ defmodule MvWeb.CoreComponents do slot :col, required: true do attr :label, :string + attr :col_click, :any, doc: "optional column-specific click handler that overrides row_click" end slot :action, doc: "the slot for showing user actions in the last table column" @@ -391,8 +392,11 @@ defmodule MvWeb.CoreComponents do {render_slot(col, @row_item.(row))} diff --git a/lib/mv_web/live/member_live/index.ex b/lib/mv_web/live/member_live/index.ex index 67ce522..1100f45 100644 --- a/lib/mv_web/live/member_live/index.ex +++ b/lib/mv_web/live/member_live/index.ex @@ -892,6 +892,16 @@ defmodule MvWeb.MemberLive.Index do |> Enum.map(&format_member_email/1) end + @doc """ + Returns a JS command to toggle member selection when clicking the checkbox column. + + Used as `col_click` handler to ensure clicking anywhere in the checkbox column + toggles the checkbox instead of navigating to the member details. + """ + def checkbox_column_click(member) do + JS.push("select_member", value: %{id: member.id}) + end + # Formats a member's email in the format "First Last " # Used for copy_emails feature and mailto links to create email-client-friendly format. def format_member_email(member) do diff --git a/lib/mv_web/live/member_live/index.html.heex b/lib/mv_web/live/member_live/index.html.heex index 9f8851b..6b69882 100644 --- a/lib/mv_web/live/member_live/index.html.heex +++ b/lib/mv_web/live/member_live/index.html.heex @@ -58,6 +58,7 @@ <:col :let={member} + col_click={&MvWeb.MemberLive.Index.checkbox_column_click/1} label={ ~H""" <.input @@ -74,11 +75,7 @@ <.input type="checkbox" name={member.id} - phx-click="select_member" - phx-value-id={member.id} checked={MapSet.member?(@selected_members, member.id)} - phx-capture-click - phx-stop-propagation aria-label={gettext("Select member")} role="checkbox" /> diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po index 57df5ab..0098ae1 100644 --- a/priv/gettext/de/LC_MESSAGES/default.po +++ b/priv/gettext/de/LC_MESSAGES/default.po @@ -10,12 +10,12 @@ msgid "" msgstr "" "Language: en\n" -#: lib/mv_web/components/core_components.ex:386 +#: lib/mv_web/components/core_components.ex:387 #, elixir-autogen, elixir-format msgid "Actions" msgstr "Aktionen" -#: lib/mv_web/live/member_live/index.html.heex:248 +#: lib/mv_web/live/member_live/index.html.heex:245 #: lib/mv_web/live/user_live/index.html.heex:72 #, elixir-autogen, elixir-format msgid "Are you sure?" @@ -28,19 +28,19 @@ msgid "Attempting to reconnect" msgstr "Verbindung wird wiederhergestellt" #: lib/mv_web/live/member_live/form.ex:53 -#: lib/mv_web/live/member_live/index.html.heex:184 +#: lib/mv_web/live/member_live/index.html.heex:181 #: lib/mv_web/live/member_live/show.ex:58 #, elixir-autogen, elixir-format msgid "City" msgstr "Stadt" -#: lib/mv_web/live/member_live/index.html.heex:250 +#: lib/mv_web/live/member_live/index.html.heex:247 #: lib/mv_web/live/user_live/index.html.heex:74 #, elixir-autogen, elixir-format msgid "Delete" msgstr "Löschen" -#: lib/mv_web/live/member_live/index.html.heex:242 +#: lib/mv_web/live/member_live/index.html.heex:239 #: lib/mv_web/live/user_live/form.ex:265 #: lib/mv_web/live/user_live/index.html.heex:66 #, elixir-autogen, elixir-format @@ -54,7 +54,7 @@ msgid "Edit Member" msgstr "Mitglied bearbeiten" #: lib/mv_web/live/member_live/form.ex:47 -#: lib/mv_web/live/member_live/index.html.heex:112 +#: lib/mv_web/live/member_live/index.html.heex:109 #: lib/mv_web/live/member_live/show.ex:50 #: lib/mv_web/live/user_live/form.ex:46 #: lib/mv_web/live/user_live/index.html.heex:44 @@ -70,7 +70,7 @@ msgid "First Name" msgstr "Vorname" #: lib/mv_web/live/member_live/form.ex:50 -#: lib/mv_web/live/member_live/index.html.heex:220 +#: lib/mv_web/live/member_live/index.html.heex:217 #: lib/mv_web/live/member_live/show.ex:55 #, elixir-autogen, elixir-format msgid "Join Date" @@ -87,7 +87,7 @@ msgstr "Nachname" msgid "New Member" msgstr "Neues Mitglied" -#: lib/mv_web/live/member_live/index.html.heex:239 +#: lib/mv_web/live/member_live/index.html.heex:236 #: lib/mv_web/live/user_live/index.html.heex:63 #, elixir-autogen, elixir-format msgid "Show" @@ -115,7 +115,7 @@ msgid "Exit Date" msgstr "Austrittsdatum" #: lib/mv_web/live/member_live/form.ex:55 -#: lib/mv_web/live/member_live/index.html.heex:148 +#: lib/mv_web/live/member_live/index.html.heex:145 #: lib/mv_web/live/member_live/show.ex:60 #, elixir-autogen, elixir-format msgid "House Number" @@ -130,21 +130,21 @@ msgstr "Notizen" #: lib/mv_web/live/components/payment_filter_component.ex:94 #: lib/mv_web/live/components/payment_filter_component.ex:144 #: lib/mv_web/live/member_live/form.ex:48 -#: lib/mv_web/live/member_live/index.html.heex:229 +#: lib/mv_web/live/member_live/index.html.heex:226 #: lib/mv_web/live/member_live/show.ex:51 #, elixir-autogen, elixir-format msgid "Paid" msgstr "Bezahlt" #: lib/mv_web/live/member_live/form.ex:49 -#: lib/mv_web/live/member_live/index.html.heex:202 +#: lib/mv_web/live/member_live/index.html.heex:199 #: lib/mv_web/live/member_live/show.ex:54 #, elixir-autogen, elixir-format msgid "Phone Number" msgstr "Telefonnummer" #: lib/mv_web/live/member_live/form.ex:56 -#: lib/mv_web/live/member_live/index.html.heex:166 +#: lib/mv_web/live/member_live/index.html.heex:163 #: lib/mv_web/live/member_live/show.ex:61 #, elixir-autogen, elixir-format msgid "Postal Code" @@ -165,7 +165,7 @@ msgid "Saving..." msgstr "Speichern..." #: lib/mv_web/live/member_live/form.ex:54 -#: lib/mv_web/live/member_live/index.html.heex:130 +#: lib/mv_web/live/member_live/index.html.heex:127 #: lib/mv_web/live/member_live/show.ex:59 #, elixir-autogen, elixir-format msgid "Street" @@ -176,7 +176,7 @@ msgstr "Straße" msgid "Id" msgstr "ID" -#: lib/mv_web/live/member_live/index.html.heex:234 +#: lib/mv_web/live/member_live/index.html.heex:231 #: lib/mv_web/live/member_live/index/formatter.ex:61 #: lib/mv_web/live/member_live/show.ex:52 #, elixir-autogen, elixir-format @@ -193,7 +193,7 @@ msgstr "Mitglied anzeigen" msgid "This is a member record from your database." msgstr "Dies ist ein Mitglied aus deiner Datenbank." -#: lib/mv_web/live/member_live/index.html.heex:234 +#: lib/mv_web/live/member_live/index.html.heex:231 #: lib/mv_web/live/member_live/index/formatter.ex:60 #: lib/mv_web/live/member_live/show.ex:52 #, elixir-autogen, elixir-format @@ -359,12 +359,12 @@ msgstr "Profil" msgid "Required" msgstr "Erforderlich" -#: lib/mv_web/live/member_live/index.html.heex:68 +#: lib/mv_web/live/member_live/index.html.heex:69 #, elixir-autogen, elixir-format msgid "Select all members" msgstr "Alle Mitglieder auswählen" -#: lib/mv_web/live/member_live/index.html.heex:82 +#: lib/mv_web/live/member_live/index.html.heex:79 #, elixir-autogen, elixir-format msgid "Select member" msgstr "Mitglied auswählen" @@ -566,7 +566,7 @@ msgstr "Benutzer*innen" msgid "Click to sort" msgstr "Klicke um zu sortieren" -#: lib/mv_web/live/member_live/index.html.heex:94 +#: lib/mv_web/live/member_live/index.html.heex:91 #, elixir-autogen, elixir-format msgid "First name" msgstr "Vorname" diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 1e0e954..58c2602 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -11,12 +11,12 @@ msgid "" msgstr "" -#: lib/mv_web/components/core_components.ex:386 +#: lib/mv_web/components/core_components.ex:387 #, elixir-autogen, elixir-format msgid "Actions" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:248 +#: lib/mv_web/live/member_live/index.html.heex:245 #: lib/mv_web/live/user_live/index.html.heex:72 #, elixir-autogen, elixir-format msgid "Are you sure?" @@ -29,19 +29,19 @@ msgid "Attempting to reconnect" msgstr "" #: lib/mv_web/live/member_live/form.ex:53 -#: lib/mv_web/live/member_live/index.html.heex:184 +#: lib/mv_web/live/member_live/index.html.heex:181 #: lib/mv_web/live/member_live/show.ex:58 #, elixir-autogen, elixir-format msgid "City" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:250 +#: lib/mv_web/live/member_live/index.html.heex:247 #: lib/mv_web/live/user_live/index.html.heex:74 #, elixir-autogen, elixir-format msgid "Delete" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:242 +#: lib/mv_web/live/member_live/index.html.heex:239 #: lib/mv_web/live/user_live/form.ex:265 #: lib/mv_web/live/user_live/index.html.heex:66 #, elixir-autogen, elixir-format @@ -55,7 +55,7 @@ msgid "Edit Member" msgstr "" #: lib/mv_web/live/member_live/form.ex:47 -#: lib/mv_web/live/member_live/index.html.heex:112 +#: lib/mv_web/live/member_live/index.html.heex:109 #: lib/mv_web/live/member_live/show.ex:50 #: lib/mv_web/live/user_live/form.ex:46 #: lib/mv_web/live/user_live/index.html.heex:44 @@ -71,7 +71,7 @@ msgid "First Name" msgstr "" #: lib/mv_web/live/member_live/form.ex:50 -#: lib/mv_web/live/member_live/index.html.heex:220 +#: lib/mv_web/live/member_live/index.html.heex:217 #: lib/mv_web/live/member_live/show.ex:55 #, elixir-autogen, elixir-format msgid "Join Date" @@ -88,7 +88,7 @@ msgstr "" msgid "New Member" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:239 +#: lib/mv_web/live/member_live/index.html.heex:236 #: lib/mv_web/live/user_live/index.html.heex:63 #, elixir-autogen, elixir-format msgid "Show" @@ -116,7 +116,7 @@ msgid "Exit Date" msgstr "" #: lib/mv_web/live/member_live/form.ex:55 -#: lib/mv_web/live/member_live/index.html.heex:148 +#: lib/mv_web/live/member_live/index.html.heex:145 #: lib/mv_web/live/member_live/show.ex:60 #, elixir-autogen, elixir-format msgid "House Number" @@ -131,21 +131,21 @@ msgstr "" #: lib/mv_web/live/components/payment_filter_component.ex:94 #: lib/mv_web/live/components/payment_filter_component.ex:144 #: lib/mv_web/live/member_live/form.ex:48 -#: lib/mv_web/live/member_live/index.html.heex:229 +#: lib/mv_web/live/member_live/index.html.heex:226 #: lib/mv_web/live/member_live/show.ex:51 #, elixir-autogen, elixir-format msgid "Paid" msgstr "" #: lib/mv_web/live/member_live/form.ex:49 -#: lib/mv_web/live/member_live/index.html.heex:202 +#: lib/mv_web/live/member_live/index.html.heex:199 #: lib/mv_web/live/member_live/show.ex:54 #, elixir-autogen, elixir-format msgid "Phone Number" msgstr "" #: lib/mv_web/live/member_live/form.ex:56 -#: lib/mv_web/live/member_live/index.html.heex:166 +#: lib/mv_web/live/member_live/index.html.heex:163 #: lib/mv_web/live/member_live/show.ex:61 #, elixir-autogen, elixir-format msgid "Postal Code" @@ -166,7 +166,7 @@ msgid "Saving..." msgstr "" #: lib/mv_web/live/member_live/form.ex:54 -#: lib/mv_web/live/member_live/index.html.heex:130 +#: lib/mv_web/live/member_live/index.html.heex:127 #: lib/mv_web/live/member_live/show.ex:59 #, elixir-autogen, elixir-format msgid "Street" @@ -177,7 +177,7 @@ msgstr "" msgid "Id" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:234 +#: lib/mv_web/live/member_live/index.html.heex:231 #: lib/mv_web/live/member_live/index/formatter.ex:61 #: lib/mv_web/live/member_live/show.ex:52 #, elixir-autogen, elixir-format @@ -194,7 +194,7 @@ msgstr "" msgid "This is a member record from your database." msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:234 +#: lib/mv_web/live/member_live/index.html.heex:231 #: lib/mv_web/live/member_live/index/formatter.ex:60 #: lib/mv_web/live/member_live/show.ex:52 #, elixir-autogen, elixir-format @@ -360,12 +360,12 @@ msgstr "" msgid "Required" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:68 +#: lib/mv_web/live/member_live/index.html.heex:69 #, elixir-autogen, elixir-format msgid "Select all members" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:82 +#: lib/mv_web/live/member_live/index.html.heex:79 #, elixir-autogen, elixir-format msgid "Select member" msgstr "" @@ -567,7 +567,7 @@ msgstr "" msgid "Click to sort" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:94 +#: lib/mv_web/live/member_live/index.html.heex:91 #, elixir-autogen, elixir-format msgid "First name" msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index 319bcc3..00b269c 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -11,12 +11,12 @@ msgstr "" "Language: en\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: lib/mv_web/components/core_components.ex:386 +#: lib/mv_web/components/core_components.ex:387 #, elixir-autogen, elixir-format msgid "Actions" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:248 +#: lib/mv_web/live/member_live/index.html.heex:245 #: lib/mv_web/live/user_live/index.html.heex:72 #, elixir-autogen, elixir-format msgid "Are you sure?" @@ -29,19 +29,19 @@ msgid "Attempting to reconnect" msgstr "" #: lib/mv_web/live/member_live/form.ex:53 -#: lib/mv_web/live/member_live/index.html.heex:184 +#: lib/mv_web/live/member_live/index.html.heex:181 #: lib/mv_web/live/member_live/show.ex:58 #, elixir-autogen, elixir-format msgid "City" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:250 +#: lib/mv_web/live/member_live/index.html.heex:247 #: lib/mv_web/live/user_live/index.html.heex:74 #, elixir-autogen, elixir-format msgid "Delete" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:242 +#: lib/mv_web/live/member_live/index.html.heex:239 #: lib/mv_web/live/user_live/form.ex:265 #: lib/mv_web/live/user_live/index.html.heex:66 #, elixir-autogen, elixir-format @@ -55,7 +55,7 @@ msgid "Edit Member" msgstr "" #: lib/mv_web/live/member_live/form.ex:47 -#: lib/mv_web/live/member_live/index.html.heex:112 +#: lib/mv_web/live/member_live/index.html.heex:109 #: lib/mv_web/live/member_live/show.ex:50 #: lib/mv_web/live/user_live/form.ex:46 #: lib/mv_web/live/user_live/index.html.heex:44 @@ -71,7 +71,7 @@ msgid "First Name" msgstr "" #: lib/mv_web/live/member_live/form.ex:50 -#: lib/mv_web/live/member_live/index.html.heex:220 +#: lib/mv_web/live/member_live/index.html.heex:217 #: lib/mv_web/live/member_live/show.ex:55 #, elixir-autogen, elixir-format msgid "Join Date" @@ -88,7 +88,7 @@ msgstr "" msgid "New Member" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:239 +#: lib/mv_web/live/member_live/index.html.heex:236 #: lib/mv_web/live/user_live/index.html.heex:63 #, elixir-autogen, elixir-format msgid "Show" @@ -116,7 +116,7 @@ msgid "Exit Date" msgstr "" #: lib/mv_web/live/member_live/form.ex:55 -#: lib/mv_web/live/member_live/index.html.heex:148 +#: lib/mv_web/live/member_live/index.html.heex:145 #: lib/mv_web/live/member_live/show.ex:60 #, elixir-autogen, elixir-format msgid "House Number" @@ -131,21 +131,21 @@ msgstr "" #: lib/mv_web/live/components/payment_filter_component.ex:94 #: lib/mv_web/live/components/payment_filter_component.ex:144 #: lib/mv_web/live/member_live/form.ex:48 -#: lib/mv_web/live/member_live/index.html.heex:229 +#: lib/mv_web/live/member_live/index.html.heex:226 #: lib/mv_web/live/member_live/show.ex:51 #, elixir-autogen, elixir-format msgid "Paid" msgstr "" #: lib/mv_web/live/member_live/form.ex:49 -#: lib/mv_web/live/member_live/index.html.heex:202 +#: lib/mv_web/live/member_live/index.html.heex:199 #: lib/mv_web/live/member_live/show.ex:54 #, elixir-autogen, elixir-format msgid "Phone Number" msgstr "" #: lib/mv_web/live/member_live/form.ex:56 -#: lib/mv_web/live/member_live/index.html.heex:166 +#: lib/mv_web/live/member_live/index.html.heex:163 #: lib/mv_web/live/member_live/show.ex:61 #, elixir-autogen, elixir-format msgid "Postal Code" @@ -166,7 +166,7 @@ msgid "Saving..." msgstr "" #: lib/mv_web/live/member_live/form.ex:54 -#: lib/mv_web/live/member_live/index.html.heex:130 +#: lib/mv_web/live/member_live/index.html.heex:127 #: lib/mv_web/live/member_live/show.ex:59 #, elixir-autogen, elixir-format msgid "Street" @@ -177,7 +177,7 @@ msgstr "" msgid "Id" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:234 +#: lib/mv_web/live/member_live/index.html.heex:231 #: lib/mv_web/live/member_live/index/formatter.ex:61 #: lib/mv_web/live/member_live/show.ex:52 #, elixir-autogen, elixir-format @@ -194,7 +194,7 @@ msgstr "" msgid "This is a member record from your database." msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:234 +#: lib/mv_web/live/member_live/index.html.heex:231 #: lib/mv_web/live/member_live/index/formatter.ex:60 #: lib/mv_web/live/member_live/show.ex:52 #, elixir-autogen, elixir-format @@ -360,12 +360,12 @@ msgstr "" msgid "Required" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:68 +#: lib/mv_web/live/member_live/index.html.heex:69 #, elixir-autogen, elixir-format msgid "Select all members" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:82 +#: lib/mv_web/live/member_live/index.html.heex:79 #, elixir-autogen, elixir-format msgid "Select member" msgstr "" @@ -567,7 +567,7 @@ msgstr "" msgid "Click to sort" msgstr "" -#: lib/mv_web/live/member_live/index.html.heex:94 +#: lib/mv_web/live/member_live/index.html.heex:91 #, elixir-autogen, elixir-format, fuzzy msgid "First name" msgstr "" From 6b0ec28d9b5f6c018aec21b3840157d7e62b929a Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 3 Dec 2025 14:34:31 +0100 Subject: [PATCH 2/4] fix checkbox tests --- test/mv_web/member_live/index_test.exs | 52 ++++++++------------------ 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/test/mv_web/member_live/index_test.exs b/test/mv_web/member_live/index_test.exs index 0bcc731..9e3323f 100644 --- a/test/mv_web/member_live/index_test.exs +++ b/test/mv_web/member_live/index_test.exs @@ -285,14 +285,9 @@ defmodule MvWeb.MemberLive.IndexTest do conn = conn_with_oidc_user(conn) {:ok, view, _html} = live(conn, "/members") - # Select two members - view - |> element("[phx-click='select_member'][phx-value-id='#{member1.id}']") - |> render_click() - - view - |> element("[phx-click='select_member'][phx-value-id='#{member2.id}']") - |> render_click() + # Select two members by sending the select_member event directly + render_click(view, "select_member", %{"id" => member1.id}) + render_click(view, "select_member", %{"id" => member2.id}) # Trigger copy_emails event view |> element("#copy-emails-btn") |> render_click() @@ -336,10 +331,8 @@ defmodule MvWeb.MemberLive.IndexTest do conn = conn_with_oidc_user(conn) {:ok, view, _html} = live(conn, "/members") - # Select member with umlauts - view - |> element("[phx-click='select_member'][phx-value-id='#{member3.id}']") - |> render_click() + # Select member with umlauts by sending the select_member event directly + render_click(view, "select_member", %{"id" => member3.id}) # Trigger copy_emails event - should not crash view |> element("#copy-emails-btn") |> render_click() @@ -355,10 +348,8 @@ defmodule MvWeb.MemberLive.IndexTest do conn = conn_with_oidc_user(conn) {:ok, view, _html} = live(conn, "/members") - # Select a member - view - |> element("[phx-click='select_member'][phx-value-id='#{member1.id}']") - |> render_click() + # Select a member by sending the select_member event directly + render_click(view, "select_member", %{"id" => member1.id}) # Delete the member from the database Ash.destroy!(member1) @@ -379,14 +370,9 @@ defmodule MvWeb.MemberLive.IndexTest do conn = conn_with_oidc_user(conn) {:ok, view, _html} = live(conn, "/members") - # Select two members - view - |> element("[phx-click='select_member'][phx-value-id='#{member1.id}']") - |> render_click() - - view - |> element("[phx-click='select_member'][phx-value-id='#{member2.id}']") - |> render_click() + # Select two members by sending the select_member event directly + render_click(view, "select_member", %{"id" => member1.id}) + render_click(view, "select_member", %{"id" => member2.id}) # Get the socket state to verify the formatted email string state = :sys.get_state(view.pid) @@ -415,10 +401,8 @@ defmodule MvWeb.MemberLive.IndexTest do {:ok, view, _html} = live(conn, "/members") - # Select the test member - view - |> element("[phx-click='select_member'][phx-value-id='#{test_member.id}']") - |> render_click() + # Select the test member by sending the select_member event directly + render_click(view, "select_member", %{"id" => test_member.id}) # The format should be "Test Format " # We verify this by checking the flash shows 1 email was copied @@ -441,10 +425,8 @@ defmodule MvWeb.MemberLive.IndexTest do conn = conn_with_oidc_user(conn) {:ok, view, _html} = live(conn, "/members") - # Select a member - view - |> element("[phx-click='select_member'][phx-value-id='#{member1.id}']") - |> render_click() + # Select a member by sending the select_member event directly + render_click(view, "select_member", %{"id" => member1.id}) # Button should now be visible assert has_element?(view, "#copy-emails-btn") @@ -457,10 +439,8 @@ defmodule MvWeb.MemberLive.IndexTest do conn = conn_with_oidc_user(conn) {:ok, view, _html} = live(conn, "/members") - # Select a member - view - |> element("[phx-click='select_member'][phx-value-id='#{member1.id}']") - |> render_click() + # Select a member by sending the select_member event directly + render_click(view, "select_member", %{"id" => member1.id}) # Click copy button view |> element("#copy-emails-btn") |> render_click() From c3e95ca71171c673788c5d920a8004c137609261 Mon Sep 17 00:00:00 2001 From: carla Date: Mon, 8 Dec 2025 11:51:45 +0100 Subject: [PATCH 3/4] formatting --- lib/mv_web/components/core_components.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mv_web/components/core_components.ex b/lib/mv_web/components/core_components.ex index bee2d2a..d19b1eb 100644 --- a/lib/mv_web/components/core_components.ex +++ b/lib/mv_web/components/core_components.ex @@ -511,9 +511,9 @@ defmodule MvWeb.CoreComponents do {render_slot(col, @row_item.(row))} From 280f02460213e3f4504f05025d7cd1943d69292d Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 4 Dec 2025 18:02:47 +0100 Subject: [PATCH 4/4] run migrations via entrypoint script --- Dockerfile | 2 +- README.md | 2 +- rel/overlays/bin/docker-entrypoint.sh | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100755 rel/overlays/bin/docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 88468a2..7a01d21 100644 --- a/Dockerfile +++ b/Dockerfile @@ -90,4 +90,4 @@ USER nobody # above and adding an entrypoint. See https://github.com/krallin/tini for details # ENTRYPOINT ["/tini", "--"] -CMD ["/app/bin/server"] +ENTRYPOINT ["/app/bin/docker-entrypoint.sh"] diff --git a/README.md b/README.md index 090f4e9..6255f8d 100644 --- a/README.md +++ b/README.md @@ -255,7 +255,7 @@ For testing the production Docker build locally: docker compose -f docker-compose.prod.yml up ``` -5. **Run database migrations:** +5. **Database migrations run automatically** on app start. For manual migration: ```bash docker compose -f docker-compose.prod.yml exec app /app/bin/mv eval "Mv.Release.migrate" ``` diff --git a/rel/overlays/bin/docker-entrypoint.sh b/rel/overlays/bin/docker-entrypoint.sh new file mode 100755 index 0000000..d6b0dd7 --- /dev/null +++ b/rel/overlays/bin/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +echo "==> Running database migrations..." +/app/bin/migrate + +echo "==> Starting application..." +exec /app/bin/server +