Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ This is **PhoenixKit** - PhoenixKit is a starter kit for building modern web app
### Quick Reference

- **Tabs & Subtabs** - Configurable navigation with parent/child relationships, custom styling, animations
- **Admin Navigation** - Registry-driven admin sidebar with permission gating, dynamic children, and parent app customization via `:admin_dashboard_tabs` config (see `ADMIN_README.md`)
- **Context Selectors** - Organization/team/project switching with dependencies
- **Theme Switcher** - `dashboard_themes` config, auto-renders in header
- **Live Badges** - Real-time badge updates via PubSub
Expand Down Expand Up @@ -662,6 +663,29 @@ See `lib/phoenix_kit/dashboard/README.md` for full documentation. Quick access i
- Single context: `socket.assigns.current_context`
- Multi context: `socket.assigns.current_contexts_map[:key]`

### Admin Dashboard Customization

The admin sidebar uses a registry-driven system with permission gating. See `lib/phoenix_kit/dashboard/ADMIN_README.md` for full documentation.

**Add custom admin tabs from parent app:**

```elixir
config :phoenix_kit, :admin_dashboard_tabs, [
%{
id: :admin_analytics,
label: "Analytics",
icon: "hero-chart-bar",
path: "/admin/analytics",
permission: "dashboard",
priority: 150,
group: :admin_main,
live_view: {MyAppWeb.PhoenixKitLive.AdminAnalyticsLive, :index}
}
]
```

The `live_view` field auto-generates a route inside PhoenixKit's admin `live_session` for seamless navigation. Custom admin LiveViews must use `LayoutWrapper.app_layout` (not `Layouts.dashboard`) and `@url_path` for the current path. See the ADMIN_README for the full LiveView template pattern.

### Dashboard Layout Performance (IMPORTANT)

**Do not pass all assigns to the dashboard layout.** Use `dashboard_assigns/1`:
Expand Down
65 changes: 64 additions & 1 deletion guides/integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,69 @@ Scope.accessible_modules(scope) # MapSet of granted permission keys

---

## Custom Admin Pages

Add custom pages to the PhoenixKit admin sidebar with seamless LiveView navigation.

### Step 1: Create the LiveView

```elixir
# lib/my_app_web/phoenix_kit_live/admin_analytics_live.ex
defmodule MyAppWeb.PhoenixKitLive.AdminAnalyticsLive do
use MyAppWeb, :live_view

def mount(_params, _session, socket) do
{:ok, assign(socket, page_title: "Analytics")}
end

def render(assigns) do
~H"""
<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
page_title={@page_title}
current_path={@url_path}
phoenix_kit_current_scope={@phoenix_kit_current_scope}
current_locale={assigns[:current_locale]}
>
<div class="container flex-col mx-auto px-4 py-6">
<h1 class="text-2xl font-bold mb-6">Analytics</h1>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>
"""
end
end
```

### Step 2: Register the Tab

```elixir
# config/config.exs
config :phoenix_kit, :admin_dashboard_tabs, [
%{
id: :admin_analytics,
label: "Analytics",
icon: "hero-chart-bar",
path: "/admin/analytics",
permission: "dashboard",
priority: 150,
group: :admin_main,
live_view: {MyAppWeb.PhoenixKitLive.AdminAnalyticsLive, :index}
}
]
```

The `live_view` field tells PhoenixKit to auto-generate a route inside the shared admin `live_session`, so navigation from other admin pages is seamless (no full page reload).

**Key rules:**
- Use `@url_path` for `current_path` (set by PhoenixKit's on_mount hooks)
- Use `LayoutWrapper.app_layout` for the admin layout (NOT `Layouts.dashboard`)
- Don't pass `project_title` — the layout has a built-in default
- Use `assigns[:current_locale]` (bracket access for optional assigns)

See the [Admin Navigation docs](../lib/phoenix_kit/dashboard/ADMIN_README.md) for the full reference.

---

## Common Tasks

### Task: Add PhoenixKit Navigation to Your Layout
Expand Down Expand Up @@ -881,4 +944,4 @@ records = PhoenixKit.Entities.EntityData.list_by_entity(entity.id)

---

**Last Updated**: 2026-02-08
**Last Updated**: 2026-02-14
19 changes: 4 additions & 15 deletions lib/modules/publishing/publishing.ex
Original file line number Diff line number Diff line change
Expand Up @@ -344,21 +344,10 @@ defmodule PhoenixKit.Modules.Publishing do
"""
@spec enabled?() :: boolean()
def enabled? do
# Check new key first using get_setting (allows nil default)
case settings_call(:get_setting, [@publishing_enabled_key, nil]) do
nil ->
# Fall back to legacy key
settings_call(:get_boolean_setting, [@legacy_enabled_key, false])

"true" ->
true

true ->
true

_ ->
false
end
# Check new key first, then fall back to legacy key
# Uses get_boolean_setting (cached) to avoid DB queries on every sidebar render
settings_call(:get_boolean_setting, [@publishing_enabled_key, false]) or
settings_call(:get_boolean_setting, [@legacy_enabled_key, false])
end

@doc """
Expand Down
2 changes: 1 addition & 1 deletion lib/phoenix_kit/config/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ defmodule PhoenixKit.Config do
dashboard_context_selectors: nil,
# Subtab styling defaults
dashboard_subtab_style: [
indent: "pl-9",
indent: "pl-4",
icon_size: "w-4 h-4",
text_size: "text-sm",
animation: :none
Expand Down
Loading
Loading