Skip to content

Web/elements/single shadowdom sidebar - #27139

Open
kensternberg-authentik wants to merge 9 commits into
web/elements/sidebar-api-disconnectfrom
web/elements/single-shadowdom-sidebar
Open

kensternberg-authentik wants to merge 9 commits into
web/elements/sidebar-api-disconnectfrom
web/elements/single-shadowdom-sidebar

Conversation

@kensternberg-authentik

Copy link
Copy Markdown
Contributor

web/admin: Make Sidebar a wholly coherent and independent entity

This commit revises how Sidebar works.

I introduce a new type that the Sidebar understands: SidebarItem:

export interface SidebarItem {
    label: string;
    key: string;
    expanded?: boolean;
    path?: string | null;
    notice?: string | TemplateResult | null;
    children?: SidebarItem[];
}

Sidebar changes

This type is meant to drive the Sidebar alone, independent of the needs of any client code (although it is, obviously, good enough to support ak-interface-admin).

I revise Sidebar to be the whole component; no SidebarItem renderer, no slots. The container into which it is rendered is the client code’s responsibility. There are two levels of rendering: the Groups and the Items, and right now they’re only distinguished by “Does it have children?” There were four renderers in SidebarItem, and two of them are gone since they were unused.

I have deliberately left room to revise this again so that a second-level can support a path and children. I have an idea for what to do with it.

The CSS has entirely been brought in to handle a single sidebar.

Sidebar Session Persistence

This is entirely in a controller now; it only needs to be included to do its magic, and it works quite well. I have also revised the very long function names in expansion.ts and treat the entire file as a single namespace. The names are shorter and more readable, and can be imported with the * as SidebarExpansion syntax to support the full namespace.

This makes Sidebar Session Persistence swappable with a Sidebar Device Persistence (using localStorage), should we so desire.

Functions in expansion that no one was using have been deleted. YAGNI forever.

Navigation

sidebarEntries.ts

The navigation folder is split: the Entries file was always meant to be an easy-to-find collection of all the Entries, and nothing more, the Entries themselves were meant to be easily editable and fit within a visually informative table. All the tooling cluttered that. With one exception, all tooling has been mooved to the Tools file. That exception is a tool, here, that will either hand you a “plain” SidebarEntries, or a “can enterprise” SidebarEntries, based on a flag. That logic does not belong in the Interface file.

sidebarTools.ts

Contains two separate units: one converts the SidebarEntries collection into a SidebarItems collection fit for sending to the Sidebar. The others (a) assists the Interface in finding the right key to send to the Sidebar for the current path, and (b) assists the header in filling out the page title.

Due to some of the needs in the Interface, resolveSidebarItems is an ExtendedSidebarItem; it has extra fields to help the CommandPalette. The shape passed to Sidebar is an unchanged SidebarItem.

Interface

The palette code is revised to understand the new ExtendedSidebarItem format.

The ak-page-navbar and ak-sidebar calls have been revised to take the new format. The values are derived at the beginning of the render() function to avoid multiple calls to the resolvers.


Checklist

  • [🥃] The project has been linted, built, and tested (make all)
  • [🥃] The documentation has been updated and formatted (make docs)
  • [🥃] I have read the AI usage policy.

…single-shadowdom-sidebar

