diff --git a/ui/src/components/Layout.tsx b/ui/src/components/Layout.tsx
index 5d271b7..25fd0e3 100644
--- a/ui/src/components/Layout.tsx
+++ b/ui/src/components/Layout.tsx
@@ -34,6 +34,7 @@ export function Layout() {
const { username, organizations, currentOrgId } = useOrgStore();
const isVendor = scopes.has('platform:admin');
+ const isTenantAdmin = scopes.has('tenant:manage');
// Determine current org slug for server dashboard link
const currentOrg = organizations.find((o) => o.id === currentOrgId);
@@ -41,7 +42,7 @@ export function Layout() {
// Build breadcrumbs from path
const segments = location.pathname.replace(/^\//, '').split('/').filter(Boolean);
- const breadcrumb = segments.map((seg, i) => {
+ const breadcrumb = segments.map((seg) => {
const label = seg.charAt(0).toUpperCase() + seg.slice(1).replace(/-/g, ' ');
return { label };
});
@@ -67,56 +68,60 @@ export function Layout() {
)}
- {/* Tenant portal */}
- }
- label="Dashboard"
- open={false}
- active={location.pathname === '/tenant'}
- onToggle={() => navigate('/tenant')}
- >
- {null}
-
+ {/* Tenant portal — only visible to tenant admins (tenant:manage scope) */}
+ {isTenantAdmin && (
+ <>
+ }
+ label="Dashboard"
+ open={false}
+ active={location.pathname === '/tenant'}
+ onToggle={() => navigate('/tenant')}
+ >
+ {null}
+
- }
- label="License"
- open={false}
- active={isActive(location, '/tenant/license')}
- onToggle={() => navigate('/tenant/license')}
- >
- {null}
-
+ }
+ label="License"
+ open={false}
+ active={isActive(location, '/tenant/license')}
+ onToggle={() => navigate('/tenant/license')}
+ >
+ {null}
+
- }
- label="OIDC"
- open={false}
- active={isActive(location, '/tenant/oidc')}
- onToggle={() => navigate('/tenant/oidc')}
- >
- {null}
-
+ }
+ label="OIDC"
+ open={false}
+ active={isActive(location, '/tenant/oidc')}
+ onToggle={() => navigate('/tenant/oidc')}
+ >
+ {null}
+
- }
- label="Team"
- open={false}
- active={isActive(location, '/tenant/team')}
- onToggle={() => navigate('/tenant/team')}
- >
- {null}
-
+ }
+ label="Team"
+ open={false}
+ active={isActive(location, '/tenant/team')}
+ onToggle={() => navigate('/tenant/team')}
+ >
+ {null}
+
- }
- label="Settings"
- open={false}
- active={isActive(location, '/tenant/settings')}
- onToggle={() => navigate('/tenant/settings')}
- >
- {null}
-
+ }
+ label="Settings"
+ open={false}
+ active={isActive(location, '/tenant/settings')}
+ onToggle={() => navigate('/tenant/settings')}
+ >
+ {null}
+
+ >
+ )}
o.id === currentOrgId);
+
+ // Vendor → vendor console
if (scopes.has('platform:admin')) {
return ;
}
- return ;
+ // Tenant admin → tenant portal
+ if (scopes.has('tenant:manage')) {
+ return ;
+ }
+ // Regular user (operator/viewer) → server dashboard directly
+ const serverUrl = currentOrg?.slug ? `/t/${currentOrg.slug}/` : '/server/';
+ window.location.href = serverUrl;
+ return null;
}
export function AppRouter() {