teamRoleSelect.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. const hasTeamRoles = features.includes('team-roles');
  29. // Determine the org-role, including if the current team has an org role
  30. // and adding the user to the current team changes their minimum team-role
  31. const possibleOrgRoles = [member.orgRole];
  32. if (member.groupOrgRoles && member.groupOrgRoles.length > 0) {
  33. possibleOrgRoles.push(member.groupOrgRoles[0].role.id);
  34. }
  35. if (team.orgRole) {
  36. possibleOrgRoles.push(team.orgRole);
  37. }
  38. const effectiveOrgRole = getEffectiveOrgRole(possibleOrgRoles, orgRoleList);
  39. // If the member's org-role has elevated permission, their team-role will
  40. // inherit scopes from it
  41. if (hasOrgRoleOverwrite({orgRole: effectiveOrgRole?.id, orgRoleList, teamRoleList})) {
  42. const effectiveTeamRole = teamRoleList.find(
  43. r => r.id === effectiveOrgRole?.minimumTeamRole
  44. );
  45. return (
  46. <RoleName>
  47. {effectiveTeamRole?.name || effectiveOrgRole?.minimumTeamRole}
  48. <IconWrapper>
  49. <RoleOverwriteIcon
  50. orgRole={effectiveOrgRole?.id}
  51. orgRoleList={orgRoleList}
  52. teamRoleList={teamRoleList}
  53. />
  54. </IconWrapper>
  55. </RoleName>
  56. );
  57. }
  58. const teamRoleId =
  59. member.teamRole || // From TeamMemberEndpoint
  60. member.teamRoles?.find(tr => tr.teamSlug === team.slug)?.role || // From OrgMemberDetailEndpoint
  61. null;
  62. const teamRole = teamRoleList.find(r => r.id === teamRoleId) || teamRoleList[0];
  63. return (
  64. <RoleSelectControl
  65. disabled={disabled || !hasTeamRoles}
  66. disableUnallowed={false}
  67. roles={teamRoleList}
  68. value={teamRole.id}
  69. onChange={option => onChangeTeamRole(option.value)}
  70. size={size}
  71. />
  72. );
  73. }
  74. export default TeamRoleSelect;
  75. const RoleName = styled('div')`
  76. display: flex;
  77. align-items: center;
  78. `;
  79. const IconWrapper = styled('div')`
  80. height: ${space(2)};
  81. margin-left: ${space(1)};
  82. `;