diff --git a/lib/music_library/scrobble_rules.ex b/lib/music_library/scrobble_rules.ex index 31a16488..328e5ada 100644 --- a/lib/music_library/scrobble_rules.ex +++ b/lib/music_library/scrobble_rules.ex @@ -15,6 +15,7 @@ defmodule MusicLibrary.ScrobbleRules do type: atom(), enabled: boolean(), query: String.t(), + order: :inserted_at | :alphabetical, offset: non_neg_integer(), limit: non_neg_integer() ] @@ -22,7 +23,8 @@ defmodule MusicLibrary.ScrobbleRules do @spec list_scrobble_rules(list_opts()) :: [ScrobbleRule.t()] def list_scrobble_rules(opts \\ []) do query = - from(r in ScrobbleRule, order_by: [desc: r.inserted_at]) + from(r in ScrobbleRule) + |> order_scrobble_rules(Keyword.get(opts, :order, :inserted_at)) |> filter_scrobble_rules(opts) query = @@ -494,6 +496,14 @@ defmodule MusicLibrary.ScrobbleRules do end end + defp order_scrobble_rules(query, :alphabetical) do + from r in query, order_by: [asc: r.match_value] + end + + defp order_scrobble_rules(query, _inserted_at) do + from r in query, order_by: [desc: r.inserted_at] + end + # column and json_path are hardcoded string literals from internal callers, # never user input. All user-derived values use parameterized ? placeholders. # sobelow_skip ["SQL.Query"] diff --git a/lib/music_library_web/live/scrobble_rules_live/index.ex b/lib/music_library_web/live/scrobble_rules_live/index.ex index ca35cf09..0b779cd6 100644 --- a/lib/music_library_web/live/scrobble_rules_live/index.ex +++ b/lib/music_library_web/live/scrobble_rules_live/index.ex @@ -42,6 +42,31 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do +
+ <.button_group> + <.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")} + + <.button + patch={order_path(@list_params, :inserted_at)} + size="sm" + class={[ + @list_params.order == :inserted_at && "bg-zinc-100! dark:bg-zinc-700!" + ]} + > + <.icon name="hero-clock" class="icon" aria-hidden="true" data-slot="icon" /> + {gettext("Updated")} + + +
+