attachmentsBadge.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {LinkButton} from 'sentry/components/button';
  4. import {IconAttachment} from 'sentry/icons';
  5. import {t, tn} from 'sentry/locale';
  6. import type {Group} from 'sentry/types/group';
  7. import parseLinkHeader from 'sentry/utils/parseLinkHeader';
  8. import {keepPreviousData} from 'sentry/utils/queryClient';
  9. import {useLocation} from 'sentry/utils/useLocation';
  10. import {Divider} from 'sentry/views/issueDetails/divider';
  11. import {useGroupEventAttachments} from 'sentry/views/issueDetails/groupEventAttachments/useGroupEventAttachments';
  12. import {Tab, TabPaths} from 'sentry/views/issueDetails/types';
  13. import {useGroupDetailsRoute} from 'sentry/views/issueDetails/useGroupDetailsRoute';
  14. export function AttachmentsBadge({group}: {group: Group}) {
  15. const location = useLocation();
  16. const {baseUrl} = useGroupDetailsRoute();
  17. const attachments = useGroupEventAttachments({
  18. groupId: group.id,
  19. activeAttachmentsTab: 'all',
  20. options: {placeholderData: keepPreviousData},
  21. });
  22. const attachmentPagination = parseLinkHeader(
  23. attachments.getResponseHeader?.('Link') ?? null
  24. );
  25. // Since we reuse whatever page the user was on, we can look at pagination to determine if there are more attachments
  26. const hasManyAttachments =
  27. attachmentPagination.next?.results || attachmentPagination.previous?.results;
  28. if (!attachments.attachments.length && !hasManyAttachments) {
  29. return null;
  30. }
  31. return (
  32. <Fragment>
  33. <Divider />
  34. <AttachmentButton
  35. type="button"
  36. priority="link"
  37. size="zero"
  38. icon={<IconAttachment size="xs" />}
  39. to={{
  40. pathname: `${baseUrl}${TabPaths[Tab.ATTACHMENTS]}`,
  41. query: location.query,
  42. replace: true,
  43. }}
  44. aria-label={t("View this issue's attachments")}
  45. >
  46. {hasManyAttachments
  47. ? t('50+ Attachments')
  48. : tn('%s Attachment', '%s Attachments', attachments.attachments.length)}
  49. </AttachmentButton>
  50. </Fragment>
  51. );
  52. }
  53. const AttachmentButton = styled(LinkButton)`
  54. color: ${p => p.theme.gray300};
  55. text-decoration: underline;
  56. text-decoration-style: dotted;
  57. `;