traceLink.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import Link from 'sentry/components/links/link';
  4. import QuestionTooltip from 'sentry/components/questionTooltip';
  5. import {generateTraceTarget} from 'sentry/components/quickTrace/utils';
  6. import {IconChevron} from 'sentry/icons';
  7. import {t, tn} from 'sentry/locale';
  8. import {space} from 'sentry/styles/space';
  9. import type {Event} from 'sentry/types';
  10. import {trackAnalytics} from 'sentry/utils/analytics';
  11. import useOrganization from 'sentry/utils/useOrganization';
  12. import {useTraceTimelineEvents} from './useTraceTimelineEvents';
  13. interface TraceLinkProps {
  14. event: Event;
  15. }
  16. export function TraceLink({event}: TraceLinkProps) {
  17. const organization = useOrganization();
  18. const {traceEvents} = useTraceTimelineEvents({event});
  19. const traceTarget = generateTraceTarget(event, organization);
  20. if (!event.contexts?.trace?.trace_id) {
  21. return (
  22. <NoTraceAvailable>
  23. {t('No Trace Available')}
  24. <QuestionTooltip
  25. position="bottom"
  26. size="sm"
  27. title={t(
  28. 'Traces help you understand if there are any issues with other services connected to this event'
  29. )}
  30. />
  31. </NoTraceAvailable>
  32. );
  33. }
  34. return (
  35. <StyledLink
  36. to={traceTarget}
  37. onClick={() => {
  38. trackAnalytics('quick_trace.trace_id.clicked', {
  39. organization,
  40. source: 'issues',
  41. });
  42. }}
  43. >
  44. <span>
  45. {t('View Full Trace')}
  46. {traceEvents.length > 0 && (
  47. <Fragment>
  48. {traceEvents.length >= 100
  49. ? t(' (100+ issues)')
  50. : tn(' (%s issue)', ' (%s issues)', traceEvents.length)}
  51. </Fragment>
  52. )}
  53. </span>
  54. <IconChevron direction="right" size="xs" />
  55. </StyledLink>
  56. );
  57. }
  58. const StyledLink = styled(Link)`
  59. display: flex;
  60. align-items: center;
  61. gap: ${space(0.25)};
  62. line-height: 1.2;
  63. font-size: ${p => p.theme.fontSizeMedium};
  64. svg {
  65. margin-top: 1px;
  66. }
  67. `;
  68. const NoTraceAvailable = styled('span')`
  69. display: flex;
  70. align-items: center;
  71. gap: ${space(0.25)};
  72. line-height: 1.2;
  73. color: ${p => p.theme.subText};
  74. font-size: ${p => p.theme.fontSizeMedium};
  75. svg {
  76. margin-top: 1px;
  77. }
  78. `;