spanSummaryHeader.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import styled from '@emotion/styled';
  2. import {SectionHeading} from 'sentry/components/charts/styles';
  3. import Count from 'sentry/components/count';
  4. import PerformanceDuration from 'sentry/components/performanceDuration';
  5. import {t, tct} from 'sentry/locale';
  6. import {space} from 'sentry/styles/space';
  7. import {defined} from 'sentry/utils';
  8. import {formatMetricUsingUnit} from 'sentry/utils/metrics/formatters';
  9. import {DataTitles} from 'sentry/views/starfish/views/spans/types';
  10. type Props = {
  11. avgDuration: number;
  12. spanCount: number;
  13. spanDescription: string;
  14. spanOp: string;
  15. timeSpent: number;
  16. };
  17. export default function SpanSummaryHeader(props: Props) {
  18. const {spanOp, spanDescription, avgDuration, timeSpent, spanCount} = props;
  19. return (
  20. <ContentHeader>
  21. <HeaderInfo data-test-id="header-operation-name">
  22. <StyledSectionHeading>{t('Span')}</StyledSectionHeading>
  23. <SectionBody>
  24. <SpanLabelContainer>{spanDescription ?? emptyValue}</SpanLabelContainer>
  25. </SectionBody>
  26. <SectionSubtext data-test-id="operation-name">{spanOp}</SectionSubtext>
  27. </HeaderInfo>
  28. <HeaderInfo data-test-id="header-avg-duration">
  29. <StyledSectionHeading>{DataTitles.avg}</StyledSectionHeading>
  30. <NumericSectionWrapper>
  31. <SectionBody>
  32. {defined(avgDuration)
  33. ? formatMetricUsingUnit(avgDuration, 'milliseconds')
  34. : '\u2014'}
  35. </SectionBody>
  36. </NumericSectionWrapper>
  37. </HeaderInfo>
  38. <HeaderInfo data-test-id="header-total-exclusive-time">
  39. <StyledSectionHeading>{DataTitles.timeSpent}</StyledSectionHeading>
  40. <NumericSectionWrapper>
  41. <SectionBody>
  42. {defined(timeSpent) ? (
  43. <PerformanceDuration abbreviation milliseconds={timeSpent} />
  44. ) : (
  45. '\u2014'
  46. )}
  47. </SectionBody>
  48. <SectionSubtext>
  49. {defined(spanCount)
  50. ? tct('[spanCount] spans', {spanCount: <Count value={spanCount} />})
  51. : '\u2014'}
  52. </SectionSubtext>
  53. </NumericSectionWrapper>
  54. </HeaderInfo>
  55. </ContentHeader>
  56. );
  57. }
  58. const ContentHeader = styled('div')`
  59. display: grid;
  60. grid-template-columns: 1fr;
  61. gap: ${space(4)};
  62. margin-bottom: ${space(2)};
  63. @media (min-width: ${p => p.theme.breakpoints.medium}) {
  64. grid-template-columns: 1fr repeat(3, max-content);
  65. }
  66. `;
  67. const HeaderInfo = styled('div')`
  68. ${p => p.theme.overflowEllipsis};
  69. height: 78px;
  70. `;
  71. const StyledSectionHeading = styled(SectionHeading)`
  72. margin: 0;
  73. `;
  74. const NumericSectionWrapper = styled('div')`
  75. text-align: right;
  76. `;
  77. const SectionBody = styled('div')<{overflowEllipsis?: boolean}>`
  78. font-size: ${p => p.theme.fontSizeExtraLarge};
  79. padding: ${space(0.5)} 0;
  80. max-height: 32px;
  81. `;
  82. const SectionSubtext = styled('div')`
  83. color: ${p => p.theme.subText};
  84. font-size: ${p => p.theme.fontSizeMedium};
  85. `;
  86. export const SpanLabelContainer = styled('div')`
  87. ${p => p.theme.overflowEllipsis};
  88. `;
  89. const EmptyValueContainer = styled('span')`
  90. color: ${p => p.theme.gray300};
  91. `;
  92. const emptyValue = <EmptyValueContainer>{t('(unnamed span)')}</EmptyValueContainer>;