12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import {useMemo} from 'react';
- import ConfigStore from 'sentry/stores/configStore';
- import {Organization, User} from 'sentry/types';
- import {isActiveSuperuser} from 'sentry/utils/isActiveSuperuser';
- import {isRenderFunc} from 'sentry/utils/isRenderFunc';
- 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.role ?? '')) {
- return false;
- }
- const requiredIndex = roleIds.indexOf(role);
- const currentIndex = roleIds.indexOf(organization.role ?? '');
- 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 = ConfigStore.get('user');
- 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};
|