From abb1ab332a38f25ee39eee109bdf162b4bfb8665 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Sat, 7 Feb 2026 10:23:35 +0000 Subject: [PATCH] Can order record sets --- lib/music_library/record_sets.ex | 11 +++++++- .../components/pagination.ex | 6 ++-- .../live/record_set_live/index.ex | 28 +++++++++++++++++-- .../live/record_set_live/index.html.heex | 23 ++++++++++++++- priv/gettext/default.pot | 6 ++++ priv/gettext/en/LC_MESSAGES/default.po | 6 ++++ 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/lib/music_library/record_sets.ex b/lib/music_library/record_sets.ex index a7d8a319..0aee6110 100644 --- a/lib/music_library/record_sets.ex +++ b/lib/music_library/record_sets.ex @@ -29,15 +29,24 @@ defmodule MusicLibrary.RecordSets do def search_record_sets(query, opts \\ []) do offset = Keyword.get(opts, :offset, 0) limit = Keyword.get(opts, :limit, 20) + order = Keyword.get(opts, :order, :updated_at) record_sets_search_query(query) - |> order_by([rs], desc: rs.updated_at) + |> apply_order(order) |> offset(^offset) |> limit(^limit) |> preload(items: :record) |> Repo.all() end + defp apply_order(query, :alphabetical) do + order_by(query, [rs], fragment("? COLLATE NOCASE ASC", rs.name)) + end + + defp apply_order(query, _) do + order_by(query, [rs], desc: rs.updated_at) + end + def get_record_set!(id) do RecordSet |> Repo.get!(id) diff --git a/lib/music_library_web/components/pagination.ex b/lib/music_library_web/components/pagination.ex index badfbf75..9b22fd9f 100644 --- a/lib/music_library_web/components/pagination.ex +++ b/lib/music_library_web/components/pagination.ex @@ -91,7 +91,7 @@ defmodule MusicLibraryWeb.Components.Pagination do attr :query, :string, required: true attr :order, :atom, - values: [:alphabetical, :purchase, :scrobbled_at, :title, :artist, :album], + values: [:alphabetical, :purchase, :scrobbled_at, :title, :artist, :album, :updated_at], required: true defp next_link(assigns) do @@ -111,7 +111,7 @@ defmodule MusicLibraryWeb.Components.Pagination do attr :query, :string, required: true attr :order, :atom, - values: [:alphabetical, :purchase, :scrobbled_at, :title, :artist, :album], + values: [:alphabetical, :purchase, :scrobbled_at, :title, :artist, :album, :updated_at], required: true defp prev_link(assigns) do @@ -140,7 +140,7 @@ defmodule MusicLibraryWeb.Components.Pagination do attr :query, :string, required: true attr :order, :atom, - values: [:alphabetical, :purchase, :scrobbled_at, :title, :artist, :album], + values: [:alphabetical, :purchase, :scrobbled_at, :title, :artist, :album, :updated_at], required: true defp numbered_link(assigns) when assigns.active do diff --git a/lib/music_library_web/live/record_set_live/index.ex b/lib/music_library_web/live/record_set_live/index.ex index 9d081dbd..44ca0385 100644 --- a/lib/music_library_web/live/record_set_live/index.ex +++ b/lib/music_library_web/live/record_set_live/index.ex @@ -48,11 +48,13 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do defp apply_action(socket, :index, params) do query = params["query"] || "" + order = parse_order(params["order"] || "updated_at") total_sets = RecordSets.count_record_sets(query) list_params = @default_list_params |> merge_query(query) + |> merge_order(order) |> merge_pagination(params, total_sets) load_and_assign_sets(socket, list_params) @@ -109,7 +111,8 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do sets = RecordSets.search_record_sets(list_params.query, offset: offset, - limit: list_params.page_size + limit: list_params.page_size, + order: list_params.order ) list_params_with_total = @@ -125,7 +128,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do def back_path(list_params) do qs = list_params - |> Map.take([:query, :page, :page_size]) + |> Map.take([:query, :page, :page_size, :order]) |> Enum.filter(fn {_, v} -> v not in ["", nil] end) ~p"/record-sets?#{qs}" @@ -163,7 +166,8 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do qs = @default_list_params |> Map.put(:query, query) - |> Map.take([:query, :page, :page_size]) + |> Map.put(:order, socket.assigns.list_params.order) + |> Map.take([:query, :page, :page_size, :order]) {:noreply, push_patch(socket, to: ~p"/record-sets?#{qs}")} end @@ -199,6 +203,24 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do {:noreply, stream_insert(socket, :record_sets, updated_set)} end + defp parse_order("alphabetical"), do: :alphabetical + defp parse_order("updated_at"), do: :updated_at + defp parse_order(_), do: :updated_at + + defp merge_order(params, order) do + Map.put(params, :order, order) + end + + defp order_path(list_params, order) do + qs = + list_params + |> Map.take([:query]) + |> Map.put(:order, order) + |> Enum.filter(fn {_, v} -> v not in ["", nil] end) + + ~p"/record-sets?#{qs}" + end + defp render_description(description) do description |> Markdown.to_html() diff --git a/lib/music_library_web/live/record_set_live/index.html.heex b/lib/music_library_web/live/record_set_live/index.html.heex index a8a1f9ed..8066bb27 100644 --- a/lib/music_library_web/live/record_set_live/index.html.heex +++ b/lib/music_library_web/live/record_set_live/index.html.heex @@ -21,6 +21,27 @@ <.search_form query={@list_params.query} /> +
+ <.button_group> + <.button + patch={order_path(@list_params, :updated_at)} + size="sm" + class={[@list_params.order == :updated_at && "bg-zinc-100! dark:bg-zinc-700!"]} + > + <.icon name="hero-clock" class="icon" aria-hidden="true" data-slot="icon" /> + {gettext("Updated")} + + <.button + patch={order_path(@list_params, :alphabetical)} + size="sm" + class={[@list_params.order == :alphabetical && "bg-zinc-100! dark:bg-zinc-700!"]} + > + <.icon name="hero-user-solid" class="icon" aria-hidden="true" data-slot="icon" /> + {gettext("A->Z")} + + +
+