Inline templates inside LV modules

This commit is contained in:
Claudio Ortolina
2026-02-24 17:20:21 +00:00
parent d55e957eea
commit e9b9717b08
32 changed files with 3583 additions and 3501 deletions
@@ -14,6 +14,143 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
order: :inserted_at
}
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
<header class="mb-6">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-zinc-900 dark:text-zinc-100">
{gettext("Scrobble Rules")}
</h1>
</div>
<div>
<.button_group>
<.button
variant="solid"
size="sm"
patch={~p"/scrobble-rules/new"}
>
<.icon name="hero-plus" class="icon" aria-hidden="true" data-slot="icon" />
{gettext("Add")}
</.button>
<.button
variant="solid"
size="sm"
phx-click="apply_all_rules"
>
<.icon name="hero-play" class="icon" />
{gettext("Apply")}
</.button>
</.button_group>
</div>
</div>
</header>
<div class="mt-6 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
:for={{dom_id, scrobble_rule} <- @streams.scrobble_rules}
id={dom_id}
class="flex justify-between"
>
<div class="flex items-center">
<.type_badge type={scrobble_rule.type} />
</div>
<div class="grow p-2">
<p class="text-sm text-zinc-900 dark:text-zinc-100">
{scrobble_rule.match_value}
</p>
<p class="text-xs font-mono text-zinc-500 dark:text-zinc-400 mt-2">
{scrobble_rule.target_musicbrainz_id}
</p>
<p class="text-xs text-zinc-500 dark:text-zinc-400 mt-2">
{scrobble_rule.description}
</p>
</div>
<div class="flex flex-col justify-center text-right">
<span>
<.status_badge enabled={scrobble_rule.enabled} />
</span>
<span class="text-xs text-zinc-500 dark:text-zinc-400 text-nowrap mt-2">
{Calendar.strftime(scrobble_rule.inserted_at, "%Y-%m-%d")}
</span>
</div>
<div class="flex items-center p-2">
<.dropdown id={"actions-#{scrobble_rule.id}"} placement="bottom-end">
<:toggle>
<.button variant="ghost">
<span class="sr-only">{gettext("Actions")}</span>
<.icon
name="hero-ellipsis-vertical"
class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer"
aria-hidden="true"
data-slot="icon"
/>
</.button>
</: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?#{Map.take(@list_params, [:page, :page_size])}"
}
>
{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>
</div>
</li>
</ul>
<.pagination id={:bottom_pagination} pagination_params={@list_params} />
</div>
<.structured_modal
:if={@live_action in [:new, :edit]}
id="scrobble_rule-modal"
on_close={JS.patch(back_path(@list_params))}
>
<.live_component
module={MusicLibraryWeb.ScrobbleRulesLive.Form}
id={@scrobble_rule.id || :new}
title={@page_title}
action={@live_action}
scrobble_rule={@scrobble_rule}
patch={back_path(@list_params)}
/>
</.structured_modal>
</Layouts.app>
"""
end
@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, :current_section, :scrobble_rules)}
@@ -1,131 +0,0 @@
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
<header class="mb-6">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-zinc-900 dark:text-zinc-100">
{gettext("Scrobble Rules")}
</h1>
</div>
<div>
<.button_group>
<.button
variant="solid"
size="sm"
patch={~p"/scrobble-rules/new"}
>
<.icon name="hero-plus" class="icon" aria-hidden="true" data-slot="icon" />
{gettext("Add")}
</.button>
<.button
variant="solid"
size="sm"
phx-click="apply_all_rules"
>
<.icon name="hero-play" class="icon" />
{gettext("Apply")}
</.button>
</.button_group>
</div>
</div>
</header>
<div class="mt-6 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
:for={{dom_id, scrobble_rule} <- @streams.scrobble_rules}
id={dom_id}
class="flex justify-between"
>
<div class="flex items-center">
<.type_badge type={scrobble_rule.type} />
</div>
<div class="grow p-2">
<p class="text-sm text-zinc-900 dark:text-zinc-100">
{scrobble_rule.match_value}
</p>
<p class="text-xs font-mono text-zinc-500 dark:text-zinc-400 mt-2">
{scrobble_rule.target_musicbrainz_id}
</p>
<p class="text-xs text-zinc-500 dark:text-zinc-400 mt-2">
{scrobble_rule.description}
</p>
</div>
<div class="flex flex-col justify-center text-right">
<span>
<.status_badge enabled={scrobble_rule.enabled} />
</span>
<span class="text-xs text-zinc-500 dark:text-zinc-400 text-nowrap mt-2">
{Calendar.strftime(scrobble_rule.inserted_at, "%Y-%m-%d")}
</span>
</div>
<div class="flex items-center p-2">
<.dropdown id={"actions-#{scrobble_rule.id}"} placement="bottom-end">
<:toggle>
<.button variant="ghost">
<span class="sr-only">{gettext("Actions")}</span>
<.icon
name="hero-ellipsis-vertical"
class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer"
aria-hidden="true"
data-slot="icon"
/>
</.button>
</: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?#{Map.take(@list_params, [:page, :page_size])}"
}
>
{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>
</div>
</li>
</ul>
<.pagination id={:bottom_pagination} pagination_params={@list_params} />
</div>
<.structured_modal
:if={@live_action in [:new, :edit]}
id="scrobble_rule-modal"
on_close={JS.patch(back_path(@list_params))}
>
<.live_component
module={MusicLibraryWeb.ScrobbleRulesLive.Form}
id={@scrobble_rule.id || :new}
title={@page_title}
action={@live_action}
scrobble_rule={@scrobble_rule}
patch={back_path(@list_params)}
/>
</.structured_modal>
</Layouts.app>