diff --git a/lib/music_library_web/components/search_components.ex b/lib/music_library_web/components/search_components.ex index 1b3da113..d9501a1d 100644 --- a/lib/music_library_web/components/search_components.ex +++ b/lib/music_library_web/components/search_components.ex @@ -168,7 +168,7 @@ defmodule MusicLibraryWeb.SearchComponents do """ attr :label, :string, required: true attr :icon, :string, required: true - attr :rest, :global, include: ~w(phx-click phx-value-path) + attr :rest, :global, include: ~w(phx-click phx-value-path phx-target) def search_result_navigation(assigns) do ~H""" @@ -273,18 +273,22 @@ defmodule MusicLibraryWeb.SearchComponents do <.results_footer /> """ attr :total_results, :integer, default: 0 + attr :has_navigable_items, :boolean, default: false def results_footer(assigns) do + assigns = + assign(assigns, :show_nav_hints, assigns.total_results > 0 or assigns.has_navigable_items) + ~H"""
-
0} class="flex items-center gap-1"> +
{gettext("Navigate")}
-
0} class="flex items-center gap-1"> +
Enter {gettext("Select")}
@@ -328,21 +332,39 @@ defmodule MusicLibraryWeb.SearchComponents do <.no_results query="radiohead" /> """ attr :query, :string, required: true + attr :target, :any, required: true def no_results(assigns) do ~H""" -
+
<.icon name="hero-face-frown" class="mx-auto mb-4 size-12 text-zinc-400" />

{gettext("No results found for '%{query}'", query: @query)}

