releaseCardCommits.tsx 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import {useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import AvatarList from 'sentry/components/avatar/avatarList';
  4. import {t, tn} from 'sentry/locale';
  5. import {space} from 'sentry/styles/space';
  6. import type {Actor} from 'sentry/types/core';
  7. import type {Release} from 'sentry/types/release';
  8. import type {User} from 'sentry/types/user';
  9. import {uniqueId} from 'sentry/utils/guid';
  10. type Props = {
  11. release: Release;
  12. withHeading: boolean;
  13. };
  14. function ReleaseCardCommits({release, withHeading = true}: Props) {
  15. const commitCount = release.commitCount || 0;
  16. const authorCount = release.authors?.length || 0;
  17. const authors = useMemo(
  18. () =>
  19. release.authors.map<Actor | User>(author =>
  20. // Add a unique id if missing
  21. ({
  22. ...author,
  23. type: 'user',
  24. id: 'id' in author ? author.id : uniqueId(),
  25. })
  26. ),
  27. [release.authors]
  28. );
  29. if (commitCount === 0) {
  30. return null;
  31. }
  32. const releaseSummary = [
  33. tn('%s commit', '%s commits', commitCount),
  34. t('by'),
  35. tn('%s author', '%s authors', authorCount),
  36. ].join(' ');
  37. return (
  38. <div className="release-stats">
  39. {withHeading && <ReleaseSummaryHeading>{releaseSummary}</ReleaseSummaryHeading>}
  40. <span style={{display: 'inline-block'}}>
  41. <AvatarList users={authors} avatarSize={25} typeAvatars="authors" />
  42. </span>
  43. </div>
  44. );
  45. }
  46. const ReleaseSummaryHeading = styled('div')`
  47. color: ${p => p.theme.gray300};
  48. font-size: ${p => p.theme.fontSizeSmall};
  49. line-height: 1.2;
  50. font-weight: ${p => p.theme.fontWeightBold};
  51. text-transform: uppercase;
  52. margin-bottom: ${space(0.5)};
  53. `;
  54. export default ReleaseCardCommits;