projectTeamAccess.tsx 2.6 KB

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