debugIdBundleDetails.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import {Fragment, useMemo, useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Button} from 'sentry/components/button';
  4. import {DateTime} from 'sentry/components/dateTime';
  5. import KeyValueList from 'sentry/components/events/interfaces/keyValueList';
  6. import Link from 'sentry/components/links/link';
  7. import {t} from 'sentry/locale';
  8. import type {KeyValueListData} from 'sentry/types/group';
  9. import type {DebugIdBundle, DebugIdBundleArtifact} from 'sentry/types/sourceMaps';
  10. import useOrganization from 'sentry/utils/useOrganization';
  11. import {makeReleasesPathname} from 'sentry/views/releases/utils/pathnames';
  12. const formatDist = (dist: string | string[] | null) => {
  13. if (Array.isArray(dist)) {
  14. return dist.join(', ');
  15. }
  16. if (dist === null) {
  17. return 'none';
  18. }
  19. return dist;
  20. };
  21. export function DebugIdBundleDetails({
  22. debugIdBundle,
  23. }: {
  24. debugIdBundle: DebugIdBundle | DebugIdBundleArtifact;
  25. }) {
  26. const [showAll, setShowAll] = useState(false);
  27. const organization = useOrganization();
  28. const detailsData = useMemo<KeyValueListData>(() => {
  29. const associations = debugIdBundle.associations;
  30. const visibleAssociations = showAll ? associations : associations.slice(0, 3);
  31. return [
  32. {
  33. key: 'count',
  34. subject: t('Artifacts'),
  35. value: debugIdBundle.fileCount,
  36. },
  37. {
  38. key: 'releases',
  39. subject: t('Associated Releases'),
  40. actionButton: associations.length > 3 && (
  41. <Button size="xs" onClick={() => setShowAll(value => !value)}>
  42. {showAll ? t('Show Less') : t('Show All')}
  43. </Button>
  44. ),
  45. value:
  46. associations.length > 0 ? (
  47. <ReleasesWrapper className="val-string-multiline">
  48. {visibleAssociations.map(association => (
  49. <Fragment key={association.release}>
  50. <Link
  51. to={makeReleasesPathname({
  52. organization,
  53. path: `/${association.release}/`,
  54. })}
  55. >
  56. {association.release}
  57. </Link>
  58. {` (Dist: ${formatDist(association.dist)})`}
  59. <br />
  60. </Fragment>
  61. ))}
  62. </ReleasesWrapper>
  63. ) : (
  64. t('No releases associated with this upload.')
  65. ),
  66. },
  67. {
  68. key: 'date',
  69. subject: t('Date Uploaded'),
  70. value: (
  71. <pre>
  72. <DateTime timeZone year date={debugIdBundle.date} />
  73. </pre>
  74. ),
  75. },
  76. ];
  77. }, [
  78. debugIdBundle.associations,
  79. debugIdBundle.date,
  80. debugIdBundle.fileCount,
  81. organization,
  82. showAll,
  83. ]);
  84. return <StyledKeyValueList data={detailsData} shouldSort={false} />;
  85. }
  86. const ReleasesWrapper = styled('pre')`
  87. max-height: 200px;
  88. overflow-y: auto !important;
  89. `;
  90. const StyledKeyValueList = styled(KeyValueList)`
  91. && {
  92. margin-bottom: 0;
  93. }
  94. `;