From 621b35d8245ea1f11a9c8568ac17e433ceea6538 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Thu, 7 May 2026 20:43:15 +0100 Subject: [PATCH] Open universal search modal instantly via client-side JS Replace phx-click server event with Fluxon.open_dialog for zero-latency modal opening. The modal DOM is now always present (no :if conditional) so it can be shown instantly; the server syncs state in the background. Fix test selectors that now match the always-present modal form by scoping to forms without phx-target (which the modal form always has). --- lib/music_library_web/live/universal_search_live/index.ex | 7 ++++--- .../live/online_store_template_live/index_test.exs | 2 +- test/music_library_web/live/scrobble_live/index_test.exs | 8 ++++---- .../live/scrobble_rules_live/index_test.exs | 2 +- .../live/scrobbled_tracks_live/index_test.exs | 2 +- .../live/universal_search_live/index_test.exs | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/music_library_web/live/universal_search_live/index.ex b/lib/music_library_web/live/universal_search_live/index.ex index 949a6e5e..1b1b0485 100644 --- a/lib/music_library_web/live/universal_search_live/index.ex +++ b/lib/music_library_web/live/universal_search_live/index.ex @@ -11,7 +11,6 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do ~H"""
<.structured_modal - :if={@show_modal} id="universal-search-root" open={@show_modal} on_close={JS.push("close_modal", value: %{}, target: "#universal-search")} @@ -184,8 +183,10 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do id="universal-search-button" variant="soft" title={gettext("Search (Cmd/Ctrl+K)")} - phx-click="open_modal" - phx-target="#universal-search" + phx-click={ + Fluxon.open_dialog("universal-search-root") + |> JS.push("open_modal", target: "#universal-search") + } phx-hook=".SearchGlobalShortcut" > {gettext("Search (Cmd/Ctrl+K)")} diff --git a/test/music_library_web/live/online_store_template_live/index_test.exs b/test/music_library_web/live/online_store_template_live/index_test.exs index 6bb4b81c..81ea5ecd 100644 --- a/test/music_library_web/live/online_store_template_live/index_test.exs +++ b/test/music_library_web/live/online_store_template_live/index_test.exs @@ -25,7 +25,7 @@ defmodule MusicLibraryWeb.OnlineStoreTemplateLive.IndexTest do assert has_element?(view, "p", "Bandcamp") view - |> form("form", query: "Amazon") + |> form("form:not([phx-target])", query: "Amazon") |> render_change() assert_patch(view, ~p"/online-store-templates?page=1&page_size=50&query=Amazon") diff --git a/test/music_library_web/live/scrobble_live/index_test.exs b/test/music_library_web/live/scrobble_live/index_test.exs index e16962ea..10760738 100644 --- a/test/music_library_web/live/scrobble_live/index_test.exs +++ b/test/music_library_web/live/scrobble_live/index_test.exs @@ -40,7 +40,7 @@ defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do test "renders search page with form", %{conn: conn} do conn |> visit(~p"/scrobble") - |> assert_has("form[phx-submit='search']") + |> assert_has("form[phx-submit='search']:not([phx-target])") end test "shows connect Last.fm button when not authenticated", %{conn: conn} do @@ -67,7 +67,7 @@ defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do session |> unwrap(fn view -> view - |> form("form[phx-submit='search']", %{query: "marbles"}) + |> form("form[phx-submit='search']:not([phx-target])", %{query: "marbles"}) |> render_submit() render(view) @@ -82,7 +82,7 @@ defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do session |> unwrap(fn view -> view - |> form("form[phx-submit='search']", %{query: ""}) + |> form("form[phx-submit='search']:not([phx-target])", %{query: ""}) |> render_submit() end) |> refute_has("h3", "Release Groups") @@ -108,7 +108,7 @@ defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do session |> unwrap(fn view -> view - |> form("form[phx-submit='search']", %{query: "nonexistent"}) + |> form("form[phx-submit='search']:not([phx-target])", %{query: "nonexistent"}) |> render_submit() render(view) diff --git a/test/music_library_web/live/scrobble_rules_live/index_test.exs b/test/music_library_web/live/scrobble_rules_live/index_test.exs index e566856b..b350a067 100644 --- a/test/music_library_web/live/scrobble_rules_live/index_test.exs +++ b/test/music_library_web/live/scrobble_rules_live/index_test.exs @@ -140,7 +140,7 @@ defmodule MusicLibraryWeb.ScrobbleRulesLiveTest do {:ok, index_live, _html} = live(conn, ~p"/scrobble-rules") index_live - |> form("form[phx-change='search']", query: scrobble_rule.match_value) + |> form("form[phx-change='search']:not([phx-target])", query: scrobble_rule.match_value) |> render_change() assert_patch(index_live) diff --git a/test/music_library_web/live/scrobbled_tracks_live/index_test.exs b/test/music_library_web/live/scrobbled_tracks_live/index_test.exs index c629e691..4b3ae4f5 100644 --- a/test/music_library_web/live/scrobbled_tracks_live/index_test.exs +++ b/test/music_library_web/live/scrobbled_tracks_live/index_test.exs @@ -56,7 +56,7 @@ defmodule MusicLibraryWeb.ScrobbledTracksLiveTest do session |> unwrap(fn view -> view - |> form("form[phx-submit='search']", %{query: "Unique Track"}) + |> form("form[phx-submit='search']:not([phx-target])", %{query: "Unique Track"}) |> render_submit() end) |> assert_has("p", "Unique Track Title") diff --git a/test/music_library_web/live/universal_search_live/index_test.exs b/test/music_library_web/live/universal_search_live/index_test.exs index 6344123c..f26f158c 100644 --- a/test/music_library_web/live/universal_search_live/index_test.exs +++ b/test/music_library_web/live/universal_search_live/index_test.exs @@ -23,7 +23,7 @@ defmodule MusicLibraryWeb.UniversalSearchLive.IndexTest do test "modal is hidden by default", %{conn: conn} do conn |> visit(~p"/collection") - |> refute_has("#universal-search-root") + |> assert_has("#universal-search-root[hidden]") end test "modal opens when search button is clicked", %{conn: conn} do