teamRoleSelect.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import styled from '@emotion/styled';
  2. import {ControlProps} from 'sentry/components/forms/controls/selectControl';
  3. import RoleSelectControl from 'sentry/components/roleSelectControl';
  4. import {space} from 'sentry/styles/space';
  5. import {Organization, Team, TeamMember, TeamRole} from 'sentry/types';
  6. import {getEffectiveOrgRole} from 'sentry/utils/orgRole';
  7. import {
  8. hasOrgRoleOverwrite,
  9. RoleOverwriteIcon,
  10. } from 'sentry/views/settings/organizationTeams/roleOverwriteWarning';
  11. interface Props {
  12. member: TeamMember;
  13. onChangeTeamRole: (newRole: TeamRole['id'] | string) => void;
  14. organization: Organization;
  15. team: Team;
  16. disabled?: boolean;
  17. size?: ControlProps['size'];
  18. }
  19. function TeamRoleSelect({
  20. organization,
  21. team,
  22. member,
  23. onChangeTeamRole,
  24. disabled,
  25. size,
  26. }: Props) {
  27. const {orgRoleList, teamRoleList, features} = organization;
  28. if (!features.includes('team-roles')) {
  29. return null;
  30. }
  31. // Determine the org-role, including if the current team has an org role
  32. // and adding the user to the current team changes their minimum team-role
  33. const possibleOrgRoles = [member.orgRole];
  34. if (member.orgRolesFromTeams && member.orgRolesFromTeams.length > 0) {
  35. possibleOrgRoles.push(member.orgRolesFromTeams[0].role.id);
  36. }
  37. if (team.orgRole) {
  38. possibleOrgRoles.push(team.orgRole);
  39. }
  40. const effectiveOrgRole = getEffectiveOrgRole(possibleOrgRoles, orgRoleList);
  41. // If the member's org-role has elevated permission, their team-role will
  42. // inherit scopes from it
  43. if (hasOrgRoleOverwrite({orgRole: effectiveOrgRole?.id, orgRoleList, teamRoleList})) {
  44. const effectiveTeamRole = teamRoleList.find(
  45. r => r.id === effectiveOrgRole?.minimumTeamRole
  46. );
  47. return (
  48. <RoleName>
  49. {effectiveTeamRole?.name || effectiveOrgRole?.minimumTeamRole}
  50. <IconWrapper>
  51. <RoleOverwriteIcon
  52. orgRole={effectiveOrgRole?.id}
  53. orgRoleList={orgRoleList}
  54. teamRoleList={teamRoleList}
  55. />
  56. </IconWrapper>
  57. </RoleName>
  58. );
  59. }
  60. const teamRoleId =
  61. member.teamRole || // From TeamMemberEndpoint
  62. member.teamRoles.find(tr => tr.teamSlug === team.slug)?.role; // From OrgMemberDetailEndpoint
  63. const teamRole = teamRoleList.find(r => r.id === teamRoleId) || teamRoleList[0];
  64. return (
  65. <RoleSelectControl
  66. disabled={disabled}
  67. disableUnallowed={false}
  68. roles={teamRoleList}
  69. value={teamRole.id}
  70. onChange={option => onChangeTeamRole(option.value)}
  71. size={size}
  72. />
  73. );
  74. }
  75. export default TeamRoleSelect;
  76. const RoleName = styled('div')`
  77. display: flex;
  78. align-items: center;
  79. `;
  80. const IconWrapper = styled('div')`
  81. height: ${space(2)};
  82. margin-left: ${space(1)};
  83. `;