spanSiblingGroupBar.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import {Fragment} from 'react';
  2. import {
  3. ConnectorBar,
  4. TOGGLE_BORDER_BOX,
  5. TreeConnector,
  6. } from 'sentry/components/performance/waterfall/treeConnector';
  7. import {t} from 'sentry/locale';
  8. import {EventTransaction} from 'sentry/types/event';
  9. import {SpanGroupBar} from './spanGroupBar';
  10. import SpanRectangle from './spanRectangle';
  11. import {SpanRectangleOverlay} from './spanRectangleOverlay';
  12. import {EnhancedSpan, ProcessedSpanType, SpanType, TreeDepthType} from './types';
  13. import {
  14. getSpanGroupBounds,
  15. isOrphanSpan,
  16. isOrphanTreeDepth,
  17. SpanBoundsType,
  18. SpanGeneratedBoundsType,
  19. unwrapTreeDepth,
  20. } from './utils';
  21. type Props = {
  22. continuingTreeDepths: Array<TreeDepthType>;
  23. event: Readonly<EventTransaction>;
  24. generateBounds: (bounds: SpanBoundsType) => SpanGeneratedBoundsType;
  25. generateContentSpanBarRef: () => (instance: HTMLDivElement | null) => void;
  26. isLastSibling: boolean;
  27. occurrence: number;
  28. onWheel: (deltaX: number) => void;
  29. span: Readonly<ProcessedSpanType>;
  30. spanGrouping: EnhancedSpan[];
  31. spanNumber: number;
  32. toggleSiblingSpanGroup: (span: SpanType, occurrence: number) => void;
  33. treeDepth: number;
  34. };
  35. export default function SpanSiblingGroupBar(props: Props) {
  36. const {
  37. continuingTreeDepths,
  38. event,
  39. generateBounds,
  40. isLastSibling,
  41. span,
  42. spanGrouping,
  43. spanNumber,
  44. occurrence,
  45. toggleSiblingSpanGroup,
  46. onWheel,
  47. generateContentSpanBarRef,
  48. } = props;
  49. function renderGroupSpansTitle(): React.ReactNode {
  50. if (spanGrouping.length === 0) {
  51. return '';
  52. }
  53. const operation = spanGrouping[0].span.op;
  54. const description = spanGrouping[0].span.description;
  55. if (!description || !operation) {
  56. if (description) {
  57. return <strong>{`${t('Autogrouped')} \u2014 ${description}`}</strong>;
  58. }
  59. if (operation) {
  60. return <strong>{`${t('Autogrouped')} \u2014 ${operation}`}</strong>;
  61. }
  62. return <strong>{`${t('Autogrouped')} \u2014 ${t('siblings')}`}</strong>;
  63. }
  64. return (
  65. <Fragment>
  66. <strong>{`${t('Autogrouped')} \u2014 ${operation} \u2014 `}</strong>
  67. {description}
  68. </Fragment>
  69. );
  70. }
  71. function renderSpanTreeConnector() {
  72. const {treeDepth: spanTreeDepth} = props;
  73. const connectorBars: Array<React.ReactNode> = continuingTreeDepths.map(treeDepth => {
  74. const depth: number = unwrapTreeDepth(treeDepth);
  75. if (depth === 0) {
  76. // do not render a connector bar at depth 0,
  77. // if we did render a connector bar, this bar would be placed at depth -1
  78. // which does not exist.
  79. return null;
  80. }
  81. const left = ((spanTreeDepth - depth) * (TOGGLE_BORDER_BOX / 2) + 2) * -1;
  82. return (
  83. <ConnectorBar
  84. style={{left}}
  85. key={`span-group-${depth}`}
  86. orphanBranch={isOrphanTreeDepth(treeDepth)}
  87. />
  88. );
  89. });
  90. return (
  91. <TreeConnector isLast={isLastSibling} hasToggler orphanBranch={isOrphanSpan(span)}>
  92. {connectorBars}
  93. </TreeConnector>
  94. );
  95. }
  96. function renderSpanRectangles() {
  97. return (
  98. <Fragment>
  99. {spanGrouping.map((_, index) => (
  100. <SpanRectangle
  101. key={index}
  102. spanGrouping={spanGrouping}
  103. bounds={getSpanGroupBounds([spanGrouping[index]], generateBounds)}
  104. />
  105. ))}
  106. <SpanRectangleOverlay
  107. spanGrouping={spanGrouping}
  108. bounds={getSpanGroupBounds(spanGrouping, generateBounds)}
  109. />
  110. </Fragment>
  111. );
  112. }
  113. return (
  114. <SpanGroupBar
  115. event={event}
  116. span={span}
  117. spanGrouping={spanGrouping}
  118. treeDepth={props.treeDepth}
  119. spanNumber={spanNumber}
  120. generateBounds={generateBounds}
  121. toggleSpanGroup={() => toggleSiblingSpanGroup?.(spanGrouping[0].span, occurrence)}
  122. renderSpanTreeConnector={renderSpanTreeConnector}
  123. renderGroupSpansTitle={renderGroupSpansTitle}
  124. renderSpanRectangles={renderSpanRectangles}
  125. onWheel={onWheel}
  126. generateContentSpanBarRef={generateContentSpanBarRef}
  127. />
  128. );
  129. }