diff --git a/lib/ash_admin/components/sidebar.ex b/lib/ash_admin/components/sidebar.ex
index 3ddbab80..2fd3f5b4 100644
--- a/lib/ash_admin/components/sidebar.ex
+++ b/lib/ash_admin/components/sidebar.ex
@@ -12,6 +12,8 @@ defmodule AshAdmin.Components.Sidebar do
attr :domain, :any, required: true
attr :resource, :any, required: true
attr :prefix, :any, required: true
+ attr :host_app_path, :string, default: nil
+ attr :host_app_label, :string, default: nil
attr :open, :boolean, default: false
# Actor/auth/tenant assigns
@@ -61,6 +63,14 @@ defmodule AshAdmin.Components.Sidebar do
>
{AshAdmin.title()}
+ <.link
+ :if={@host_app_path}
+ href={@host_app_path}
+ class="mt-2 flex items-center gap-1 text-sm text-slate-400 hover:text-white transition-colors"
+ >
+
+ {@host_app_label}
+
<%!-- Domain/Resource navigation --%>
diff --git a/lib/ash_admin/pages/page_live.ex b/lib/ash_admin/pages/page_live.ex
index 329cc105..03af4de8 100644
--- a/lib/ash_admin/pages/page_live.ex
+++ b/lib/ash_admin/pages/page_live.ex
@@ -58,6 +58,8 @@ defmodule AshAdmin.PageLive do
{:ok,
socket
|> assign(:prefix, prefix)
+ |> assign(:host_app_path, session["host_app_path"])
+ |> assign(:host_app_label, session["host_app_label"])
|> assign(:primary_key, nil)
|> assign(:record, nil)
|> assign(:domains, domains)
@@ -89,6 +91,8 @@ defmodule AshAdmin.PageLive do
domain={@domain}
resource={@resource}
prefix={@prefix}
+ host_app_path={@host_app_path}
+ host_app_label={@host_app_label}
open={@sidebar_open}
actor={@actor}
actor_domain={@actor_domain}
diff --git a/lib/ash_admin/router.ex b/lib/ash_admin/router.ex
index 0cf2f564..d67de878 100644
--- a/lib/ash_admin/router.ex
+++ b/lib/ash_admin/router.ex
@@ -67,6 +67,11 @@ defmodule AshAdmin.Router do
* `:live_session_name` - Optional atom to name the `live_session`. Defaults to `:ash_admin`.
+ * `:host_app_path` - Optional path to your application. When set, the sidebar shows a link
+ back to it.
+
+ * `:host_app_label` - Optional label for the `:host_app_path` link. Defaults to `"Back to app"`.
+
## Examples
defmodule MyAppWeb.Router do
use Phoenix.Router
@@ -106,7 +111,15 @@ defmodule AshAdmin.Router do
live_session opts[:live_session_name] || :ash_admin,
on_mount: List.wrap(opts[:on_mount]),
session:
- {AshAdmin.Router, :__session__, [%{"prefix" => path}, List.wrap(opts[:session])]},
+ {AshAdmin.Router, :__session__,
+ [
+ %{
+ "prefix" => path,
+ "host_app_path" => opts[:host_app_path],
+ "host_app_label" => opts[:host_app_label] || "Back to app"
+ },
+ List.wrap(opts[:session])
+ ]},
root_layout: {AshAdmin.Layouts, :root} do
live(
"#{path}/*route",
diff --git a/priv/static/assets/app.css b/priv/static/assets/app.css
index 6d94c7a1..ee4ca2cf 100644
--- a/priv/static/assets/app.css
+++ b/priv/static/assets/app.css
@@ -1332,6 +1332,19 @@ select {
margin-bottom: 0;
}
+.hero-arrow-left-mini {
+ --hero-arrow-left-mini: url('data:image/svg+xml;utf8,');
+ -webkit-mask: var(--hero-arrow-left-mini);
+ mask: var(--hero-arrow-left-mini);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ background-color: currentColor;
+ vertical-align: middle;
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
.hero-arrow-left-solid {
--hero-arrow-left-solid: url('data:image/svg+xml;utf8,');
-webkit-mask: var(--hero-arrow-left-solid);
@@ -2399,12 +2412,6 @@ select {
resize: vertical;
}
-.appearance-none {
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
-}
-
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
@@ -3713,11 +3720,6 @@ select {
color: rgb(232 121 249 / var(--tw-text-opacity));
}
-.text-fuchsia-500 {
- --tw-text-opacity: 1;
- color: rgb(217 70 239 / var(--tw-text-opacity));
-}
-
.text-gray-200 {
--tw-text-opacity: 1;
color: rgb(229 231 235 / var(--tw-text-opacity));
@@ -5127,6 +5129,14 @@ main.admin-main::after {
border-top-width: 2px;
}
+.group\/cinder-filter[data-cinder-partial] .group-data-\[cinder-partial\]\/cinder-filter\:visible {
+ visibility: visible;
+}
+
+.group\/cinder-filters[data-cinder-partial] .group-data-\[cinder-partial\]\/cinder-filters\:visible {
+ visibility: visible;
+}
+
.phx-submit-loading.phx-submit-loading\:opacity-75 {
opacity: 0.75;
}
@@ -5372,10 +5382,6 @@ main.admin-main::after {
--tw-ring-color: rgb(51 65 85 / var(--tw-ring-opacity));
}
- .dark\:ring-offset-gray-800 {
- --tw-ring-offset-color: #1f2937;
- }
-
.dark\:file\:bg-slate-700::file-selector-button {
--tw-bg-opacity: 1;
background-color: rgb(51 65 85 / var(--tw-bg-opacity));
@@ -5465,11 +5471,6 @@ main.admin-main::after {
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity));
}
- .dark\:focus\:ring-blue-600:focus {
- --tw-ring-opacity: 1;
- --tw-ring-color: rgb(37 99 235 / var(--tw-ring-opacity));
- }
-
.dark\:focus\:ring-blue-800:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(30 64 175 / var(--tw-ring-opacity));
diff --git a/test/page_live_test.exs b/test/page_live_test.exs
index 44eb54dc..298b4f38 100644
--- a/test/page_live_test.exs
+++ b/test/page_live_test.exs
@@ -38,6 +38,26 @@ defmodule AshAdmin.Test.PageLiveTest do
refute html =~ "Ash Admin"
end
+ test "it does not show a host app link when host_app_path is not set", %{conn: conn} do
+ {:ok, view, html} = live(conn, "/api/admin")
+
+ refute html =~ "Back to app"
+ refute has_element?(view, ~s|a[href="/dashboard"]|)
+ end
+
+ test "it shows a link back to the host app when host_app_path is set", %{conn: conn} do
+ {:ok, view, html} = live(conn, "/api/host-app/admin")
+
+ assert html =~ "Back to dashboard"
+ assert has_element?(view, ~s|a[href="/dashboard"]|, "Back to dashboard")
+ end
+
+ test "it uses a default label for the host app link", %{conn: conn} do
+ {:ok, view, _html} = live(conn, "/api/host-app-default/admin")
+
+ assert has_element?(view, ~s|a[href="/dashboard"]|, "Back to app")
+ end
+
test "it renders the schema by default", %{conn: conn} do
{:ok, _view, html} = live(conn, "/api/admin")
diff --git a/test/support/router.ex b/test/support/router.ex
index af42078e..dd385b9d 100644
--- a/test/support/router.ex
+++ b/test/support/router.ex
@@ -31,5 +31,16 @@ defmodule AshAdmin.Test.Router do
live_session_name: :ash_admin_csp_full,
csp_nonce_assign_key: csp_full
)
+
+ ash_admin("/host-app/admin",
+ live_session_name: :ash_admin_host_app,
+ host_app_path: "/dashboard",
+ host_app_label: "Back to dashboard"
+ )
+
+ ash_admin("/host-app-default/admin",
+ live_session_name: :ash_admin_host_app_default,
+ host_app_path: "/dashboard"
+ )
end
end