Skip to content

feat(ui): role and deployment-mode adaptive UI (landing, sidebar, top navbar)#10449

Merged
mudler merged 7 commits into
masterfrom
feat/role-mode-adaptive-ui
Jun 22, 2026
Merged

feat(ui): role and deployment-mode adaptive UI (landing, sidebar, top navbar)#10449
mudler merged 7 commits into
masterfrom
feat/role-mode-adaptive-ui

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

What

Make the React UI adapt its landing page, sidebar order, and a new desktop top navbar to the viewer's role (admin vs non-admin) and the deployment mode (single-node, NATS-distributed, or P2P/Swarm), so each kind of user sees an interface scoped to what they actually do. Crucially, this changes only ordering, grouping, collapse state, and the landing redirect: it does not touch any visibility gate.

Why

The UI presented the same shell to everyone. A non-admin end-user just wants to chat but landed on a dashboard-style Home with an operator-shaped sidebar; an admin running a cluster cared first about node health but the cluster lived several clicks deep under Operate > Cluster. This reframes the experience around who is using it and how LocalAI is deployed.

The model (role x mode)

Three signals we already have: useAuth().isAdmin, features.distributed, and a P2P "enabled" signal (a network token exists). Gating stays governed entirely by isConsoleItemVisible() and the existing route guards; the adaptive layer sits on top.

Single-node Distributed (NATS) P2P / Swarm only
Admin Home Nodes page P2P page
Non-admin Chat Chat Chat
  • Landing redirects /app per the precedence distributed > p2p > plain (admins), and to Chat for non-admins (deep-linkable, reuses each target's own guard).
  • Sidebar pins the Operate > Cluster group (Nodes / Scheduling / Swarm) to the top and collapses Create for cluster admins; in a p2p-only deployment only Swarm survives the gate. Single-node and non-admin layouts are unchanged. Swarm stays visible (not pinned) for admins when nothing is enabled, as the onboarding entry.
  • Top navbar (new, desktop-only, complementary to the existing mobile header): admins get a mode pill, an admin-only token-usage glance (links to /app/usage, hides gracefully when there is no data), a settings cog, and an "Admin via chat" quick-jump into the LocalAI Assistant (manage mode); non-admins get a model link plus theme and account.

Changes

  • contexts/DeploymentContext.jsx - one shared fetch of /api/features + the P2P token; replaces the per-component /api/features fetches.
  • utils/resolveHome.js + components/HomeRoute.jsx - pure resolver + index-route element that waits for both auth and deployment signals, then renders Home or redirects.
  • utils/sidebarPolicy.js + Sidebar.jsx - cluster-pin and Create-collapse policy (filtered through the existing isConsoleItemVisible).
  • components/TopNavbar.jsx + components/navbar/TokenUsageMeter.jsx + App.jsx/App.css - the desktop bar and admin meter.
  • utils/launchAssistantChat.js - shared "open a fresh chat in assistant mode" action, reused by the Home CTA and the navbar (re-triggerable from the chat page via a localai-open-assistant event).

Testing

  • npm run lint: no new errors (holds at the pre-existing master baseline); npm run build passes.
  • Playwright render-smoke specs added in e2e/role-mode-adaptive.spec.js (landing per cell, cluster pin, navbar variants, token-meter graceful degrade). These were authored and parse/lint clean but were not run locally (the fresh worktree lacks generated proto for the e2e Go server and port 8089 was held by another service); CI runs the full suite on this PR.

Follow-ups (deferred, cosmetic)

  • Home.jsx still fetches /api/features directly (could move to useDeployment()); it only renders for admin single-node now.
  • TopNavbar shows a brief non-admin variant during the initial auth/deploy load (cosmetic flash).
  • sidebarPolicy.loadSectionState(collapseCreate) has a vestigial parameter branch (the effect does the real work).

Design doc: docs/superpowers/specs/2026-06-22-role-mode-adaptive-ui-design.md (kept local, not committed).

Assisted-by: Claude Opus 4.8 (Claude Code). The submitter has reviewed and is responsible for every line.

mudler added 7 commits June 22, 2026 17:14
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
M1: the desktop .top-navbar was hidden at max-width 768px while the
.mobile-header only appears at max-width 639px, leaving 640-768px with
neither bar so admins lost the mode pill, token meter and admin-via-chat
jump. Hide the top bar at 639px instead so it covers every width the rail
sidebar is shown and hands off to the mobile-header exactly at 639px.

M2: the navbar 'Admin via chat' button wrote localStorage and called
navigate('/app/chat'), but when already on the chat page Chat does not
remount so its mount-time payload reader never fired and the click was a
no-op until reload. The payload consume logic is factored into a shared
callback; the launcher now dispatches a localai-open-assistant event that
the mounted Chat listens for to re-consume the payload. Mount behavior is
unchanged.

Assisted-by: Claude:claude-opus-4-8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
@mudler mudler merged commit 9d54a59 into master Jun 22, 2026
60 checks passed
@mudler mudler deleted the feat/role-mode-adaptive-ui branch June 22, 2026 19:27
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.

2 participants