From 5bc48f7db2bbe56403fb4fcdb7a4ea68be19c140 Mon Sep 17 00:00:00 2001 From: Etienne Lacoursiere Date: Mon, 2 Nov 2026 12:54:47 -0500 Subject: [PATCH 1/2] chore: rebuild assets for cinder 0.18 app.css was not regenerated after the cinder 0.17 -> 0.18 bump. Tailwind scans deps/cinder, so the new cinder-partial filter classes were missing and some unused classes were still present. Co-Authored-By: Claude Opus 5.5 --- priv/static/assets/app.css | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/priv/static/assets/app.css b/priv/static/assets/app.css index 6d94c7a1..3ad43202 100644 --- a/priv/static/assets/app.css +++ b/priv/static/assets/app.css @@ -2399,12 +2399,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 +3707,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 +5116,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 +5369,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 +5458,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)); From bc1968f091756926582170230c23caa00fe89bff Mon Sep 17 00:00:00 2001 From: Etienne Lacoursiere Date: Mon, 2 Nov 2026 12:54:48 -0500 Subject: [PATCH 2/2] feat: add host_app_path option to link back to the host app Adds `:host_app_path` and `:host_app_label` options to the `ash_admin` router macro. When `:host_app_path` is set, the sidebar shows a link back to the host application. `:host_app_label` defaults to "Back to app". Co-Authored-By: Claude Opus 5.5 --- lib/ash_admin/components/sidebar.ex | 10 ++++++++++ lib/ash_admin/pages/page_live.ex | 4 ++++ lib/ash_admin/router.ex | 15 ++++++++++++++- priv/static/assets/app.css | 13 +++++++++++++ test/page_live_test.exs | 20 ++++++++++++++++++++ test/support/router.ex | 11 +++++++++++ 6 files changed, 72 insertions(+), 1 deletion(-) 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 3ad43202..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); 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