- <.link - class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100" - navigate={~p"/wishlist/import?#{[import_query: @query]}"} - > - {gettext("Add a record instead", query: @query)} -
+ <.search_result_group title={gettext("Quick actions")} count={3}> + <.search_result_navigation + label={gettext("Add to wishlist")} + icon="hero-star" + phx-click="navigate_to_link" + phx-value-path={~p"/wishlist/import?#{[import_query: @query]}"} + phx-target={@target} + /> + <.search_result_navigation + label={gettext("Add to collection")} + icon="hero-plus-circle" + phx-click="navigate_to_link" + phx-value-path={~p"/collection/import?#{[import_query: @query]}"} + phx-target={@target} + /> + <.search_result_navigation + label={gettext("Search to scrobble")} + icon="hero-play" + phx-click="navigate_to_link" + phx-value-path={~p"/scrobble?#{[query: @query]}"} + phx-target={@target} + /> + """ end diff --git a/lib/music_library_web/live/collection_live/index.ex b/lib/music_library_web/live/collection_live/index.ex index 57673f4f..0423bd9c 100644 --- a/lib/music_library_web/live/collection_live/index.ex +++ b/lib/music_library_web/live/collection_live/index.ex @@ -169,7 +169,7 @@ defmodule MusicLibraryWeb.CollectionLive.Index do action={@live_action} record={@record} patch={back_path(@record_list_params)} - initial_query="" + initial_query={@import_query} icon_name="hero-plus" /> @@ -198,6 +198,7 @@ defmodule MusicLibraryWeb.CollectionLive.Index do {:ok, socket |> assign(:current_section, :collection) + |> assign(:import_query, "") |> assign(:display, :grid)} end @@ -207,9 +208,12 @@ defmodule MusicLibraryWeb.CollectionLive.Index do end defp apply_action(socket, :import, params) do + import_query = params["import_query"] || "" + socket |> apply_fallback_index(params, :records, &apply_action/3) |> assign(:page_title, gettext("Add new Record · Collection")) + |> assign(:import_query, import_query) |> assign(:record, nil) end diff --git a/lib/music_library_web/live/scrobble_live/index.ex b/lib/music_library_web/live/scrobble_live/index.ex index c3149f19..f25bbdb3 100644 --- a/lib/music_library_web/live/scrobble_live/index.ex +++ b/lib/music_library_web/live/scrobble_live/index.ex @@ -168,9 +168,20 @@ defmodule MusicLibraryWeb.ScrobbleLive.Index do {:noreply, apply_action(socket, socket.assigns.live_action, params)} end - defp apply_action(socket, :index, _params) do - socket - |> assign(:page_title, gettext("Scrobble")) + defp apply_action(socket, :index, params) do + query = params["query"] || "" + + socket = + socket + |> assign(:page_title, gettext("Scrobble")) + |> assign(:search_query, query) + + if String.trim(query) != "" do + send(self(), {:perform_search, query}) + assign(socket, :loading, true) + else + socket + end end @impl true 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 064b18c9..b683da04 100644 --- a/lib/music_library_web/live/universal_search_live/index.ex +++ b/lib/music_library_web/live/universal_search_live/index.ex @@ -36,7 +36,11 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do <.empty_state :if={@search_query == ""} /> - <.no_results :if={@search_query != "" and @total_results == 0} query={@search_query} /> + <.no_results + :if={@search_query != "" and @total_results == 0} + query={@search_query} + target={@myself} + />
0} class="mt-4 max-h-148 overflow-y-auto md:max-h-164"> <.search_result_group @@ -145,7 +149,10 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do /> - <.results_footer total_results={@total_results} /> + <.results_footer + total_results={@total_results} + has_navigable_items={@search_query != ""} + />
""" diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index dd9b8d64..b4e92833 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -1327,11 +1327,6 @@ msgstr "" msgid "Scrobble Anything" msgstr "" -#: lib/music_library_web/components/search_components.ex -#, elixir-autogen, elixir-format -msgid "Add a record instead" -msgstr "" - #: lib/music_library_web/components/stats_components.ex #, elixir-autogen, elixir-format msgid "Today" @@ -2345,3 +2340,23 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Re-connect to Last.fm" msgstr "" + +#: lib/music_library_web/components/search_components.ex +#, elixir-autogen, elixir-format +msgid "Add to collection" +msgstr "" + +#: lib/music_library_web/components/search_components.ex +#, elixir-autogen, elixir-format +msgid "Add to wishlist" +msgstr "" + +#: lib/music_library_web/components/search_components.ex +#, elixir-autogen, elixir-format +msgid "Quick actions" +msgstr "" + +#: lib/music_library_web/components/search_components.ex +#, elixir-autogen, elixir-format +msgid "Search to scrobble" +msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index a9bac115..0322473d 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -1327,11 +1327,6 @@ msgstr "" msgid "Scrobble Anything" msgstr "" -#: lib/music_library_web/components/search_components.ex -#, elixir-autogen, elixir-format -msgid "Add a record instead" -msgstr "" - #: lib/music_library_web/components/stats_components.ex #, elixir-autogen, elixir-format msgid "Today" @@ -2345,3 +2340,23 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Re-connect to Last.fm" msgstr "" + +#: lib/music_library_web/components/search_components.ex +#, elixir-autogen, elixir-format +msgid "Add to collection" +msgstr "" + +#: lib/music_library_web/components/search_components.ex +#, elixir-autogen, elixir-format, fuzzy +msgid "Add to wishlist" +msgstr "" + +#: lib/music_library_web/components/search_components.ex +#, elixir-autogen, elixir-format +msgid "Quick actions" +msgstr "" + +#: lib/music_library_web/components/search_components.ex +#, elixir-autogen, elixir-format +msgid "Search to scrobble" +msgstr "" diff --git a/test/music_library_web/live/collection_live/index_test.exs b/test/music_library_web/live/collection_live/index_test.exs index c8abaa00..512f495e 100644 --- a/test/music_library_web/live/collection_live/index_test.exs +++ b/test/music_library_web/live/collection_live/index_test.exs @@ -253,6 +253,16 @@ defmodule MusicLibraryWeb.CollectionLive.IndexTest do |> assert_path(~p"/collection/import") end + test "pre-fills the search query from import_query param", %{conn: conn} do + Req.Test.stub(MusicBrainz.API, fn conn -> + Req.Test.json(conn, %{"release-groups" => [], "count" => 0}) + end) + + conn + |> visit(~p"/collection/import?#{[import_query: "test query"]}") + |> assert_has("input[value='test query']") + end + test "imports a record when selected", %{conn: conn} do release_group_search_results = Map.get(release_group_search_results(), "release-groups") 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 2e0ef3fe..ef351624 100644 --- a/test/music_library_web/live/scrobble_live/index_test.exs +++ b/test/music_library_web/live/scrobble_live/index_test.exs @@ -51,6 +51,19 @@ defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do |> assert_has("a", "Connect your Last.fm account") end + test "pre-fills search and loads results from query param", %{conn: conn} do + session = visit(conn, ~p"/scrobble?#{[query: "marbles"]}") + + session + |> unwrap(fn view -> + # Process the {:perform_search, query} message + render(view) + end) + |> assert_has("input[value='marbles']") + |> assert_has("h3", "Release Groups") + |> assert_has("p", "Marbles") + end + test "search with results shows release groups", %{conn: conn} do session = visit(conn, ~p"/scrobble") 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 db9b9cbf..0cfa9b26 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 @@ -43,13 +43,20 @@ defmodule MusicLibraryWeb.UniversalSearchLive.IndexTest do end describe "Search functionality" do - test "shows no results message when query has no matches", %{conn: conn} do + test "shows no results message with quick action links when query has no matches", %{ + conn: conn + } do conn |> visit(~p"/collection") |> click_button("Search (Cmd/Ctrl+K)") |> fill_in("Universal Search", with: "nonexistent query xyz") |> assert_has("p", "No results found for 'nonexistent query xyz'") - |> assert_has("a", "Add a record instead") + |> assert_has("[role='option']", "Add to wishlist") + |> assert_has("[role='option']", "Add to collection") + |> assert_has("[role='option']", "Search to scrobble") + |> assert_has("kbd", "↑") + |> assert_has("kbd", "↓") + |> assert_has("span", "Navigate") end test "resets results when query is cleared", %{conn: conn} do