Add pagination for scrobble rules
This commit is contained in:
@@ -45,9 +45,64 @@ defmodule MusicLibrary.ScrobbleRules do
|
|||||||
where: r.enabled == ^enabled
|
where: r.enabled == ^enabled
|
||||||
end
|
end
|
||||||
|
|
||||||
|
query =
|
||||||
|
case Keyword.get(opts, :offset) do
|
||||||
|
nil ->
|
||||||
|
query
|
||||||
|
|
||||||
|
offset ->
|
||||||
|
from r in query,
|
||||||
|
offset: ^offset
|
||||||
|
end
|
||||||
|
|
||||||
|
query =
|
||||||
|
case Keyword.get(opts, :limit) do
|
||||||
|
nil ->
|
||||||
|
query
|
||||||
|
|
||||||
|
limit ->
|
||||||
|
from r in query,
|
||||||
|
limit: ^limit
|
||||||
|
end
|
||||||
|
|
||||||
Repo.all(query)
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the count of scrobble_rules.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> count_scrobble_rules()
|
||||||
|
42
|
||||||
|
|
||||||
|
"""
|
||||||
|
def count_scrobble_rules(opts \\ []) do
|
||||||
|
query = from(r in ScrobbleRule)
|
||||||
|
|
||||||
|
query =
|
||||||
|
case Keyword.get(opts, :type) do
|
||||||
|
nil ->
|
||||||
|
query
|
||||||
|
|
||||||
|
type ->
|
||||||
|
from r in query,
|
||||||
|
where: r.type == ^type
|
||||||
|
end
|
||||||
|
|
||||||
|
query =
|
||||||
|
case Keyword.get(opts, :enabled) do
|
||||||
|
nil ->
|
||||||
|
query
|
||||||
|
|
||||||
|
enabled ->
|
||||||
|
from r in query,
|
||||||
|
where: r.enabled == ^enabled
|
||||||
|
end
|
||||||
|
|
||||||
|
Repo.aggregate(query, :count)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Gets a single scrobble_rule.
|
Gets a single scrobble_rule.
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
||||||
use MusicLibraryWeb, :live_view
|
use MusicLibraryWeb, :live_view
|
||||||
|
|
||||||
|
import MusicLibraryWeb.Components.Pagination
|
||||||
|
|
||||||
alias MusicLibrary.ScrobbleRules
|
alias MusicLibrary.ScrobbleRules
|
||||||
alias MusicLibrary.ScrobbleRules.ScrobbleRule
|
alias MusicLibrary.ScrobbleRules.ScrobbleRule
|
||||||
|
|
||||||
|
@default_list_params %{
|
||||||
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
query: "",
|
||||||
|
order: :inserted_at
|
||||||
|
}
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
{:ok, assign(socket, :current_section, :scrobble_rules)}
|
{:ok, assign(socket, :current_section, :scrobble_rules)}
|
||||||
@@ -28,11 +37,14 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
|||||||
|> assign(:scrobble_rule, %ScrobbleRule{})
|
|> assign(:scrobble_rule, %ScrobbleRule{})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp apply_action(socket, :index, _params) do
|
defp apply_action(socket, :index, params) do
|
||||||
socket
|
total_rules = ScrobbleRules.count_scrobble_rules()
|
||||||
|> assign(:page_title, gettext("Scrobble Rules"))
|
|
||||||
|> assign(:scrobble_rule, nil)
|
list_params =
|
||||||
|> stream(:scrobble_rules, ScrobbleRules.list_scrobble_rules(), reset: true)
|
@default_list_params
|
||||||
|
|> merge_pagination(params, total_rules)
|
||||||
|
|
||||||
|
load_and_assign_rules(socket, list_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_fallback_index(socket, params) do
|
def apply_fallback_index(socket, params) do
|
||||||
@@ -44,12 +56,74 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp merge_pagination(params, url_params, total_records) do
|
||||||
|
page = parse_page(url_params["page"])
|
||||||
|
page_size = parse_page_size(url_params["page_size"])
|
||||||
|
|
||||||
|
params
|
||||||
|
|> Map.put(:page, page)
|
||||||
|
|> Map.put(:page_size, page_size)
|
||||||
|
|> Map.put(:total_records, total_records)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parse_page(nil), do: 1
|
||||||
|
|
||||||
|
defp parse_page(page) when is_binary(page) do
|
||||||
|
case Integer.parse(page) do
|
||||||
|
{num, ""} when num > 0 -> num
|
||||||
|
_ -> 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parse_page(_), do: 1
|
||||||
|
|
||||||
|
defp parse_page_size(nil), do: 20
|
||||||
|
|
||||||
|
defp parse_page_size(page_size) when is_binary(page_size) do
|
||||||
|
case Integer.parse(page_size) do
|
||||||
|
{num, ""} when num in [20, 50, 100] -> num
|
||||||
|
_ -> 20
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parse_page_size(_), do: 20
|
||||||
|
|
||||||
|
defp load_and_assign_rules(socket, list_params) do
|
||||||
|
offset = page_to_offset(list_params.page, list_params.page_size)
|
||||||
|
|
||||||
|
rules =
|
||||||
|
ScrobbleRules.list_scrobble_rules(
|
||||||
|
offset: offset,
|
||||||
|
limit: list_params.page_size
|
||||||
|
)
|
||||||
|
|
||||||
|
list_params_with_total =
|
||||||
|
Map.put(list_params, :total_entries, list_params.total_records)
|
||||||
|
|
||||||
|
socket
|
||||||
|
|> assign(:list_params, list_params_with_total)
|
||||||
|
|> assign(:page_title, gettext("Scrobble Rules"))
|
||||||
|
|> assign(:scrobble_rule, nil)
|
||||||
|
|> stream(:scrobble_rules, rules, reset: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def back_path(list_params) do
|
||||||
|
qs =
|
||||||
|
list_params
|
||||||
|
|> Map.take([:page, :page_size])
|
||||||
|
|
||||||
|
~p"/scrobble-rules?#{qs}"
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info(
|
def handle_info(
|
||||||
{MusicLibraryWeb.ScrobbleRulesLive.Form, {:created, scrobble_rule}},
|
{MusicLibraryWeb.ScrobbleRulesLive.Form, {:created, scrobble_rule}},
|
||||||
socket
|
socket
|
||||||
) do
|
) do
|
||||||
{:noreply, stream_insert(socket, :scrobble_rules, scrobble_rule, at: 0)}
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> stream_insert(:scrobble_rules, scrobble_rule, at: 0)
|
||||||
|
|> load_and_assign_rules(socket.assigns.list_params)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_info(
|
def handle_info(
|
||||||
@@ -64,7 +138,10 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
|||||||
scrobble_rule = ScrobbleRules.get_scrobble_rule!(id)
|
scrobble_rule = ScrobbleRules.get_scrobble_rule!(id)
|
||||||
{:ok, _} = ScrobbleRules.delete_scrobble_rule(scrobble_rule)
|
{:ok, _} = ScrobbleRules.delete_scrobble_rule(scrobble_rule)
|
||||||
|
|
||||||
{:noreply, stream_delete(socket, :scrobble_rules, scrobble_rule)}
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> stream_delete(:scrobble_rules, scrobble_rule)
|
||||||
|
|> load_and_assign_rules(socket.assigns.list_params)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|||||||
@@ -31,6 +31,16 @@
|
|||||||
|
|
||||||
<div class="mt-6 space-y-4">
|
<div class="mt-6 space-y-4">
|
||||||
<ul phx-update="stream" id="scrobble-rules-list" class="space-y-4">
|
<ul phx-update="stream" id="scrobble-rules-list" class="space-y-4">
|
||||||
|
<li
|
||||||
|
id="no-scrobble-rules"
|
||||||
|
class="hidden only:block p-8 text-center bg-zinc-50 dark:bg-zinc-800 rounded-lg"
|
||||||
|
>
|
||||||
|
<.icon name="hero-beaker" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
||||||
|
<p class="text-zinc-600 dark:text-zinc-400">
|
||||||
|
{gettext("No scrobble rules found")}
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
:for={{dom_id, scrobble_rule} <- @streams.scrobble_rules}
|
:for={{dom_id, scrobble_rule} <- @streams.scrobble_rules}
|
||||||
id={dom_id}
|
id={dom_id}
|
||||||
@@ -79,7 +89,9 @@
|
|||||||
</.dropdown_button>
|
</.dropdown_button>
|
||||||
<.dropdown_link
|
<.dropdown_link
|
||||||
id={"actions-#{scrobble_rule.id}-edit"}
|
id={"actions-#{scrobble_rule.id}-edit"}
|
||||||
patch={~p"/scrobble-rules/#{scrobble_rule}/edit"}
|
patch={
|
||||||
|
~p"/scrobble-rules/#{scrobble_rule}/edit?#{Map.take(@list_params, [:page, :page_size])}"
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{gettext("Edit")}
|
{gettext("Edit")}
|
||||||
</.dropdown_link>
|
</.dropdown_link>
|
||||||
@@ -98,12 +110,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<.pagination id={:bottom_pagination} pagination_params={@list_params} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<.structured_modal
|
<.structured_modal
|
||||||
:if={@live_action in [:new, :edit]}
|
:if={@live_action in [:new, :edit]}
|
||||||
id="scrobble_rule-modal"
|
id="scrobble_rule-modal"
|
||||||
on_close={JS.patch(~p"/scrobble-rules")}
|
on_close={JS.patch(back_path(@list_params))}
|
||||||
>
|
>
|
||||||
<.live_component
|
<.live_component
|
||||||
module={MusicLibraryWeb.ScrobbleRulesLive.Form}
|
module={MusicLibraryWeb.ScrobbleRulesLive.Form}
|
||||||
@@ -111,7 +125,7 @@
|
|||||||
title={@page_title}
|
title={@page_title}
|
||||||
action={@live_action}
|
action={@live_action}
|
||||||
scrobble_rule={@scrobble_rule}
|
scrobble_rule={@scrobble_rule}
|
||||||
patch={~p"/scrobble-rules"}
|
patch={back_path(@list_params)}
|
||||||
/>
|
/>
|
||||||
</.structured_modal>
|
</.structured_modal>
|
||||||
</Layouts.app>
|
</Layouts.app>
|
||||||
|
|||||||
@@ -1667,3 +1667,8 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Artist MusicBrainz ID"
|
msgid "Artist MusicBrainz ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "No scrobble rules found"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -1667,3 +1667,8 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Artist MusicBrainz ID"
|
msgid "Artist MusicBrainz ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "No scrobble rules found"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ defmodule MusicLibraryWeb.ScrobbleRulesLiveTest do
|
|||||||
|> render_click() =~
|
|> render_click() =~
|
||||||
"Edit Scrobble Rule"
|
"Edit Scrobble Rule"
|
||||||
|
|
||||||
assert_patch(index_live, ~p"/scrobble-rules/#{scrobble_rule}/edit")
|
assert_patch(index_live, ~p"/scrobble-rules/#{scrobble_rule}/edit?page=1&page_size=20")
|
||||||
|
|
||||||
assert index_live
|
assert index_live
|
||||||
|> form("#scrobble_rule-form", scrobble_rule: @invalid_attrs)
|
|> form("#scrobble_rule-form", scrobble_rule: @invalid_attrs)
|
||||||
|
|||||||
Reference in New Issue
Block a user