Enable sorting options in collection view

This commit is contained in:
Claudio Ortolina
2024-12-29 15:47:37 +00:00
parent 1534d28c9e
commit 6427710029
8 changed files with 59 additions and 32 deletions
+2 -1
View File
@@ -8,8 +8,9 @@ defmodule MusicLibrary.Collection do
def search_records(query, opts \\ []) do def search_records(query, opts \\ []) do
limit = Keyword.get(opts, :limit, 20) limit = Keyword.get(opts, :limit, 20)
offset = Keyword.get(opts, :offset, 0) offset = Keyword.get(opts, :offset, 0)
order = Keyword.get(opts, :order, :alphabetical)
Records.search_records(base_search(), query, limit: limit, offset: offset) Records.search_records(base_search(), query, limit: limit, offset: offset, order: order)
end end
def search_records_count(query) do def search_records_count(query) do
+10 -2
View File
@@ -28,10 +28,11 @@ defmodule MusicLibrary.Records do
def search_records(initial_search, query, opts) do def search_records(initial_search, query, opts) do
limit = Keyword.fetch!(opts, :limit) limit = Keyword.fetch!(opts, :limit)
offset = Keyword.fetch!(opts, :offset) offset = Keyword.fetch!(opts, :offset)
order = Keyword.fetch!(opts, :order)
search = search =
initial_search initial_search
|> build_search(query) |> build_search(query, order)
|> limit(^limit) |> limit(^limit)
|> offset(^offset) |> offset(^offset)
|> select(^essential_fields()) |> select(^essential_fields())
@@ -45,10 +46,12 @@ defmodule MusicLibrary.Records do
Repo.aggregate(search, :count) Repo.aggregate(search, :count)
end end
defp build_search(initial_search, query) do defp build_search(initial_search, query, order \\ :alphabetical) do
{:ok, parsed_query} = SearchParser.parse(query) {:ok, parsed_query} = SearchParser.parse(query)
search_with_order = search_with_order =
case order do
:alphabetical ->
initial_search initial_search
|> order_by( |> order_by(
fragment( fragment(
@@ -56,6 +59,11 @@ defmodule MusicLibrary.Records do
) )
) )
:purchase ->
initial_search
|> order_by([r], {:desc, r.purchased_at})
end
Enum.reduce(parsed_query, search_with_order, fn Enum.reduce(parsed_query, search_with_order, fn
{:artist, artist}, search -> {:artist, artist}, search ->
search search
+2 -1
View File
@@ -8,8 +8,9 @@ defmodule MusicLibrary.Wishlist do
def search_records(query, opts \\ []) do def search_records(query, opts \\ []) do
limit = Keyword.get(opts, :limit, 20) limit = Keyword.get(opts, :limit, 20)
offset = Keyword.get(opts, :offset, 0) offset = Keyword.get(opts, :offset, 0)
order = Keyword.get(opts, :order, :alphabetical)
Records.search_records(base_search(), query, limit: limit, offset: offset) Records.search_records(base_search(), query, limit: limit, offset: offset, order: order)
end end
def search_records_count(query) do def search_records_count(query) do
+13 -5
View File
@@ -25,7 +25,7 @@ defmodule MusicLibraryWeb.Pagination do
]}> ]}>
<.link <.link
:if={@page_links.prev_page} :if={@page_links.prev_page}
patch={"?" <> encode_query(page: @page_links.prev_page, page_size: @pagination_params.page_size, query: @pagination_params.query)} patch={"?" <> encode_query(page: @page_links.prev_page, page_size: @pagination_params.page_size, query: @pagination_params.query, order: @pagination_params.order)}
phx-click={JS.dispatch("music_library:scroll_top")} phx-click={JS.dispatch("music_library:scroll_top")}
class={[ class={[
"relative inline-flex items-center rounded-md border", "relative inline-flex items-center rounded-md border",
@@ -39,7 +39,7 @@ defmodule MusicLibraryWeb.Pagination do
</.link> </.link>
<.link <.link
:if={@page_links.next_page} :if={@page_links.next_page}
patch={"?" <> encode_query(page: @page_links.next_page, page_size: @pagination_params.page_size, query: @pagination_params.query)} patch={"?" <> encode_query(page: @page_links.next_page, page_size: @pagination_params.page_size, query: @pagination_params.query, order: @pagination_params.order)}
phx-click={JS.dispatch("music_library:scroll_top")} phx-click={JS.dispatch("music_library:scroll_top")}
class={[ class={[
"relative ml-3 inline-flex items-center rounded-md border", "relative ml-3 inline-flex items-center rounded-md border",
@@ -60,12 +60,14 @@ defmodule MusicLibraryWeb.Pagination do
page_number={@page_links.prev_page} page_number={@page_links.prev_page}
page_size={@pagination_params.page_size} page_size={@pagination_params.page_size}
query={@pagination_params.query} query={@pagination_params.query}
order={@pagination_params.order}
/> />
<.numbered_link <.numbered_link
:for={page_number <- @page_links.visible_left_pages} :for={page_number <- @page_links.visible_left_pages}
page_number={page_number} page_number={page_number}
page_size={@pagination_params.page_size} page_size={@pagination_params.page_size}
query={@pagination_params.query} query={@pagination_params.query}
order={@pagination_params.order}
/> />
<.separator :if={@page_links.left_separator} /> <.separator :if={@page_links.left_separator} />
<.numbered_link <.numbered_link
@@ -74,6 +76,7 @@ defmodule MusicLibraryWeb.Pagination do
active={page_number == @pagination_params.page} active={page_number == @pagination_params.page}
page_size={@pagination_params.page_size} page_size={@pagination_params.page_size}
query={@pagination_params.query} query={@pagination_params.query}
order={@pagination_params.order}
/> />
<.separator :if={@page_links.right_separator} /> <.separator :if={@page_links.right_separator} />
<.numbered_link <.numbered_link
@@ -81,12 +84,14 @@ defmodule MusicLibraryWeb.Pagination do
page_number={page_number} page_number={page_number}
page_size={@pagination_params.page_size} page_size={@pagination_params.page_size}
query={@pagination_params.query} query={@pagination_params.query}
order={@pagination_params.order}
/> />
<.next_link <.next_link
:if={@page_links.next_page} :if={@page_links.next_page}
page_number={@page_links.next_page} page_number={@page_links.next_page}
page_size={@pagination_params.page_size} page_size={@pagination_params.page_size}
query={@pagination_params.query} query={@pagination_params.query}
order={@pagination_params.order}
/> />
</nav> </nav>
</div> </div>
@@ -102,6 +107,7 @@ defmodule MusicLibraryWeb.Pagination do
attr :page_number, :integer, required: true attr :page_number, :integer, required: true
attr :page_size, :integer, required: true attr :page_size, :integer, required: true
attr :query, :string, required: true attr :query, :string, required: true
attr :order, :atom, required: true
defp next_link(assigns) do defp next_link(assigns) do
~H""" ~H"""
@@ -111,7 +117,7 @@ defmodule MusicLibraryWeb.Pagination do
"text-zinc-400 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 focus:z-20 focus:outline-offset-0" "text-zinc-400 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 focus:z-20 focus:outline-offset-0"
]} ]}
phx-click={JS.dispatch("music_library:scroll_top")} phx-click={JS.dispatch("music_library:scroll_top")}
patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query)} patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query, order: @order)}
> >
<span class="sr-only">{gettext("Next")}</span> <span class="sr-only">{gettext("Next")}</span>
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
@@ -128,13 +134,14 @@ defmodule MusicLibraryWeb.Pagination do
attr :page_number, :integer, required: true attr :page_number, :integer, required: true
attr :page_size, :integer, required: true attr :page_size, :integer, required: true
attr :query, :string, required: true attr :query, :string, required: true
attr :order, :atom, required: true
defp prev_link(assigns) do defp prev_link(assigns) do
~H""" ~H"""
<.link <.link
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-zinc-400 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 focus:z-20 focus:outline-offset-0" class="relative inline-flex items-center rounded-l-md px-2 py-2 text-zinc-400 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 focus:z-20 focus:outline-offset-0"
phx-click={JS.dispatch("music_library:scroll_top")} phx-click={JS.dispatch("music_library:scroll_top")}
patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query)} patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query, order: @order)}
> >
<span class="sr-only">{gettext("Previous")}</span> <span class="sr-only">{gettext("Previous")}</span>
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
@@ -160,6 +167,7 @@ defmodule MusicLibraryWeb.Pagination do
attr :page_size, :integer, required: true attr :page_size, :integer, required: true
attr :active, :boolean, default: false attr :active, :boolean, default: false
attr :query, :string, required: true attr :query, :string, required: true
attr :order, :atom, required: true
defp numbered_link(assigns) when assigns.active do defp numbered_link(assigns) when assigns.active do
~H""" ~H"""
@@ -174,7 +182,7 @@ defmodule MusicLibraryWeb.Pagination do
<.link <.link
class="relative hidden items-center first:rounded-l-md last:rounded-r-md px-4 py-2 text-sm font-semibold text-zinc-900 dark:text-zinc-400 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-300 hover:text-zinc-500 focus:z-20 focus:outline-offset-0 md:inline-flex" class="relative hidden items-center first:rounded-l-md last:rounded-r-md px-4 py-2 text-sm font-semibold text-zinc-900 dark:text-zinc-400 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-300 hover:text-zinc-500 focus:z-20 focus:outline-offset-0 md:inline-flex"
phx-click={JS.dispatch("music_library:scroll_top")} phx-click={JS.dispatch("music_library:scroll_top")}
patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query)} patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query, order: @order)}
> >
{@page_number} {@page_number}
</.link> </.link>
@@ -74,8 +74,10 @@ defmodule MusicLibraryWeb.CollectionLive.Index do
offset = page_to_offset(record_list_params.page, record_list_params.page_size) offset = page_to_offset(record_list_params.page, record_list_params.page_size)
opts = [limit: record_list_params.page_size, offset: offset, order: parse_order(order)]
records = records =
Collection.search_records(query, limit: record_list_params.page_size, offset: offset) Collection.search_records(query, opts)
socket socket
|> assign(:page_title, gettext("Collection")) |> assign(:page_title, gettext("Collection"))
@@ -166,7 +168,7 @@ defmodule MusicLibraryWeb.CollectionLive.Index do
defp order_path(record_list_params, order) do defp order_path(record_list_params, order) do
qs = qs =
record_list_params record_list_params
|> Map.take([:query, :page, :page_size]) |> Map.take([:query])
|> Map.put(:order, order) |> Map.put(:order, order)
|> Enum.filter(fn {_, v} -> v not in ["", nil] end) |> Enum.filter(fn {_, v} -> v not in ["", nil] end)
@@ -10,7 +10,8 @@ defmodule MusicLibraryWeb.WishlistLive.Index do
@default_records_list_params %{ @default_records_list_params %{
query: "", query: "",
page: 1, page: 1,
page_size: 20 page_size: 20,
order: :alphabetical
} }
@impl true @impl true
@@ -70,7 +71,13 @@ defmodule MusicLibraryWeb.WishlistLive.Index do
|> merge_pagination(params, total_records) |> merge_pagination(params, total_records)
offset = page_to_offset(record_list_params.page, record_list_params.page_size) offset = page_to_offset(record_list_params.page, record_list_params.page_size)
records = Wishlist.search_records(query, limit: record_list_params.page_size, offset: offset)
records =
Wishlist.search_records(query,
limit: record_list_params.page_size,
offset: offset,
order: record_list_params.order
)
socket socket
|> assign(:page_title, gettext("Wishlist")) |> assign(:page_title, gettext("Wishlist"))
+12 -12
View File
@@ -31,7 +31,7 @@ msgstr ""
#: lib/music_library_web/components/layouts/app.html.heex:14 #: lib/music_library_web/components/layouts/app.html.heex:14
#: lib/music_library_web/live/artist_live/show.html.heex:73 #: lib/music_library_web/live/artist_live/show.html.heex:73
#: lib/music_library_web/live/collection_live/index.ex:81 #: lib/music_library_web/live/collection_live/index.ex:83
#: lib/music_library_web/live/collection_live/show.ex:115 #: lib/music_library_web/live/collection_live/show.ex:115
#: lib/music_library_web/live/collection_live/show.ex:132 #: lib/music_library_web/live/collection_live/show.ex:132
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@@ -59,12 +59,12 @@ msgstr ""
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
#: lib/music_library_web/live/collection_live/index.ex:127 #: lib/music_library_web/live/collection_live/index.ex:129
#: lib/music_library_web/live/collection_live/index.ex:134 #: lib/music_library_web/live/collection_live/index.ex:136
#: lib/music_library_web/live/stats_live/index.ex:53 #: lib/music_library_web/live/stats_live/index.ex:53
#: lib/music_library_web/live/stats_live/index.ex:59 #: lib/music_library_web/live/stats_live/index.ex:59
#: lib/music_library_web/live/wishlist_live/index.ex:121
#: lib/music_library_web/live/wishlist_live/index.ex:128 #: lib/music_library_web/live/wishlist_live/index.ex:128
#: lib/music_library_web/live/wishlist_live/index.ex:135
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Error importing record" msgid "Error importing record"
msgstr "" msgstr ""
@@ -136,7 +136,7 @@ msgid "MusicBrainz ID"
msgstr "" msgstr ""
#: lib/music_library_web/components/pagination.ex:52 #: lib/music_library_web/components/pagination.ex:52
#: lib/music_library_web/components/pagination.ex:116 #: lib/music_library_web/components/pagination.ex:122
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Next" msgid "Next"
msgstr "" msgstr ""
@@ -164,7 +164,7 @@ msgid "Password"
msgstr "" msgstr ""
#: lib/music_library_web/components/pagination.ex:38 #: lib/music_library_web/components/pagination.ex:38
#: lib/music_library_web/components/pagination.ex:139 #: lib/music_library_web/components/pagination.ex:146
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Previous" msgid "Previous"
msgstr "" msgstr ""
@@ -186,15 +186,15 @@ msgstr ""
msgid "Purchased on" msgid "Purchased on"
msgstr "" msgstr ""
#: lib/music_library_web/live/collection_live/index.ex:119 #: lib/music_library_web/live/collection_live/index.ex:121
#: lib/music_library_web/live/stats_live/index.ex:45 #: lib/music_library_web/live/stats_live/index.ex:45
#: lib/music_library_web/live/wishlist_live/index.ex:113 #: lib/music_library_web/live/wishlist_live/index.ex:120
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Record imported successfully" msgid "Record imported successfully"
msgstr "" msgstr ""
#: lib/music_library_web/live/record_live/form_component.ex:123 #: lib/music_library_web/live/record_live/form_component.ex:123
#: lib/music_library_web/live/wishlist_live/index.ex:141 #: lib/music_library_web/live/wishlist_live/index.ex:148
#: lib/music_library_web/live/wishlist_live/show.ex:105 #: lib/music_library_web/live/wishlist_live/show.ex:105
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Record updated successfully" msgid "Record updated successfully"
@@ -261,7 +261,7 @@ msgstr ""
#: lib/music_library_web/live/collection_live/index.ex:21 #: lib/music_library_web/live/collection_live/index.ex:21
#: lib/music_library_web/live/collection_live/show.ex:12 #: lib/music_library_web/live/collection_live/show.ex:12
#: lib/music_library_web/live/wishlist_live/index.ex:20 #: lib/music_library_web/live/wishlist_live/index.ex:21
#: lib/music_library_web/live/wishlist_live/show.ex:10 #: lib/music_library_web/live/wishlist_live/show.ex:10
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "The application has been updated, please reload." msgid "The application has been updated, please reload."
@@ -305,7 +305,7 @@ msgstr ""
#: lib/music_library_web/components/layouts/app.html.heex:20 #: lib/music_library_web/components/layouts/app.html.heex:20
#: lib/music_library_web/live/artist_live/show.html.heex:128 #: lib/music_library_web/live/artist_live/show.html.heex:128
#: lib/music_library_web/live/wishlist_live/index.ex:76 #: lib/music_library_web/live/wishlist_live/index.ex:83
#: lib/music_library_web/live/wishlist_live/show.ex:129 #: lib/music_library_web/live/wishlist_live/show.ex:129
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Wishlist" msgid "Wishlist"
@@ -416,7 +416,7 @@ msgstr ""
msgid "Import from MusicBrainz · Collection" msgid "Import from MusicBrainz · Collection"
msgstr "" msgstr ""
#: lib/music_library_web/live/wishlist_live/index.ex:43 #: lib/music_library_web/live/wishlist_live/index.ex:44
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Import from MusicBrainz · Wishlist" msgid "Import from MusicBrainz · Wishlist"
msgstr "" msgstr ""
+1 -1
View File
@@ -27,7 +27,7 @@ defmodule MusicLibrary.RecordsTest do
# so we rely on record ids to compare results # so we rely on record ids to compare results
defp search(query, limit, offset) do defp search(query, limit, offset) do
SearchIndex SearchIndex
|> Records.search_records(query, limit: limit, offset: offset) |> Records.search_records(query, limit: limit, offset: offset, order: :alphabetical)
|> Enum.map(& &1.id) |> Enum.map(& &1.id)
end end