From 879cef62f1c6f4b4693ab93f7bf0aef8a4f03e47 Mon Sep 17 00:00:00 2001 From: timujeen Date: Sun, 15 Mar 2026 20:22:16 +0000 Subject: [PATCH] Show not-installed packages on Modules page with install instructions --- lib/phoenix_kit/module_registry.ex | 28 +++++++++++++ lib/phoenix_kit_web/live/modules.ex | 2 + lib/phoenix_kit_web/live/modules.html.heex | 48 ++++++++++++++++------ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/lib/phoenix_kit/module_registry.ex b/lib/phoenix_kit/module_registry.ex index d8c494511..e0698e0ff 100644 --- a/lib/phoenix_kit/module_registry.ex +++ b/lib/phoenix_kit/module_registry.ex @@ -213,6 +213,18 @@ defmodule PhoenixKit.ModuleRegistry do end) end + @doc """ + Returns known external PhoenixKit packages that are not currently installed. + + Used by the admin Modules page to inform users about available packages + they can add as dependencies. + """ + @spec not_installed_packages() :: [map()] + def not_installed_packages do + known_external_packages() + |> Enum.reject(fn pkg -> Code.ensure_loaded?(pkg.module) end) + end + @doc "Returns all feature module key strings from registered modules." @spec all_feature_keys() :: [String.t()] def all_feature_keys do @@ -413,6 +425,22 @@ defmodule PhoenixKit.ModuleRegistry do ] end + # Known external PhoenixKit packages. Listed here so the admin Modules page + # can show "not installed" cards for packages the user hasn't added yet. + defp known_external_packages do + [ + %{ + module: PhoenixKit.Modules.Newsletters, + hex_package: "phoenix_kit_newsletters", + name: "Newsletters", + description: + "Email newsletter management with list subscriptions, broadcast campaigns, and delivery tracking.", + icon: "📧", + hex_url: "https://hex.pm/packages/phoenix_kit_newsletters" + } + ] + end + defp warn_duplicate_tab_ids(tabs) do tabs |> Enum.map(& &1.id) diff --git a/lib/phoenix_kit_web/live/modules.ex b/lib/phoenix_kit_web/live/modules.ex index dec2bf10b..985bcd526 100644 --- a/lib/phoenix_kit_web/live/modules.ex +++ b/lib/phoenix_kit_web/live/modules.ex @@ -31,6 +31,7 @@ defmodule PhoenixKitWeb.Live.Modules do external_modules = load_external_modules(module_configs) dep_warnings = ModuleRegistry.dependency_warnings() + not_installed = ModuleRegistry.not_installed_packages() socket = socket @@ -40,6 +41,7 @@ defmodule PhoenixKitWeb.Live.Modules do |> assign(:module_configs, module_configs) |> assign(:external_modules, external_modules) |> assign(:dep_warnings, dep_warnings) + |> assign(:not_installed_packages, not_installed) {:ok, socket} end diff --git a/lib/phoenix_kit_web/live/modules.html.heex b/lib/phoenix_kit_web/live/modules.html.heex index 9bfd6c36d..d1bcf1570 100644 --- a/lib/phoenix_kit_web/live/modules.html.heex +++ b/lib/phoenix_kit_web/live/modules.html.heex @@ -1422,21 +1422,43 @@ <% end %> - <%!-- Future Modules Section --%> -
-
-
-
📦
-

- More Modules Coming Soon -

-

- Additional system modules and extensions will be available here as they're developed. - Each module will have its own dedicated configuration page for scalable management. -

+ <%!-- Available Packages (known but not installed) --%> + <%= if @not_installed_packages != [] do %> +
+

Available Packages

+
+ <%= for pkg <- @not_installed_packages do %> +
+
+
+
{pkg.icon}
+
+

{pkg.name}

+

{pkg.description}

+
+
+ +
+ + + +
+

Add to mix.exs:

+ + {~s|{:#{pkg.hex_package}, "~> 0.1"}|} + +
+
+
+ <% end %>
-
+ <% end %> <%!-- Module Management Help --%>