fix: vendor scoping, sidebar visibility, and landing redirect
- OrgResolver merges global + org-scoped token scopes so vendor's platform:admin (from global saas-vendor role) is always visible - LandingRedirect waits for scopes to load before redirecting (prevents premature redirect to server dashboard) - Layout hides tenant portal sidebar items when vendor is on /vendor/* routes; shows them when navigating to tenant context Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,9 @@ export function Layout() {
|
|||||||
|
|
||||||
const isVendor = scopes.has('platform:admin');
|
const isVendor = scopes.has('platform:admin');
|
||||||
const isTenantAdmin = scopes.has('tenant:manage');
|
const isTenantAdmin = scopes.has('tenant:manage');
|
||||||
|
const onVendorRoute = location.pathname.startsWith('/vendor');
|
||||||
|
// Vendor on vendor routes: show only TENANTS. On tenant routes: show tenant portal too (for debugging).
|
||||||
|
const showTenantPortal = isTenantAdmin && (!isVendor || !onVendorRoute);
|
||||||
|
|
||||||
// Determine current org slug for server dashboard link
|
// Determine current org slug for server dashboard link
|
||||||
const currentOrg = organizations.find((o) => o.id === currentOrgId);
|
const currentOrg = organizations.find((o) => o.id === currentOrgId);
|
||||||
@@ -68,8 +71,8 @@ export function Layout() {
|
|||||||
</Sidebar.Section>
|
</Sidebar.Section>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Tenant portal — only visible to tenant admins (tenant:manage scope) */}
|
{/* Tenant portal — visible to tenant admins; hidden for vendor on vendor routes */}
|
||||||
{isTenantAdmin && (
|
{showTenantPortal && (
|
||||||
<>
|
<>
|
||||||
<Sidebar.Section
|
<Sidebar.Section
|
||||||
icon={<LayoutDashboard size={16} />}
|
icon={<LayoutDashboard size={16} />}
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ function LandingRedirect() {
|
|||||||
const { organizations, currentOrgId } = useOrgStore();
|
const { organizations, currentOrgId } = useOrgStore();
|
||||||
const currentOrg = organizations.find((o) => o.id === currentOrgId);
|
const currentOrg = organizations.find((o) => o.id === currentOrgId);
|
||||||
|
|
||||||
|
// Wait for scopes to be resolved — they're loaded async by OrgResolver.
|
||||||
|
// An empty set means "not yet loaded" (even viewer gets observe:read).
|
||||||
|
if (scopes.size === 0) {
|
||||||
|
return null; // OrgResolver is still fetching tokens
|
||||||
|
}
|
||||||
|
|
||||||
// Vendor → vendor console
|
// Vendor → vendor console
|
||||||
if (scopes.has('platform:admin')) {
|
if (scopes.has('platform:admin')) {
|
||||||
return <Navigate to="/vendor/tenants" replace />;
|
return <Navigate to="/vendor/tenants" replace />;
|
||||||
|
|||||||
Reference in New Issue
Block a user