import { HoverCard, HoverCardContent, HoverCardTrigger, } from "@/src/components/ui/hover-card"; import { SelectItem } from "@/src/components/ui/select"; import { Role } from "@langfuse/shared"; import { HoverCardPortal } from "@radix-ui/react-hover-card"; import { organizationRoleAccessRights, orgNoneRoleComment, } from "@/src/features/rbac/constants/organizationAccessRights"; import { projectNoneRoleComment, projectRoleAccessRights, } from "@/src/features/rbac/constants/projectAccessRights"; import { orderedRoles } from "@/src/features/rbac/constants/orderedRoles"; export const RoleSelectItem = ({ role, isProjectRole, }: { role: Role; isProjectRole?: boolean; }) => { const isProjectNoneRole = role === Role.NONE && isProjectRole; const isOrgNoneRole = role === Role.NONE && !isProjectRole; const orgScopes = reduceScopesToListItems(organizationRoleAccessRights, role); const projectScopes = reduceScopesToListItems(projectRoleAccessRights, role); return ( {formatRole(role)} {isProjectNoneRole ? " (keep default role)" : ""} {isProjectNoneRole ? (
{projectNoneRoleComment}
) : isOrgNoneRole ? (
{orgNoneRoleComment}
) : ( <>
Role: {formatRole(role)}

Organization Scopes

    {orgScopes}

Project Scopes

    {projectScopes}

Note:{" "} Muted scopes are inherited from lower role.

)}
); }; const reduceScopesToListItems = ( accessRights: Record, role: Role, ) => { const currentRoleLevel = orderedRoles[role]; const lowerRole = Object.entries(orderedRoles).find( ([_role, level]) => level === currentRoleLevel - 1, )?.[0] as Role | undefined; const inheritedScopes = lowerRole ? accessRights[lowerRole] : []; return accessRights[role].length > 0 ? ( <> {Object.entries( accessRights[role].reduce( (acc, scope) => { const [resource, action] = scope.split(":"); if (!acc[resource]) { acc[resource] = []; } acc[resource].push(action); return acc; }, {} as Record, ), ).map(([resource, actions]) => { const inheritedActions = actions.filter((action) => inheritedScopes.includes(`${resource}:${action}`), ); const newActions = actions.filter( (action) => !inheritedScopes.includes(`${resource}:${action}`), ); return (
  • {resource}: {inheritedActions.length > 0 ? inheritedActions.join(", ") : ""} {newActions.length > 0 && inheritedActions.length > 0 ? ", " : ""} {newActions.length > 0 ? newActions.join(", ") : ""}
  • ); })} ) : (
  • None
  • ); }; const formatRole = (role: Role) => role.charAt(0).toUpperCase() + role.slice(1).toLowerCase();