spanSummaryHeader.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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 data-test-id="header-span-description">
  25. {spanDescription ? spanDescription : emptyValue}
  26. </SpanLabelContainer>
  27. </SectionBody>
  28. <SectionSubtext data-test-id="operation-name">{spanOp}</SectionSubtext>
  29. </HeaderInfo>
  30. <HeaderInfo data-test-id="header-avg-duration">
  31. <StyledSectionHeading>{DataTitles.avg}</StyledSectionHeading>
  32. <NumericSectionWrapper>
  33. <SectionBody>
  34. {defined(avgDuration)
  35. ? formatMetricUsingUnit(avgDuration, 'milliseconds')
  36. : '\u2014'}
  37. </SectionBody>
  38. </NumericSectionWrapper>
  39. </HeaderInfo>
  40. <HeaderInfo data-test-id="header-total-time-spent">
  41. <StyledSectionHeading>{DataTitles.timeSpent}</StyledSectionHeading>
  42. <NumericSectionWrapper>
  43. <SectionBody>
  44. {defined(timeSpent) ? (
  45. <PerformanceDuration abbreviation milliseconds={timeSpent} />
  46. ) : (
  47. '\u2014'
  48. )}
  49. </SectionBody>
  50. <SectionSubtext data-test-id="total-span-count">
  51. {defined(spanCount)
  52. ? tct('[spanCount] spans', {spanCount: <Count value={spanCount} />})
  53. : '\u2014'}
  54. </SectionSubtext>
  55. </NumericSectionWrapper>
  56. </HeaderInfo>
  57. </ContentHeader>
  58. );
  59. }
  60. const ContentHeader = styled('div')`
  61. display: grid;
  62. grid-template-columns: 1fr;
  63. gap: ${space(4)};
  64. margin-bottom: ${space(2)};
  65. @media (min-width: ${p => p.theme.breakpoints.medium}) {
  66. grid-template-columns: 1fr repeat(3, max-content);
  67. }
  68. `;
  69. const HeaderInfo = styled('div')`
  70. ${p => p.theme.overflowEllipsis};
  71. height: 78px;
  72. `;
  73. const StyledSectionHeading = styled(SectionHeading)`
  74. margin: 0;
  75. `;
  76. const NumericSectionWrapper = styled('div')`
  77. text-align: right;
  78. `;
  79. const SectionBody = styled('div')<{overflowEllipsis?: boolean}>`
  80. font-size: ${p => p.theme.fontSizeExtraLarge};
  81. padding: ${space(0.5)} 0;
  82. max-height: 32px;
  83. `;
  84. const SectionSubtext = styled('div')`
  85. color: ${p => p.theme.subText};
  86. font-size: ${p => p.theme.fontSizeMedium};
  87. `;
  88. export const SpanLabelContainer = styled('div')`
  89. ${p => p.theme.overflowEllipsis};
  90. `;
  91. const EmptyValueContainer = styled('span')`
  92. color: ${p => p.theme.gray300};
  93. `;
  94. const emptyValue = <EmptyValueContainer>{'\u2014'}</EmptyValueContainer>;