Add Top 20 Release Years widget
This commit is contained in:
@@ -161,6 +161,23 @@ defmodule MusicLibrary.Collection do
|
|||||||
Repo.all(q)
|
Repo.all(q)
|
||||||
end
|
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()
|
@spec collected_releases_query() :: Ecto.Query.t()
|
||||||
def collected_releases_query do
|
def collected_releases_query do
|
||||||
from rr in RecordRelease,
|
from rr in RecordRelease,
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
</.tabs>
|
</.tabs>
|
||||||
</div>
|
</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>
|
<div>
|
||||||
<h1 class="text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
<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)})}
|
{gettext("Top %{n} Collection Artists", %{n: length(@records_by_artist)})}
|
||||||
@@ -336,6 +336,23 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
</Layouts.app>
|
</Layouts.app>
|
||||||
"""
|
"""
|
||||||
@@ -347,6 +364,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
latest_record = Collection.get_latest_record()
|
latest_record = Collection.get_latest_record()
|
||||||
records_by_artists = Collection.count_records_by_artist(limit: 20)
|
records_by_artists = Collection.count_records_by_artist(limit: 20)
|
||||||
records_by_genre = Collection.count_records_by_genre(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 =
|
records_on_this_day =
|
||||||
current_date
|
current_date
|
||||||
@@ -375,6 +393,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
current_section: :stats,
|
current_section: :stats,
|
||||||
records_by_artist: records_by_artists,
|
records_by_artist: records_by_artists,
|
||||||
records_by_genre: records_by_genre,
|
records_by_genre: records_by_genre,
|
||||||
|
records_by_release_year: records_by_release_year,
|
||||||
records_on_this_day: records_on_this_day
|
records_on_this_day: records_on_this_day
|
||||||
)}
|
)}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2336,3 +2336,8 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Track ID"
|
msgid "Track ID"
|
||||||
msgstr ""
|
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
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Track ID"
|
msgid "Track ID"
|
||||||
msgstr ""
|
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
|
||||||
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
|
describe "collected_artist_ids/0" do
|
||||||
setup [:fill_collection]
|
setup [:fill_collection]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user