feat: add RBAC hooks and permission-gated components
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
15
ui/src/components/DeploymentStatusBadge.tsx
Normal file
15
ui/src/components/DeploymentStatusBadge.tsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Badge } from '@cameleer/design-system';
|
||||||
|
|
||||||
|
// Badge color values: 'primary' | 'success' | 'warning' | 'error' | 'running' | 'auto'
|
||||||
|
const STATUS_COLORS: Record<string, 'primary' | 'success' | 'warning' | 'error' | 'running' | 'auto'> = {
|
||||||
|
BUILDING: 'warning',
|
||||||
|
STARTING: 'warning',
|
||||||
|
RUNNING: 'running',
|
||||||
|
FAILED: 'error',
|
||||||
|
STOPPED: 'auto',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function DeploymentStatusBadge({ status }: { status: string }) {
|
||||||
|
const color = STATUS_COLORS[status] ?? 'auto';
|
||||||
|
return <Badge label={status} color={color} />;
|
||||||
|
}
|
||||||
13
ui/src/components/RequirePermission.tsx
Normal file
13
ui/src/components/RequirePermission.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { usePermissions } from '../hooks/usePermissions';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
permission: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
fallback?: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RequirePermission({ permission, children, fallback }: Props) {
|
||||||
|
const { has } = usePermissions();
|
||||||
|
if (!has(permission)) return fallback ? <>{fallback}</> : null;
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
||||||
27
ui/src/hooks/usePermissions.ts
Normal file
27
ui/src/hooks/usePermissions.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { useAuthStore } from '../auth/auth-store';
|
||||||
|
|
||||||
|
const ROLE_PERMISSIONS: Record<string, string[]> = {
|
||||||
|
OWNER: ['tenant:manage', 'billing:manage', 'team:manage', 'apps:manage', 'apps:deploy', 'secrets:manage', 'observe:read', 'observe:debug', 'settings:manage'],
|
||||||
|
ADMIN: ['team:manage', 'apps:manage', 'apps:deploy', 'secrets:manage', 'observe:read', 'observe:debug', 'settings:manage'],
|
||||||
|
DEVELOPER: ['apps:deploy', 'secrets:manage', 'observe:read', 'observe:debug'],
|
||||||
|
VIEWER: ['observe:read'],
|
||||||
|
};
|
||||||
|
|
||||||
|
export function usePermissions() {
|
||||||
|
const roles = useAuthStore((s) => s.roles);
|
||||||
|
|
||||||
|
const permissions = new Set<string>();
|
||||||
|
for (const role of roles) {
|
||||||
|
const perms = ROLE_PERMISSIONS[role];
|
||||||
|
if (perms) perms.forEach((p) => permissions.add(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
has: (permission: string) => permissions.has(permission),
|
||||||
|
canManageApps: permissions.has('apps:manage'),
|
||||||
|
canDeploy: permissions.has('apps:deploy'),
|
||||||
|
canManageTenant: permissions.has('tenant:manage'),
|
||||||
|
canViewObservability: permissions.has('observe:read'),
|
||||||
|
roles,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user