Enable universal navigation
This commit is contained in:
@@ -159,6 +159,45 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Renders a search result item for navigation links.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<.search_result_navigation label="Collection" icon="hero-circle-stack" />
|
||||||
|
"""
|
||||||
|
attr :label, :string, required: true
|
||||||
|
attr :icon, :string, required: true
|
||||||
|
attr :rest, :global, include: ~w(phx-click phx-value-path)
|
||||||
|
|
||||||
|
def search_result_navigation(assigns) do
|
||||||
|
~H"""
|
||||||
|
<div
|
||||||
|
class={[
|
||||||
|
"p-3 rounded-lg cursor-pointer transition-colors",
|
||||||
|
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
||||||
|
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
||||||
|
]}
|
||||||
|
role="option"
|
||||||
|
{@rest}
|
||||||
|
>
|
||||||
|
<div class="flex items-center space-x-3">
|
||||||
|
<div class="shrink-0 w-8 h-8 rounded-md bg-zinc-100 dark:bg-zinc-700 flex items-center justify-center">
|
||||||
|
<.icon name={@icon} class="h-4 w-4 text-zinc-500 dark:text-zinc-400" />
|
||||||
|
</div>
|
||||||
|
<div class="min-w-0 flex-1">
|
||||||
|
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
|
{@label}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<span class="text-xs text-zinc-400 dark:text-zinc-500">
|
||||||
|
{gettext("Go to →")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Renders a search result group with a title and items.
|
Renders a search result group with a title and items.
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,20 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do
|
|||||||
<.no_results :if={@search_query != "" and @total_results == 0} query={@search_query} />
|
<.no_results :if={@search_query != "" and @total_results == 0} query={@search_query} />
|
||||||
|
|
||||||
<div :if={@total_results > 0} class="max-h-148 md:max-h-164 overflow-y-auto mt-4">
|
<div :if={@total_results > 0} class="max-h-148 md:max-h-164 overflow-y-auto mt-4">
|
||||||
|
<.search_result_group
|
||||||
|
:if={length(@navigation_links_results) > 0}
|
||||||
|
title={gettext("Go to")}
|
||||||
|
count={length(@navigation_links_results)}
|
||||||
|
>
|
||||||
|
<.search_result_navigation
|
||||||
|
:for={link <- @navigation_links_results}
|
||||||
|
label={link.label}
|
||||||
|
icon={link.icon}
|
||||||
|
phx-click="navigate_to_link"
|
||||||
|
phx-value-path={link.path}
|
||||||
|
phx-target={@myself}
|
||||||
|
/>
|
||||||
|
</.search_result_group>
|
||||||
<.search_result_group
|
<.search_result_group
|
||||||
:if={length(@search_results.artists) > 0}
|
:if={length(@search_results.artists) > 0}
|
||||||
title="Artists"
|
title="Artists"
|
||||||
@@ -206,9 +220,11 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do
|
|||||||
query ->
|
query ->
|
||||||
search_results = Search.universal_search(query, limit: 5)
|
search_results = Search.universal_search(query, limit: 5)
|
||||||
search_counts = Search.search_counts(query)
|
search_counts = Search.search_counts(query)
|
||||||
|
navigation_links_results = filter_navigation_links(query)
|
||||||
|
|
||||||
total_results =
|
total_results =
|
||||||
length(search_results.collection) +
|
length(navigation_links_results) +
|
||||||
|
length(search_results.collection) +
|
||||||
length(search_results.wishlist) +
|
length(search_results.wishlist) +
|
||||||
length(search_results.artists) +
|
length(search_results.artists) +
|
||||||
length(search_results.record_sets)
|
length(search_results.record_sets)
|
||||||
@@ -218,6 +234,7 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do
|
|||||||
|> assign(:search_query, query)
|
|> assign(:search_query, query)
|
||||||
|> assign(:search_results, search_results)
|
|> assign(:search_results, search_results)
|
||||||
|> assign(:search_counts, search_counts)
|
|> assign(:search_counts, search_counts)
|
||||||
|
|> assign(:navigation_links_results, navigation_links_results)
|
||||||
|> assign(:total_results, total_results)}
|
|> assign(:total_results, total_results)}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -293,6 +310,14 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do
|
|||||||
|> push_navigate(to: ~p"/record-sets?query=#{query}")}
|
|> push_navigate(to: ~p"/record-sets?query=#{query}")}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event("navigate_to_link", %{"path" => path}, socket) do
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> assign(:show_modal, false)
|
||||||
|
|> push_navigate(to: path)}
|
||||||
|
end
|
||||||
|
|
||||||
defp reset(socket) do
|
defp reset(socket) do
|
||||||
socket
|
socket
|
||||||
|> assign(:search_query, "")
|
|> assign(:search_query, "")
|
||||||
@@ -303,6 +328,87 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do
|
|||||||
artists_count: 0,
|
artists_count: 0,
|
||||||
record_sets_count: 0
|
record_sets_count: 0
|
||||||
})
|
})
|
||||||
|
|> assign(:navigation_links_results, [])
|
||||||
|> assign(:total_results, 0)
|
|> assign(:total_results, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp filter_navigation_links(query) do
|
||||||
|
downcased = String.downcase(query)
|
||||||
|
|
||||||
|
Enum.filter(navigation_links(), fn link ->
|
||||||
|
String.contains?(String.downcase(link.label), downcased) or
|
||||||
|
Enum.any?(link.keywords, &String.contains?(&1, downcased))
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp navigation_links do
|
||||||
|
[
|
||||||
|
%{
|
||||||
|
label: "Stats",
|
||||||
|
path: ~p"/",
|
||||||
|
icon: "hero-chart-pie",
|
||||||
|
keywords: ["stats", "dashboard", "home"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Collection",
|
||||||
|
path: ~p"/collection",
|
||||||
|
icon: "hero-circle-stack",
|
||||||
|
keywords: ["collection", "collected", "records"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Wishlist",
|
||||||
|
path: ~p"/wishlist",
|
||||||
|
icon: "hero-star",
|
||||||
|
keywords: ["wishlist", "wish", "want"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Sets",
|
||||||
|
path: ~p"/record-sets",
|
||||||
|
icon: "hero-rectangle-stack",
|
||||||
|
keywords: ["sets", "record sets", "groups"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Scrobble Anything",
|
||||||
|
path: ~p"/scrobble",
|
||||||
|
icon: "hero-play",
|
||||||
|
keywords: ["scrobble", "play"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Scrobbled Tracks",
|
||||||
|
path: ~p"/scrobbled-tracks",
|
||||||
|
icon: "hero-musical-note",
|
||||||
|
keywords: ["scrobbled", "tracks", "history", "listening"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Scrobble Rules",
|
||||||
|
path: ~p"/scrobble-rules",
|
||||||
|
icon: "hero-adjustments-horizontal",
|
||||||
|
keywords: ["scrobble rules", "rules", "remap"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Online Store Templates",
|
||||||
|
path: ~p"/online-store-templates",
|
||||||
|
icon: "hero-building-storefront",
|
||||||
|
keywords: ["store", "templates", "online", "buy"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Live Dashboard",
|
||||||
|
path: ~p"/dev/dashboard",
|
||||||
|
icon: "hero-chart-bar",
|
||||||
|
keywords: ["live dashboard", "telemetry", "metrics"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Oban",
|
||||||
|
path: ~p"/dev/oban",
|
||||||
|
icon: "hero-cog",
|
||||||
|
keywords: ["oban", "jobs", "workers", "queue"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
label: "Maintenance",
|
||||||
|
path: ~p"/dev/maintenance",
|
||||||
|
icon: "hero-wrench-screwdriver",
|
||||||
|
keywords: ["maintenance", "admin", "vacuum"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2021,3 +2021,13 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Wikipedia"
|
msgid "Wikipedia"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/universal_search_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Go to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Go to →"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -2021,3 +2021,13 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Wikipedia"
|
msgid "Wikipedia"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/universal_search_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Go to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Go to →"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
Reference in New Issue
Block a user