role.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import * as React from 'react';
  2. import ConfigStore from 'app/stores/configStore';
  3. import {Organization} from 'app/types';
  4. import {isActiveSuperuser} from 'app/utils/isActiveSuperuser';
  5. import {isRenderFunc} from 'app/utils/isRenderFunc';
  6. import withOrganization from 'app/utils/withOrganization';
  7. type RoleRenderProps = {
  8. hasRole: boolean;
  9. };
  10. type ChildrenRenderFn = (props: RoleRenderProps) => React.ReactNode;
  11. type Props = {
  12. /**
  13. * Minimum required role
  14. */
  15. role: string;
  16. /**
  17. * Current Organization
  18. */
  19. organization: Organization;
  20. /**
  21. * If children is a function then will be treated as a render prop and
  22. * passed RoleRenderProps.
  23. *
  24. * The other interface is more simple, only show `children` if user has
  25. * the minimum required role.
  26. */
  27. children: React.ReactNode | ChildrenRenderFn;
  28. };
  29. class Role extends React.Component<Props> {
  30. hasRole() {
  31. const user = ConfigStore.get('user');
  32. const {organization, role} = this.props;
  33. const {availableRoles} = organization;
  34. const currentRole = organization.role ?? '';
  35. if (!user) {
  36. return false;
  37. }
  38. if (isActiveSuperuser()) {
  39. return true;
  40. }
  41. if (!Array.isArray(availableRoles)) {
  42. return false;
  43. }
  44. const roleIds = availableRoles.map(r => r.id);
  45. if (!roleIds.includes(role) || !roleIds.includes(currentRole)) {
  46. return false;
  47. }
  48. const requiredIndex = roleIds.indexOf(role);
  49. const currentIndex = roleIds.indexOf(currentRole);
  50. return currentIndex >= requiredIndex;
  51. }
  52. render() {
  53. const {children} = this.props;
  54. const hasRole = this.hasRole();
  55. if (isRenderFunc<ChildrenRenderFn>(children)) {
  56. return children({hasRole});
  57. }
  58. return hasRole && children ? children : null;
  59. }
  60. }
  61. export default withOrganization(Role);