* web/elements/sidebar-api-disconnect: (28 commits)
  Fix some merge issues.
  The test exists and passes.
  Moving the load of the AdminOverviewPage to the entrypoint. The idea is to have the dashboard as live as possible as early as possible.  Putting into Routes made Routes into a browser-only feature, and it could not be unit tested without this move.
  web/elements: test that ak-mdx does not evaluate API-supplied content (#24524)
  root: require Node.js 24.22.1 (#27093)
  Formatter opinions.
  That side effect infected downstream tests. Darnit.
  web/admin: Simplify sidebar entries handling
  website/docs: change routing info after 2026.8 changes (#27109)
  core: bump astral-sh/uv from 0.13.4 to 0.13.5 in /lifecycle/container (#27096)
  flows: avoid saving plan history when inspector inaccessible (#27089)
  core: bump pyo3 from 0.29.0 to 0.30.1 (#27099)
  core: bump arc-swap from 1.9.2 to 1.9.3 (#27098)
  core: bump pyroscope-io from 1.2.5 to 1.3.0 (#27100)
  core: bump pyo3-build-config from 0.29.0 to 0.30.1 (#27097)
  core: bump dexidp/dex from v2.46.0 to v2.46.1 in /tests/e2e (#27095)
  website/integrations: VCF 9: touch up (#27094)
  lifecycle/container: add a distroless version of the server image (#26321)
  ci: run tests in the server image (#26510)
  packages/client-ts: Generate imports with `.js` extensions (#27029)
  ...
…single-shadowdom-sidebar

* web/elements/sidebar-api-disconnect:
  Replace aria wayfinders used for testing with Open UI Automation identifiers.
  web/element: Move the SidebarVersion out of Elements.
  .
  .
  The test exists and passes.
  Moving the load of the AdminOverviewPage to the entrypoint. The idea is to have the dashboard as live as possible as early as possible.  Putting into Routes made Routes into a browser-only feature, and it could not be unit tested without this move.
  Formatter opinions.
  That side effect infected downstream tests. Darnit.
  web/admin: Simplify sidebar entries handling
  website/docs: remove xattr workaround for agent (#27128)
  web/elements: make ak-toggle-group akForm-compatible and form-associated (#27092)
  root: bump ctutils (#27129)
  web/elements: make toggle group usable as input field (#27061)
  sources/ldap: fix password write error message (#27076)
  core, web: update translations (#27123)
  core: bump cachetools from 7.2.3 to 7.2.4 (#27125)
  sources/saml: log response processing errors and show users a generic message (#27012)
  sources/saml: Tell IDP to use AES256-GCM by default (#27010)
  website/docs: fix mention of saml 1.1 assertion support for ws-fed (#27113)
This commit revises how Sidebar works.

I introduce a new type that the Sidebar understands: `SidebarItem`:

``` javascript
export interface SidebarItem {
    label: string;
    key: string;
    expanded?: boolean;
    path?: string | null;
    notice?: string | TemplateResult | null;
    children?: SidebarItem[];
}
```

## Sidebar changes

This type is meant to drive the Sidebar alone, independent of the needs of any client code (although it is, obviously, good enough to support ak-interface-admin).

I revise `Sidebar` to be the whole component; no SidebarItem renderer, no slots. The container into which it is rendered is the client code’s responsibility. There are two levels of rendering: the Groups and the Items, and right now they’re only distinguished by “Does it have children?” There were four renderers in SidebarItem, and two of them are gone since they were unused.

I have deliberately left room to revise this again so that a second-level can support a path *and* children. I have an idea for what to do with it.

The CSS has entirely been brought in to handle a single sidebar.

## Sidebar Session Persistence

This is entirely in a controller now; it only needs to be included to do its magic, and it works quite well. I have also revised the very long function names in `expansion.ts` and treat the entire file as a single namespace. The names are shorter and more readable, and can be imported with the `* as SidebarExpansion` syntax to support the full namespace.

This makes Sidebar Session Persistence swappable with a Sidebar Device Persistence (using `localStorage`), should we so desire.

Functions in `expansion` that no one was using have been deleted. YAGNI forever.

## Navigation

*`sidebarEntries.ts`*

The navigation folder is split: the `Entries` file was always meant to be an easy-to-find collection of all the *Entries*, and nothing more, the Entries themselves were meant to be easily editable and fit within a visually informative table. All the tooling cluttered that. With one exception, all tooling has been mooved to the `Tools` file. That exception is a tool, *here*, that will either hand you a “plain” SidebarEntries, or a “can enterprise” SidebarEntries, based on a flag. That logic does not belong in the Interface file.

*`sidebarTools.ts`*

Contains two separate units: one converts the `SidebarEntries` collection into a `SidebarItems` collection fit for sending to the Sidebar. The others (a) assists the Interface in finding the right key to send to the Sidebar for the current path, and (b) assists the header in filling out the page title.

Due to some of the needs in the Interface, `resolveSidebarItems` is an `ExtendedSidebarItem`; it has extra fields to help the CommandPalette. The shape passed to Sidebar is an unchanged `SidebarItem`.

## Interface

The palette code is revised to understand the new `ExtendedSidebarItem` format.

The `ak-page-navbar` and `ak-sidebar` calls have been revised to take the new format. The values are derived at the beginning of the `render()` function to avoid multiple calls to the resolvers.
@kensternberg-authentik
kensternberg-authentik changed the base branch from main to web/elements/sidebar-api-disconnect October 23, 2026 21:24
@netlify

netlify Bot commented Oct 23, 2026

Copy link
Copy Markdown

✅ Deploy Preview for authentik-storybook ready!

Name Link
🔨 Latest commit f7dc984
🔍 Latest deploy log https://app.netlify.com/projects/authentik-storybook/deploys/6adbd073f68b9e75ae40354b
😎 Deploy Preview https://deploy-preview-27139--authentik-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Oct 23, 2026

Copy link
Copy Markdown

✅ Deploy Preview for authentik-docs ready!

Name Link
🔨 Latest commit f7dc984
🔍 Latest deploy log https://app.netlify.com/projects/authentik-docs/deploys/6adbd0737b88567356b9a779
😎 Deploy Preview https://deploy-preview-27139--authentik-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread web/src/admin/navigation/sidebar.unit.test.ts Outdated
}

if (children) {
item.children = resolveSidebarEntries(children ?? [], { licensed, canEnterprise });
@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 49.85%. Comparing base (33adf57) to head (f7dc984).
✅ All tests successful. No failed tests found.

❗ There is a different number of reports uploaded between BASE (33adf57) and HEAD (f7dc984). Click for more details.

HEAD has 54 uploads less than BASE
Flag BASE (33adf57) HEAD (f7dc984)
unit 19 3
integration 1 0
conformance 7 0
unit-migrate 19 0
e2e 11 0
Additional details and impacted files
@@                           Coverage Diff                            @@
##           web/elements/sidebar-api-disconnect   #27139       +/-   ##
========================================================================
- Coverage                                95.11%   49.85%   -45.27%     
========================================================================
  Files                                     1152     1190       +38     
  Lines                                    75862    80258     +4396     
  Branches                                     0     4351     +4351     
========================================================================
- Hits                                     72157    40009    -32148     
- Misses                                    3705    40183    +36478     
- Partials                                     0       66       +66     
Flag Coverage Δ
conformance ?
e2e ?
integration ?
rust 44.42% <ø> (?)
unit 50.16% <ø> (-43.90%) ⬇️
unit-migrate ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

],
]];

export function createAdminSidebarEntries(needsEnterprise: boolean) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same function name as before, only it does the whole job, depending on the flag passed in. So now only the Interface needs to know the enterprise flag.

grid-area: header;
}

ak-sidebar-item:active ak-sidebar-item::part(list-item),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved into the sidebar proper.

),
);
},
action: () => navigate(path!),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this information is pre-processed now in the resolver that converts SidebarEntries into SidebarItems; we just have to use it now.

@kensternberg-authentik
kensternberg-authentik marked this pull request as ready for review October 23, 2026 21:33
@kensternberg-authentik
kensternberg-authentik requested a review from a team as a code owner October 23, 2026 21:33
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Playwright e2e

Download this run's HTML report and traces, then open the report:

gh run download 40026484025 -D playwright-artifacts
npx playwright show-report playwright-artifacts/playwright-report

Installation instructions

Instructions for docker-compose

Add the following block to your .env file:

AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
AUTHENTIK_TAG=gh-f7dc9841272931b6231369b221bb3263d5fada9a
# Distroless image: AUTHENTIK_TAG=gh-f7dc9841272931b6231369b221bb3263d5fada9a-distroless
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s

Afterwards, run the upgrade commands from the latest release notes.

Instructions for Kubernetes

Add the following block to your values.yml file:

authentik:
    outposts:
        container_image_base: ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
global:
    image:
        repository: ghcr.io/goauthentik/dev-server
        tag: gh-f7dc9841272931b6231369b221bb3263d5fada9a
        # Distroless image: tag: gh-f7dc9841272931b6231369b221bb3263d5fada9a-distroless

Afterwards, run the upgrade commands from the latest release notes.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant