projectTeamAccess.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import styled from '@emotion/styled';
  2. import Button from 'sentry/components/button';
  3. import {SectionHeading} from 'sentry/components/charts/styles';
  4. import Collapsible from 'sentry/components/collapsible';
  5. import IdBadge from 'sentry/components/idBadge';
  6. import Link from 'sentry/components/links/link';
  7. import Placeholder from 'sentry/components/placeholder';
  8. import {IconOpen} from 'sentry/icons';
  9. import {t, tn} from 'sentry/locale';
  10. import space from 'sentry/styles/space';
  11. import {Organization, Project} from 'sentry/types';
  12. import {SectionHeadingLink, SectionHeadingWrapper, SidebarSection} from './styles';
  13. type Props = {
  14. organization: Organization;
  15. project?: Project;
  16. };
  17. function ProjectTeamAccess({organization, project}: Props) {
  18. const hasEditPermissions = organization.access.includes('project:write');
  19. const settingsLink = `/settings/${organization.slug}/projects/${project?.slug}/teams/`;
  20. function renderInnerBody() {
  21. if (!project) {
  22. return <Placeholder height="23px" />;
  23. }
  24. if (project.teams.length === 0) {
  25. return (
  26. <Button
  27. to={settingsLink}
  28. disabled={!hasEditPermissions}
  29. title={
  30. hasEditPermissions ? undefined : t('You do not have permission to do this')
  31. }
  32. priority="primary"
  33. size="sm"
  34. >
  35. {t('Assign Team')}
  36. </Button>
  37. );
  38. }
  39. return (
  40. <Collapsible
  41. expandButton={({onExpand, numberOfHiddenItems}) => (
  42. <Button priority="link" onClick={onExpand}>
  43. {tn('Show %s collapsed team', 'Show %s collapsed teams', numberOfHiddenItems)}
  44. </Button>
  45. )}
  46. >
  47. {project.teams
  48. .sort((a, b) => a.slug.localeCompare(b.slug))
  49. .map(team => (
  50. <StyledLink
  51. to={`/settings/${organization.slug}/teams/${team.slug}/`}
  52. key={team.slug}
  53. >
  54. <IdBadge team={team} hideAvatar />
  55. </StyledLink>
  56. ))}
  57. </Collapsible>
  58. );
  59. }
  60. return (
  61. <StyledSidebarSection>
  62. <SectionHeadingWrapper>
  63. <SectionHeading>{t('Team Access')}</SectionHeading>
  64. <SectionHeadingLink to={settingsLink}>
  65. <IconOpen />
  66. </SectionHeadingLink>
  67. </SectionHeadingWrapper>
  68. <div>{renderInnerBody()}</div>
  69. </StyledSidebarSection>
  70. );
  71. }
  72. const StyledSidebarSection = styled(SidebarSection)`
  73. font-size: ${p => p.theme.fontSizeMedium};
  74. `;
  75. const StyledLink = styled(Link)`
  76. display: block;
  77. margin-bottom: ${space(0.5)};
  78. `;
  79. export default ProjectTeamAccess;