Render scrobble rules list with Fluxon table

This commit is contained in:
Claudio Ortolina
2025-07-04 14:05:08 +01:00
parent 6518a4b10e
commit 81f0ec8830
4 changed files with 97 additions and 158 deletions
@@ -118,20 +118,4 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
"Disabled"
end
end
defp enabled_badge_class(enabled) do
if enabled do
"text-green-800 bg-green-100 dark:bg-green-900 dark:text-green-300"
else
"text-red-800 bg-red-100 dark:bg-red-900 dark:text-red-300"
end
end
defp type_badge_class(type) do
case type do
"album" -> "text-blue-800 bg-blue-100 dark:bg-blue-900 dark:text-blue-300"
"artist" -> "text-purple-800 bg-purple-100 dark:bg-purple-900 dark:text-purple-300"
_ -> "text-gray-800 bg-gray-100 dark:bg-gray-900 dark:text-gray-300"
end
end
end
@@ -14,136 +14,75 @@
<.icon name="hero-plus" class="h-4 w-4 mr-2" />
{gettext("New Rule")}
</.button>
<.button phx-click="apply_all_rules" class="!bg-green-600 hover:!bg-green-700">
<.icon name="hero-play" class="h-4 w-4 mr-2" />
{gettext("Apply All Rules")}
</.button>
</.link>
</div>
</div>
</header>
<div class="mt-6 space-y-4">
<div class="flex justify-between items-center">
<p class="text-sm text-zinc-600 dark:text-zinc-400">
{gettext(
"Rules are applied automatically by the background worker, or you can apply them manually."
)}
</p>
<.button phx-click="apply_all_rules" class="!bg-green-600 hover:!bg-green-700">
<.icon name="hero-play" class="h-4 w-4 mr-2" />
{gettext("Apply All Rules")}
</.button>
</div>
<div class="bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-zinc-200/10 sm:rounded-lg overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-zinc-200 dark:divide-zinc-800">
<thead class="bg-zinc-50 dark:bg-zinc-800">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
{gettext("Type")}
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
{gettext("Match Value")}
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
{gettext("Target MusicBrainz ID")}
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
{gettext("Status")}
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
{gettext("Description")}
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
{gettext("Created")}
</th>
<th class="px-6 py-3 text-right text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
{gettext("Actions")}
</th>
</tr>
</thead>
<tbody
id="scrobble_rules"
phx-update="stream"
class="bg-white dark:bg-zinc-900 divide-y divide-zinc-200 dark:divide-zinc-800"
>
<tr
:for={{dom_id, scrobble_rule} <- @streams.scrobble_rules}
id={dom_id}
class="hover:bg-zinc-50 dark:hover:bg-zinc-800"
>
<td class="px-6 py-4 whitespace-nowrap">
<span class={[
"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium",
type_badge_class(scrobble_rule.type)
]}>
{rule_type_badge(scrobble_rule.type)}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100 font-medium">
{scrobble_rule.match_value}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400 font-mono">
{scrobble_rule.target_musicbrainz_id}
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class={[
"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium",
enabled_badge_class(scrobble_rule.enabled)
]}>
{enabled_badge(scrobble_rule.enabled)}
</span>
</td>
<td class="px-6 py-4 text-sm text-zinc-500 dark:text-zinc-400">
{scrobble_rule.description}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400">
{Calendar.strftime(scrobble_rule.inserted_at, "%Y-%m-%d")}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium space-x-2">
<.button
phx-click="apply_rule"
phx-value-id={scrobble_rule.id}
class="!bg-green-600 hover:!bg-green-700 !text-white !text-xs !px-2 !py-1"
>
<.icon name="hero-play" class="h-3 w-3" />
</.button>
<.button
phx-click="toggle_enabled"
phx-value-id={scrobble_rule.id}
class={[
"!text-white !text-xs !px-2 !py-1",
if(scrobble_rule.enabled,
do: "!bg-yellow-600 hover:!bg-yellow-700",
else: "!bg-green-600 hover:!bg-green-700"
)
]}
>
<.table>
<.table_head>
<:col>{gettext("Type")}</:col>
<:col>{gettext("Match Value")}</:col>
<:col>{gettext("Target MusicBrainz ID")}</:col>
<:col>{gettext("Status")}</:col>
<:col>{gettext("Description")}</:col>
<:col>{gettext("Created")}</:col>
<:col></:col>
</.table_head>
<.table_body>
<.table_row :for={{dom_id, scrobble_rule} <- @streams.scrobble_rules} id={dom_id}>
<:cell>{rule_type_badge(scrobble_rule.type)}</:cell>
<:cell>{scrobble_rule.match_value}</:cell>
<:cell class="whitespace-nowrap font-mono">{scrobble_rule.target_musicbrainz_id}</:cell>
<:cell>{enabled_badge(scrobble_rule.enabled)}</:cell>
<:cell>{scrobble_rule.description}</:cell>
<:cell>{Calendar.strftime(scrobble_rule.inserted_at, "%Y-%m-%d")}</:cell>
<:cell>
<.dropdown id={"actions-#{scrobble_rule.id}"} placement="bottom-end">
<:toggle>
<div>
<span class="sr-only">{gettext("Actions")}</span>
<.icon
name={if scrobble_rule.enabled, do: "hero-pause", else: "hero-play"}
class="h-3 w-3"
name="hero-ellipsis-vertical"
class="-mt-1 h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer"
aria-hidden="true"
data-slot="icon"
/>
</.button>
<.link patch={~p"/scrobble-rules/#{scrobble_rule}/edit"}>
<.button class="!bg-blue-600 hover:!bg-blue-700 !text-white !text-xs !px-2 !py-1">
<.icon name="hero-pencil" class="h-3 w-3" />
</.button>
</.link>
<.button
phx-click="delete"
phx-value-id={scrobble_rule.id}
data-confirm={gettext("Are you sure you want to delete this rule?")}
class="!bg-red-600 hover:!bg-red-700 !text-white !text-xs !px-2 !py-1"
>
<.icon name="hero-trash" class="h-3 w-3" />
</.button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</:toggle>
<.dropdown_button phx-click="apply_rule" phx-value-id={scrobble_rule.id}>
{gettext("Apply rule")}
</.dropdown_button>
<.dropdown_button phx-click="toggle_enabled" phx-value-id={scrobble_rule.id}>
{if scrobble_rule.enabled, do: gettext("Disable rule"), else: gettext("Enable rule")}
</.dropdown_button>
<.dropdown_link
id={"actions-#{scrobble_rule.id}-edit"}
patch={~p"/scrobble-rules/#{scrobble_rule}/edit"}
>
{gettext("Edit")}
</.dropdown_link>
<.separator />
<.dropdown_button
phx-click="delete"
phx-value-id={scrobble_rule.id}
data-confirm={gettext("Are you sure?")}
class={[
"text-red-900! hover:bg-red-50! dark:text-red-500! dark:hover:bg-red-900/30! dark:hover:text-red-600!"
]}
>
{gettext("Delete")}
</.dropdown_button>
</.dropdown>
</:cell>
</.table_row>
</.table_body>
</.table>
</div>
<.modal
+18 -10
View File
@@ -13,6 +13,7 @@ msgstr ""
#: lib/music_library_web/components/record_components.ex
#: lib/music_library_web/live/collection_live/show.html.heex
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#: lib/music_library_web/live/wishlist_live/show.html.heex
#, elixir-autogen, elixir-format
msgid "Are you sure?"
@@ -33,6 +34,7 @@ msgstr ""
#: lib/music_library_web/components/record_components.ex
#: lib/music_library_web/live/collection_live/show.html.heex
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#: lib/music_library_web/live/wishlist_live/show.html.heex
#, elixir-autogen, elixir-format
msgid "Delete"
@@ -41,6 +43,7 @@ msgstr ""
#: lib/music_library_web/components/record_components.ex
#: lib/music_library_web/live/collection_live/show.ex
#: lib/music_library_web/live/collection_live/show.html.heex
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#: lib/music_library_web/live/wishlist_live/show.ex
#: lib/music_library_web/live/wishlist_live/show.html.heex
#, elixir-autogen, elixir-format
@@ -974,11 +977,6 @@ msgstr ""
msgid "Apply All Rules"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this rule?"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/form_component.ex
#, elixir-autogen, elixir-format
msgid "Artist"
@@ -1055,11 +1053,6 @@ msgstr ""
msgid "Rule applied successfully. Updated %{count} tracks."
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Rules are applied automatically by the background worker, or you can apply them manually."
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/form_component.ex
#, elixir-autogen, elixir-format
msgid "Save Rule"
@@ -1107,3 +1100,18 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "e.g. The Dark Side of the Moon"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Apply rule"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Disable rule"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Enable rule"
msgstr ""
+18 -10
View File
@@ -13,6 +13,7 @@ msgstr ""
#: lib/music_library_web/components/record_components.ex
#: lib/music_library_web/live/collection_live/show.html.heex
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#: lib/music_library_web/live/wishlist_live/show.html.heex
#, elixir-autogen, elixir-format
msgid "Are you sure?"
@@ -33,6 +34,7 @@ msgstr ""
#: lib/music_library_web/components/record_components.ex
#: lib/music_library_web/live/collection_live/show.html.heex
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#: lib/music_library_web/live/wishlist_live/show.html.heex
#, elixir-autogen, elixir-format
msgid "Delete"
@@ -41,6 +43,7 @@ msgstr ""
#: lib/music_library_web/components/record_components.ex
#: lib/music_library_web/live/collection_live/show.ex
#: lib/music_library_web/live/collection_live/show.html.heex
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#: lib/music_library_web/live/wishlist_live/show.ex
#: lib/music_library_web/live/wishlist_live/show.html.heex
#, elixir-autogen, elixir-format
@@ -974,11 +977,6 @@ msgstr ""
msgid "Apply All Rules"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this rule?"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/form_component.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Artist"
@@ -1055,11 +1053,6 @@ msgstr ""
msgid "Rule applied successfully. Updated %{count} tracks."
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Rules are applied automatically by the background worker, or you can apply them manually."
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/form_component.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Save Rule"
@@ -1107,3 +1100,18 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "e.g. The Dark Side of the Moon"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Apply rule"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Disable rule"
msgstr ""
#: lib/music_library_web/live/scrobble_rules_live/index.html.heex
#, elixir-autogen, elixir-format, fuzzy
msgid "Enable rule"
msgstr ""