From 9100c6c04afbd3b6af82e42708323ba53f7664d3 Mon Sep 17 00:00:00 2001
From: Claudio Ortolina
Date: Thu, 29 May 2025 21:50:32 +0100
Subject: [PATCH] Extract actions_menu
---
.../components/add_record_component.ex | 39 +-------
.../components/core_components.ex | 51 ++++++++++
.../components/record_components.ex | 94 ++-----------------
.../live/artist_live/show.ex | 2 +-
.../live/artist_live/show.html.heex | 32 +------
.../live/collection_live/show.ex | 2 -
.../live/collection_live/show.html.heex | 32 +------
.../live/stats_live/index.ex | 10 --
.../live/stats_live/index.html.heex | 80 ++++------------
.../live/wishlist_live/show.ex | 2 -
.../live/wishlist_live/show.html.heex | 32 +------
priv/gettext/default.pot | 6 +-
priv/gettext/en/LC_MESSAGES/default.po | 6 +-
13 files changed, 95 insertions(+), 293 deletions(-)
diff --git a/lib/music_library_web/components/add_record_component.ex b/lib/music_library_web/components/add_record_component.ex
index 5b0752f2..9150fef8 100644
--- a/lib/music_library_web/components/add_record_component.ex
+++ b/lib/music_library_web/components/add_record_component.ex
@@ -1,8 +1,7 @@
defmodule MusicLibraryWeb.AddRecordComponent do
use MusicLibraryWeb, :live_component
- import MusicLibraryWeb.RecordComponents,
- only: [toggle_actions_menu: 1, close_actions_menu: 1, format_label: 1, type_label: 1]
+ import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1]
alias MusicBrainz.ReleaseGroupSearchResult
alias MusicLibrary.Records
@@ -88,37 +87,9 @@ defmodule MusicLibraryWeb.AddRecordComponent do
)}
-
-
-
- <.focus_wrap
- id={"actions-#{@release_group.id}"}
- class={[
- "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
- ]}
- role="menu"
- aria-orientation="vertical"
- aria-labelledby="options-menu-0-button"
- >
+ <.actions_menu id={@release_group.id} background_container_target="#records > li">
+ <:links>
<.link
:for={format <- Records.Record.formats()}
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
@@ -131,8 +102,8 @@ defmodule MusicLibraryWeb.AddRecordComponent do
>
{format_label(format)}
-
-
+
+
"""
diff --git a/lib/music_library_web/components/core_components.ex b/lib/music_library_web/components/core_components.ex
index cf0c00a1..e23e24cc 100644
--- a/lib/music_library_web/components/core_components.ex
+++ b/lib/music_library_web/components/core_components.ex
@@ -194,6 +194,57 @@ defmodule MusicLibraryWeb.CoreComponents do
"""
end
+ attr :id, :string, required: true
+ attr :class, :string, default: nil
+ attr :background_container_target, :string, required: true
+ slot :links, required: true
+ slot :button, required: false
+
+ def actions_menu(assigns) do
+ ~H"""
+
+
+ <.focus_wrap
+ id={"actions-#{@id}"}
+ class={[
+ "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
+ ]}
+ role="menu"
+ aria-orientation="vertical"
+ aria-labelledby="options-menu-0-button"
+ phx-click-away={close_actions_menu(@id, @background_container_target)}
+ >
+ {render_slot(@links)}
+
+
+ """
+ end
+
+ defp default_actions_menu_button(assigns) do
+ ~H"""
+ {gettext("Open options")}
+ <.icon name="hero-ellipsis-vertical" class="-mt-1 h-5 w-5" aria-hidden="true" data-slot="icon" />
+ """
+ end
+
+ defp toggle_actions_menu(id, background_container_target) do
+ JS.toggle(to: "#actions-#{id}")
+ |> JS.toggle_class("pointer-events-none", to: background_container_target)
+ end
+
+ defp close_actions_menu(id, background_container_target) do
+ JS.hide(to: "#actions-#{id}")
+ |> JS.remove_class("pointer-events-none", to: background_container_target)
+ end
+
## JS Commands
def show(js \\ %JS{}, selector) do
diff --git a/lib/music_library_web/components/record_components.ex b/lib/music_library_web/components/record_components.ex
index af7d922b..9836d3c4 100644
--- a/lib/music_library_web/components/record_components.ex
+++ b/lib/music_library_web/components/record_components.ex
@@ -95,42 +95,8 @@ defmodule MusicLibraryWeb.RecordComponents do
<%!-- TODO: replace with OSS version --%>
-
-
-
- <.focus_wrap
- id={"actions-#{record.id}"}
- class={[
- "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
- ]}
- role="menu"
- aria-orientation="vertical"
- aria-labelledby="options-menu-0-button"
- >
+ <.actions_menu id={record.id} background_container_target="#records > li">
+ <:links>
<.link
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
role="menuitem"
@@ -185,8 +151,8 @@ defmodule MusicLibraryWeb.RecordComponents do
>
{gettext("Delete")}
-
-
+
+
@@ -270,42 +236,8 @@ defmodule MusicLibraryWeb.RecordComponents do
{record.title}
-
-
-
- <.focus_wrap
- id={"actions-#{record.id}"}
- class={[
- "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
- ]}
- role="menu"
- aria-orientation="vertical"
- aria-labelledby="options-menu-0-button"
- >
+ <.actions_menu id={record.id} background_container_target="#records > li" class="mt-2">
+ <:links>
<.link
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
role="menuitem"
@@ -360,8 +292,8 @@ defmodule MusicLibraryWeb.RecordComponents do
>
{gettext("Delete")}
-
-
+
+
{format_label(record.format)} · {type_label(record.type)}
@@ -450,14 +382,4 @@ defmodule MusicLibraryWeb.RecordComponents do
country_code
end
end
-
- def toggle_actions_menu(record_id) do
- JS.toggle(to: "#actions-#{record_id}")
- |> JS.toggle_class("pointer-events-none", to: "#records > li")
- end
-
- def close_actions_menu(record_id) do
- JS.hide(to: "#actions-#{record_id}")
- |> JS.remove_class("pointer-events-none", to: "#records > li")
- end
end
diff --git a/lib/music_library_web/live/artist_live/show.ex b/lib/music_library_web/live/artist_live/show.ex
index f2d2601b..e3fa215b 100644
--- a/lib/music_library_web/live/artist_live/show.ex
+++ b/lib/music_library_web/live/artist_live/show.ex
@@ -2,7 +2,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
use MusicLibraryWeb, :live_view
import MusicLibraryWeb.RecordComponents,
- only: [record_grid: 1, toggle_actions_menu: 1, close_actions_menu: 1, country_label: 1]
+ only: [record_grid: 1, country_label: 1]
alias MusicLibrary.Artists.ArtistInfo
alias MusicLibrary.{Artists, Records}
diff --git a/lib/music_library_web/live/artist_live/show.html.heex b/lib/music_library_web/live/artist_live/show.html.heex
index 0644cd47..0d0d4f46 100644
--- a/lib/music_library_web/live/artist_live/show.html.heex
+++ b/lib/music_library_web/live/artist_live/show.html.heex
@@ -6,32 +6,8 @@
<.country_flag country={@country} />
-
-
- <.focus_wrap
- id={"actions-#{@artist.musicbrainz_id}"}
- class={[
- "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
- ]}
- role="menu"
- aria-orientation="vertical"
- aria-labelledby="options-menu-0-button"
- phx-click-away={close_actions_menu(@artist.musicbrainz_id)}
- >
+ <.actions_menu id={@artist.musicbrainz_id} background_container_target="#records > li">
+ <:links>
<.link
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
role="menuitem"
@@ -63,8 +39,8 @@
/>
{gettext("Refresh info")}
-
-
+
+
diff --git a/lib/music_library_web/live/collection_live/show.ex b/lib/music_library_web/live/collection_live/show.ex
index 5d5d3503..592fe142 100644
--- a/lib/music_library_web/live/collection_live/show.ex
+++ b/lib/music_library_web/live/collection_live/show.ex
@@ -3,8 +3,6 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
import MusicLibraryWeb.RecordComponents,
only: [
- toggle_actions_menu: 1,
- close_actions_menu: 1,
format_label: 1,
type_label: 1,
release_summary: 1
diff --git a/lib/music_library_web/live/collection_live/show.html.heex b/lib/music_library_web/live/collection_live/show.html.heex
index b112d5f6..50bb2e59 100644
--- a/lib/music_library_web/live/collection_live/show.html.heex
+++ b/lib/music_library_web/live/collection_live/show.html.heex
@@ -28,32 +28,8 @@
)} · {type_label(@record.type)}
-
-
- <.focus_wrap
- id={"actions-#{@record.id}"}
- class={[
- "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
- ]}
- role="menu"
- aria-orientation="vertical"
- aria-labelledby="options-menu-0-button"
- phx-click-away={close_actions_menu(@record.id)}
- >
+ <.actions_menu id={@record.id} background_container_target="#records > li">
+ <:links>
<.link
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
role="menuitem"
@@ -134,8 +110,8 @@
/>
{gettext("Delete")}
-
-
+
+
<%!-- TODO: replace with OSS version --%>
diff --git a/lib/music_library_web/live/stats_live/index.ex b/lib/music_library_web/live/stats_live/index.ex
index fd59a661..5e2a24e8 100644
--- a/lib/music_library_web/live/stats_live/index.ex
+++ b/lib/music_library_web/live/stats_live/index.ex
@@ -216,16 +216,6 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|> DateTime.to_iso8601()
end
- defp toggle_actions_menu(track_id) do
- JS.toggle(to: "#actions-#{track_id}")
- |> JS.toggle_class("pointer-events-none", to: "#scrobble-activity > li")
- end
-
- defp close_actions_menu(track_id) do
- JS.hide(to: "#actions-#{track_id}")
- |> JS.remove_class("pointer-events-none", to: "#scrobble-activity > li")
- end
-
defp resolve_timezone! do
Application.get_env(:music_library, MusicLibraryWeb)
|> Keyword.fetch!(:timezone)
diff --git a/lib/music_library_web/live/stats_live/index.html.heex b/lib/music_library_web/live/stats_live/index.html.heex
index 9c21cd9c..988b9ba5 100644
--- a/lib/music_library_web/live/stats_live/index.html.heex
+++ b/lib/music_library_web/live/stats_live/index.html.heex
@@ -220,7 +220,7 @@
-
-
-
- <.focus_wrap
- id={"actions-#{album.scrobbled_at_uts}"}
- class={[
- "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
- ]}
- role="menu"
- aria-orientation="vertical"
- aria-labelledby="options-menu-0-button"
- >
+
+ <:links>
<.link
:for={format <- Records.Record.formats()}
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
@@ -275,8 +251,8 @@
>
{format_label(format)}
-
-
+
+
@@ -345,7 +321,7 @@
-
-
-
- <.focus_wrap
- id={"actions-#{track.scrobbled_at_uts}"}
- class={[
- "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
- ]}
- role="menu"
- aria-orientation="vertical"
- aria-labelledby="options-menu-0-button"
- >
+
+ <:links>
<.link
:for={format <- Records.Record.formats()}
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
@@ -400,8 +352,8 @@
>
{format_label(format)}
-
-
+
+
diff --git a/lib/music_library_web/live/wishlist_live/show.ex b/lib/music_library_web/live/wishlist_live/show.ex
index e4594c05..dafbc8bc 100644
--- a/lib/music_library_web/live/wishlist_live/show.ex
+++ b/lib/music_library_web/live/wishlist_live/show.ex
@@ -3,8 +3,6 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
import MusicLibraryWeb.RecordComponents,
only: [
- toggle_actions_menu: 1,
- close_actions_menu: 1,
format_label: 1,
type_label: 1,
release_summary: 1
diff --git a/lib/music_library_web/live/wishlist_live/show.html.heex b/lib/music_library_web/live/wishlist_live/show.html.heex
index 6bd9b5bd..c732ab61 100644
--- a/lib/music_library_web/live/wishlist_live/show.html.heex
+++ b/lib/music_library_web/live/wishlist_live/show.html.heex
@@ -30,32 +30,8 @@
· {format_label(@record.format)} · {type_label(@record.type)}
-
-
- <.focus_wrap
- id={"actions-#{@record.id}"}
- class={[
- "hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-hidden"
- ]}
- role="menu"
- aria-orientation="vertical"
- aria-labelledby="options-menu-0-button"
- phx-click-away={close_actions_menu(@record.id)}
- >
+ <.actions_menu id={@record.id} background_container_target="#records > li">
+ <:links>
<.link
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
role="menuitem"
@@ -156,8 +132,8 @@
/>
{gettext("Delete")}
-
-
+
+
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot
index d85c8edc..ffe3fb5e 100644
--- a/priv/gettext/default.pot
+++ b/priv/gettext/default.pot
@@ -123,10 +123,7 @@ msgstr ""
msgid "No results"
msgstr ""
-#: lib/music_library_web/components/record_components.ex
-#: lib/music_library_web/live/artist_live/show.html.heex
-#: lib/music_library_web/live/collection_live/show.html.heex
-#: lib/music_library_web/live/wishlist_live/show.html.heex
+#: lib/music_library_web/components/core_components.ex
#, elixir-autogen, elixir-format
msgid "Open options"
msgstr ""
@@ -283,7 +280,6 @@ msgstr ""
msgid "Scrobble activity"
msgstr ""
-#: lib/music_library_web/components/add_record_component.ex
#: lib/music_library_web/live/stats_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Choose which format to import"
diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po
index e77950ef..336768bf 100644
--- a/priv/gettext/en/LC_MESSAGES/default.po
+++ b/priv/gettext/en/LC_MESSAGES/default.po
@@ -123,10 +123,7 @@ msgstr ""
msgid "No results"
msgstr ""
-#: lib/music_library_web/components/record_components.ex
-#: lib/music_library_web/live/artist_live/show.html.heex
-#: lib/music_library_web/live/collection_live/show.html.heex
-#: lib/music_library_web/live/wishlist_live/show.html.heex
+#: lib/music_library_web/components/core_components.ex
#, elixir-autogen, elixir-format
msgid "Open options"
msgstr ""
@@ -283,7 +280,6 @@ msgstr ""
msgid "Scrobble activity"
msgstr ""
-#: lib/music_library_web/components/add_record_component.ex
#: lib/music_library_web/live/stats_live/index.html.heex
#, elixir-autogen, elixir-format
msgid "Choose which format to import"