123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- import {Fragment} from 'react';
- import type {SpanBarType} from 'sentry/components/performance/waterfall/constants';
- import {
- ConnectorBar,
- TOGGLE_BORDER_BOX,
- TreeConnector,
- } from 'sentry/components/performance/waterfall/treeConnector';
- import {t} from 'sentry/locale';
- import type {AggregateEventTransaction, EventTransaction} from 'sentry/types/event';
- import {trackAnalytics} from 'sentry/utils/analytics';
- import useOrganization from 'sentry/utils/useOrganization';
- import {SpanGroupBar} from './spanGroupBar';
- import SpanRectangle from './spanRectangle';
- import {SpanRectangleOverlay} from './spanRectangleOverlay';
- import type {EnhancedSpan, ProcessedSpanType, SpanType, TreeDepthType} from './types';
- import type {SpanBoundsType, SpanGeneratedBoundsType, VerticalMark} from './utils';
- import {
- getSpanGroupBounds,
- isOrphanSpan,
- isOrphanTreeDepth,
- unwrapTreeDepth,
- } from './utils';
- export type SpanSiblingGroupBarProps = {
- addContentSpanBarRef: (instance: HTMLDivElement | null) => void;
- continuingTreeDepths: Array<TreeDepthType>;
- didAnchoredSpanMount: () => boolean;
- event: Readonly<EventTransaction | AggregateEventTransaction>;
- generateBounds: (bounds: SpanBoundsType) => SpanGeneratedBoundsType;
- getCurrentLeftPos: () => number;
- isEmbeddedSpanTree: boolean;
- isLastSibling: boolean;
- occurrence: number;
- onWheel: (deltaX: number) => void;
- removeContentSpanBarRef: (instance: HTMLDivElement | null) => void;
- span: ProcessedSpanType;
- spanGrouping: EnhancedSpan[];
- spanNumber: number;
- toggleSiblingSpanGroup: (span: SpanType, occurrence: number) => void;
- treeDepth: number;
- measurements?: Map<number, VerticalMark>;
- spanBarType?: SpanBarType;
- };
- export default function SpanSiblingGroupBar(props: SpanSiblingGroupBarProps) {
- const {
- continuingTreeDepths,
- event,
- generateBounds,
- getCurrentLeftPos,
- isLastSibling,
- span,
- spanGrouping,
- spanNumber,
- occurrence,
- toggleSiblingSpanGroup,
- onWheel,
- addContentSpanBarRef,
- removeContentSpanBarRef,
- isEmbeddedSpanTree,
- didAnchoredSpanMount,
- spanBarType,
- measurements,
- } = props;
- const organization = useOrganization();
- function renderGroupSpansTitle(): React.ReactNode {
- if (spanGrouping.length === 0) {
- return '';
- }
- const operation = spanGrouping[0].span.op;
- const description = spanGrouping[0].span.description;
- if (!description || !operation) {
- if (description) {
- return <strong>{`${t('Autogrouped')} \u2014 ${description}`}</strong>;
- }
- if (operation) {
- return <strong>{`${t('Autogrouped')} \u2014 ${operation}`}</strong>;
- }
- return <strong>{`${t('Autogrouped')} \u2014 ${t('siblings')}`}</strong>;
- }
- return (
- <Fragment>
- <strong>{`${t('Autogrouped')} \u2014 ${operation} \u2014 `}</strong>
- {description}
- </Fragment>
- );
- }
- function renderSpanTreeConnector() {
- const {treeDepth: spanTreeDepth} = props;
- const connectorBars: Array<React.ReactNode> = continuingTreeDepths.map(treeDepth => {
- const depth: number = unwrapTreeDepth(treeDepth);
- if (depth === 0) {
-
-
-
- return null;
- }
- const left = ((spanTreeDepth - depth) * (TOGGLE_BORDER_BOX / 2) + 2) * -1;
- return (
- <ConnectorBar
- style={{left}}
- key={`span-group-${depth}`}
- orphanBranch={isOrphanTreeDepth(treeDepth)}
- />
- );
- });
- return (
- <TreeConnector isLast={isLastSibling} hasToggler orphanBranch={isOrphanSpan(span)}>
- {connectorBars}
- </TreeConnector>
- );
- }
- function renderSpanRectangles() {
- return (
- <Fragment>
- {spanGrouping.map((_, index) => (
- <SpanRectangle
- key={index}
- spanGrouping={spanGrouping}
- bounds={getSpanGroupBounds([spanGrouping[index]], generateBounds)}
- spanBarType={spanBarType}
- />
- ))}
- <SpanRectangleOverlay
- spanGrouping={spanGrouping}
- bounds={getSpanGroupBounds(spanGrouping, generateBounds)}
- spanBarType={spanBarType}
- />
- </Fragment>
- );
- }
- return (
- <SpanGroupBar
- event={event}
- measurements={measurements}
- span={span}
- spanGrouping={spanGrouping}
- treeDepth={props.treeDepth}
- spanNumber={spanNumber}
- generateBounds={generateBounds}
- toggleSpanGroup={() => {
- toggleSiblingSpanGroup?.(spanGrouping[0].span, occurrence);
- isEmbeddedSpanTree &&
- trackAnalytics('issue_details.performance.autogrouped_siblings_toggle', {
- organization,
- });
- }}
- renderSpanTreeConnector={renderSpanTreeConnector}
- renderGroupSpansTitle={renderGroupSpansTitle}
- renderSpanRectangles={renderSpanRectangles}
- onWheel={onWheel}
- addContentSpanBarRef={addContentSpanBarRef}
- removeContentSpanBarRef={removeContentSpanBarRef}
- didAnchoredSpanMount={didAnchoredSpanMount}
- getCurrentLeftPos={getCurrentLeftPos}
- spanBarType={spanBarType}
- />
- );
- }
|