1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- import {useMemo} from 'react';
- import type {Organization} from 'sentry/types/organization';
- import type {User} from 'sentry/types/user';
- import {isActiveSuperuser} from 'sentry/utils/isActiveSuperuser';
- import {isRenderFunc} from 'sentry/utils/isRenderFunc';
- import {useUser} from 'sentry/utils/useUser';
- import withOrganization from 'sentry/utils/withOrganization';
- type RoleRenderProps = {
- hasRole: boolean;
- };
- type ChildrenRenderFn = (props: RoleRenderProps) => React.ReactElement | null;
- function checkUserRole(user: User, organization: Organization, role: RoleProps['role']) {
- if (!user) {
- return false;
- }
- if (isActiveSuperuser()) {
- return true;
- }
- if (!Array.isArray(organization.orgRoleList)) {
- return false;
- }
- const roleIds = organization.orgRoleList.map(r => r.id);
- if (!roleIds.includes(role) || !roleIds.includes(organization.orgRole ?? '')) {
- return false;
- }
- const requiredIndex = roleIds.indexOf(role);
- const currentIndex = roleIds.indexOf(organization.orgRole ?? '');
- return currentIndex >= requiredIndex;
- }
- interface RoleProps {
- /**
- * If children is a function then will be treated as a render prop and
- * passed RoleRenderProps.
- *
- * The other interface is more simple, only show `children` if user has
- * the minimum required role.
- */
- children: React.ReactElement | ChildrenRenderFn;
- /**
- * Current Organization
- */
- organization: Organization;
- /**
- * Minimum required role
- */
- role: string;
- }
- function Role({role, organization, children}: RoleProps): React.ReactElement | null {
- const user = useUser();
- const hasRole = useMemo(
- () => checkUserRole(user, organization, role),
- // It seems that this returns a stable reference, but
- [organization, role, user]
- );
- if (isRenderFunc<ChildrenRenderFn>(children)) {
- return children({hasRole});
- }
- return hasRole ? children : null;
- }
- const withOrganizationRole = withOrganization(Role);
- export {withOrganizationRole as Role};
|