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
limit = Keyword.get(opts, :limit, 20)
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
def search_records_count(query) do
+16 -8
View File
@@ -28,10 +28,11 @@ defmodule MusicLibrary.Records do
def search_records(initial_search, query, opts) do
limit = Keyword.fetch!(opts, :limit)
offset = Keyword.fetch!(opts, :offset)
order = Keyword.fetch!(opts, :order)
search =
initial_search
|> build_search(query)
|> build_search(query, order)
|> limit(^limit)
|> offset(^offset)
|> select(^essential_fields())
@@ -45,16 +46,23 @@ defmodule MusicLibrary.Records do
Repo.aggregate(search, :count)
end
defp build_search(initial_search, query) do
defp build_search(initial_search, query, order \\ :alphabetical) do
{:ok, parsed_query} = SearchParser.parse(query)
search_with_order =
initial_search
|> order_by(
fragment(
"unaccent(json_extract(artists, '$[0].sort_name')) COLLATE NOCASE ASC, unaccent(title) COLLATE NOCASE ASC"
)
)
case order do
:alphabetical ->
initial_search
|> order_by(
fragment(
"unaccent(json_extract(artists, '$[0].sort_name')) COLLATE NOCASE ASC, unaccent(title) COLLATE NOCASE ASC"
)
)
:purchase ->
initial_search
|> order_by([r], {:desc, r.purchased_at})
end
Enum.reduce(parsed_query, search_with_order, fn
{:artist, artist}, search ->
+2 -1
View File
@@ -8,8 +8,9 @@ defmodule MusicLibrary.Wishlist do
def search_records(query, opts \\ []) do
limit = Keyword.get(opts, :limit, 20)
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
def search_records_count(query) do
+13 -5
View File
@@ -25,7 +25,7 @@ defmodule MusicLibraryWeb.Pagination do
]}>
<.link
: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")}
class={[
"relative inline-flex items-center rounded-md border",
@@ -39,7 +39,7 @@ defmodule MusicLibraryWeb.Pagination do
</.link>
<.link
: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")}
class={[
"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_size={@pagination_params.page_size}
query={@pagination_params.query}
order={@pagination_params.order}
/>
<.numbered_link
:for={page_number <- @page_links.visible_left_pages}
page_number={page_number}
page_size={@pagination_params.page_size}
query={@pagination_params.query}
order={@pagination_params.order}
/>
<.separator :if={@page_links.left_separator} />
<.numbered_link
@@ -74,6 +76,7 @@ defmodule MusicLibraryWeb.Pagination do
active={page_number == @pagination_params.page}
page_size={@pagination_params.page_size}
query={@pagination_params.query}
order={@pagination_params.order}
/>
<.separator :if={@page_links.right_separator} />
<.numbered_link
@@ -81,12 +84,14 @@ defmodule MusicLibraryWeb.Pagination do
page_number={page_number}
page_size={@pagination_params.page_size}
query={@pagination_params.query}
order={@pagination_params.order}
/>
<.next_link
:if={@page_links.next_page}
page_number={@page_links.next_page}
page_size={@pagination_params.page_size}
query={@pagination_params.query}
order={@pagination_params.order}
/>
</nav>
</div>
@@ -102,6 +107,7 @@ defmodule MusicLibraryWeb.Pagination do
attr :page_number, :integer, required: true
attr :page_size, :integer, required: true
attr :query, :string, required: true
attr :order, :atom, required: true
defp next_link(assigns) do
~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"
]}
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>
<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_size, :integer, required: true
attr :query, :string, required: true
attr :order, :atom, required: true
defp prev_link(assigns) do
~H"""
<.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"
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>
<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 :active, :boolean, default: false
attr :query, :string, required: true
attr :order, :atom, required: true
defp numbered_link(assigns) when assigns.active do
~H"""
@@ -174,7 +182,7 @@ defmodule MusicLibraryWeb.Pagination do
<.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"
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}
</.link>
@@ -74,8 +74,10 @@ defmodule MusicLibraryWeb.CollectionLive.Index do
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 =
Collection.search_records(query, limit: record_list_params.page_size, offset: offset)
Collection.search_records(query, opts)
socket
|> assign(:page_title, gettext("Collection"))
@@ -166,7 +168,7 @@ defmodule MusicLibraryWeb.CollectionLive.Index do
defp order_path(record_list_params, order) do
qs =
record_list_params
|> Map.take([:query, :page, :page_size])
|> Map.take([:query])
|> Map.put(:order, order)
|> Enum.filter(fn {_, v} -> v not in ["", nil] end)
@@ -10,7 +10,8 @@ defmodule MusicLibraryWeb.WishlistLive.Index do
@default_records_list_params %{
query: "",
page: 1,
page_size: 20
page_size: 20,
order: :alphabetical
}
@impl true
@@ -70,7 +71,13 @@ defmodule MusicLibraryWeb.WishlistLive.Index do
|> merge_pagination(params, total_records)
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
|> 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/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:132
#, elixir-autogen, elixir-format
@@ -59,12 +59,12 @@ msgstr ""
msgid "Edit"
msgstr ""
#: lib/music_library_web/live/collection_live/index.ex:127
#: lib/music_library_web/live/collection_live/index.ex:134
#: lib/music_library_web/live/collection_live/index.ex:129
#: 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: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:135
#, elixir-autogen, elixir-format
msgid "Error importing record"
msgstr ""
@@ -136,7 +136,7 @@ msgid "MusicBrainz ID"
msgstr ""
#: 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
msgid "Next"
msgstr ""
@@ -164,7 +164,7 @@ msgid "Password"
msgstr ""
#: 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
msgid "Previous"
msgstr ""
@@ -186,15 +186,15 @@ msgstr ""
msgid "Purchased on"
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/wishlist_live/index.ex:113
#: lib/music_library_web/live/wishlist_live/index.ex:120
#, elixir-autogen, elixir-format
msgid "Record imported successfully"
msgstr ""
#: 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
#, elixir-autogen, elixir-format
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/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
#, elixir-autogen, elixir-format
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/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
#, elixir-autogen, elixir-format
msgid "Wishlist"
@@ -416,7 +416,7 @@ msgstr ""
msgid "Import from MusicBrainz · Collection"
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
msgid "Import from MusicBrainz · Wishlist"
msgstr ""
+1 -1
View File
@@ -27,7 +27,7 @@ defmodule MusicLibrary.RecordsTest do
# so we rely on record ids to compare results
defp search(query, limit, offset) do
SearchIndex
|> Records.search_records(query, limit: limit, offset: offset)
|> Records.search_records(query, limit: limit, offset: offset, order: :alphabetical)
|> Enum.map(& &1.id)
end