Add Top 20 Release Years widget
This commit is contained in:
@@ -161,6 +161,23 @@ defmodule MusicLibrary.Collection do
|
||||
Repo.all(q)
|
||||
end
|
||||
|
||||
@spec count_records_by_release_year(keyword()) :: [{String.t(), non_neg_integer()}]
|
||||
def count_records_by_release_year(opts \\ []) do
|
||||
limit = Keyword.get(opts, :limit, @pagination[:stats_limit])
|
||||
|
||||
q =
|
||||
from r in Record,
|
||||
where: not is_nil(r.purchased_at),
|
||||
where: not is_nil(r.release_date),
|
||||
where: r.release_date != "",
|
||||
group_by: fragment("substr(?, 1, 4)", r.release_date),
|
||||
order_by: [desc: fragment("count(1)")],
|
||||
select: {fragment("substr(?, 1, 4)", r.release_date), fragment("count(1)")},
|
||||
limit: ^limit
|
||||
|
||||
Repo.all(q)
|
||||
end
|
||||
|
||||
@spec collected_releases_query() :: Ecto.Query.t()
|
||||
def collected_releases_query do
|
||||
from rr in RecordRelease,
|
||||
|
||||
@@ -292,7 +292,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
||||
</.tabs>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 grid grid-cols-1 gap-5 lg:grid-cols-2">
|
||||
<div class="mt-5 grid grid-cols-1 gap-5 lg:grid-cols-3">
|
||||
<div>
|
||||
<h1 class="text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||
{gettext("Top %{n} Collection Artists", %{n: length(@records_by_artist)})}
|
||||
@@ -336,6 +336,23 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1 class="text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||
{gettext("Top 20 Release Years")}
|
||||
</h1>
|
||||
<div class="mt-5 rounded-md bg-white shadow-sm dark:bg-zinc-800">
|
||||
<.vertical_bar_chart
|
||||
data={@records_by_release_year}
|
||||
width={600}
|
||||
height={26 * length(@records_by_release_year)}
|
||||
color_class="fill-red-500"
|
||||
label_fn={fn {year, _count} -> year end}
|
||||
value_fn={fn {_year, count} -> count end}
|
||||
class="w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layouts.app>
|
||||
"""
|
||||
@@ -347,6 +364,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
||||
latest_record = Collection.get_latest_record()
|
||||
records_by_artists = Collection.count_records_by_artist(limit: 20)
|
||||
records_by_genre = Collection.count_records_by_genre(limit: 20)
|
||||
records_by_release_year = Collection.count_records_by_release_year(limit: 20)
|
||||
|
||||
records_on_this_day =
|
||||
current_date
|
||||
@@ -375,6 +393,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
||||
current_section: :stats,
|
||||
records_by_artist: records_by_artists,
|
||||
records_by_genre: records_by_genre,
|
||||
records_by_release_year: records_by_release_year,
|
||||
records_on_this_day: records_on_this_day
|
||||
)}
|
||||
end
|
||||
|
||||
@@ -2336,3 +2336,8 @@ msgstr ""
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Track ID"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/live/stats_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Top 20 Release Years"
|
||||
msgstr ""
|
||||
|
||||
@@ -2336,3 +2336,8 @@ msgstr ""
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Track ID"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/live/stats_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Top 20 Release Years"
|
||||
msgstr ""
|
||||
|
||||
@@ -156,6 +156,79 @@ defmodule MusicLibrary.CollectionTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "count_records_by_release_year/1" do
|
||||
test "returns counts grouped by release year, ordered by count descending" do
|
||||
record_with_artist("Artist A", %{
|
||||
release_date: "1994-09-13",
|
||||
purchased_at: ~U[2024-12-27 16:50:57Z]
|
||||
})
|
||||
|
||||
record_with_artist("Artist B", %{
|
||||
release_date: "1994-03-01",
|
||||
purchased_at: ~U[2024-12-28 16:50:57Z]
|
||||
})
|
||||
|
||||
record_with_artist("Artist C", %{
|
||||
release_date: "2020",
|
||||
purchased_at: ~U[2024-12-29 16:50:57Z]
|
||||
})
|
||||
|
||||
assert [{"1994", 2}, {"2020", 1}] = Collection.count_records_by_release_year()
|
||||
end
|
||||
|
||||
test "excludes wishlisted records" do
|
||||
record_with_artist("Artist A", %{
|
||||
release_date: "2020",
|
||||
purchased_at: ~U[2024-12-27 16:50:57Z]
|
||||
})
|
||||
|
||||
record_with_artist("Artist B", %{
|
||||
release_date: "2020",
|
||||
purchased_at: nil
|
||||
})
|
||||
|
||||
assert [{"2020", 1}] = Collection.count_records_by_release_year()
|
||||
end
|
||||
|
||||
test "excludes records without a release date" do
|
||||
record_with_artist("Artist A", %{
|
||||
release_date: "2020",
|
||||
purchased_at: ~U[2024-12-27 16:50:57Z]
|
||||
})
|
||||
|
||||
record_with_artist("Artist B", %{
|
||||
release_date: nil,
|
||||
purchased_at: ~U[2024-12-28 16:50:57Z]
|
||||
})
|
||||
|
||||
record_with_artist("Artist C", %{
|
||||
release_date: "",
|
||||
purchased_at: ~U[2024-12-29 16:50:57Z]
|
||||
})
|
||||
|
||||
assert [{"2020", 1}] = Collection.count_records_by_release_year()
|
||||
end
|
||||
|
||||
test "respects limit" do
|
||||
record_with_artist("Artist A", %{
|
||||
release_date: "1994",
|
||||
purchased_at: ~U[2024-12-27 16:50:57Z]
|
||||
})
|
||||
|
||||
record_with_artist("Artist B", %{
|
||||
release_date: "1994",
|
||||
purchased_at: ~U[2024-12-28 16:50:57Z]
|
||||
})
|
||||
|
||||
record_with_artist("Artist C", %{
|
||||
release_date: "2020",
|
||||
purchased_at: ~U[2024-12-29 16:50:57Z]
|
||||
})
|
||||
|
||||
assert [{"1994", 2}] = Collection.count_records_by_release_year(limit: 1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "collected_artist_ids/0" do
|
||||
setup [:fill_collection]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user