import {Fragment} from 'react'; import type {Location} from 'history'; import Feature from 'sentry/components/acl/feature'; import IdBadge from 'sentry/components/idBadge'; import * as Layout from 'sentry/components/layouts/thirds'; import type {Organization} from 'sentry/types/organization'; import type {Project} from 'sentry/types/project'; import DiscoverQuery from 'sentry/utils/discover/discoverQuery'; import type EventView from 'sentry/utils/discover/eventView'; import type {ChildrenProps as SpanExamplesProps} from 'sentry/utils/performance/suspectSpans/spanExamplesQuery'; import SpanExamplesQuery from 'sentry/utils/performance/suspectSpans/spanExamplesQuery'; import type {ChildrenProps as SuspectSpansProps} from 'sentry/utils/performance/suspectSpans/suspectSpansQuery'; import SuspectSpansQuery from 'sentry/utils/performance/suspectSpans/suspectSpansQuery'; import type {SpanSlug} from 'sentry/utils/performance/suspectSpans/types'; import {setGroupedEntityTag} from 'sentry/utils/performanceForSentry'; import {decodeScalar} from 'sentry/utils/queryString'; import useRouteAnalyticsEventNames from 'sentry/utils/routeAnalytics/useRouteAnalyticsEventNames'; import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams'; import Breadcrumb from 'sentry/views/performance/breadcrumb'; import SpanSummary from 'sentry/views/performance/transactionSummary/transactionSpans/spanSummary/content'; import {getSelectedProjectPlatforms} from 'sentry/views/performance/utils'; import Tab from '../../tabs'; import {SpanSortOthers} from '../types'; import {getTotalsView} from '../utils'; import SpanChart from './chart'; import SpanDetailsControls from './spanDetailsControls'; import SpanDetailsHeader from './spanDetailsHeader'; import SpanTable from './spanDetailsTable'; import {ZoomKeys} from './utils'; type Props = { eventView: EventView; location: Location; organization: Organization; project: Project | undefined; spanSlug: SpanSlug; transactionName: string; }; export default function SpanDetailsContentWrapper(props: Props) { const {location, organization, eventView, project, transactionName, spanSlug} = props; const minExclusiveTime = decodeScalar(location.query[ZoomKeys.MIN]); const maxExclusiveTime = decodeScalar(location.query[ZoomKeys.MAX]); // customize the route analytics event we send useRouteAnalyticsEventNames( 'performance_views.span_summary.view', 'Performance Views: Span Summary page viewed' ); useRouteAnalyticsParams({ project_platforms: project ? getSelectedProjectPlatforms(location, [project]) : '', }); const hasNewSpansUIFlag = organization.features.includes('performance-spans-new-ui') && organization.features.includes('insights-initial-modules'); // TODO: When this feature is rolled out to GA, we will no longer need the entire `spanDetails` directory and can switch to `spanSummary` if (hasNewSpansUIFlag) { return ; } return ( {project && ( )} {transactionName} {({tableData}) => { const totalCount: number | null = (tableData?.data?.[0]?.['count()'] as number) ?? null; if (totalCount) { setGroupedEntityTag('spans.totalCount', 1000, totalCount); } return ( {suspectSpansResults => ( {spanExamplesResults => ( )} )} ); }} ); } type ContentProps = { eventView: EventView; location: Location; organization: Organization; project: Project | undefined; spanExamplesResults: SpanExamplesProps; spanSlug: SpanSlug; suspectSpansResults: SuspectSpansProps; totalCount: number; transactionName: string; }; function SpanDetailsContent(props: ContentProps) { const { location, organization, project, eventView, spanSlug, transactionName, totalCount, suspectSpansResults, spanExamplesResults, } = props; // There should always be exactly 1 result const suspectSpan = suspectSpansResults.suspectSpans?.[0]; const examples = spanExamplesResults.examples?.[0]?.examples; const transactionCountContainingSpan = suspectSpan?.frequency; return ( ); } function getSpansEventView(eventView: EventView): EventView { // TODO: There is a bug where if the sort is not avg occurrence, // then the avg occurrence will never be added to the fields eventView = eventView.withSorts([{field: SpanSortOthers.AVG_OCCURRENCE, kind: 'desc'}]); eventView.fields = [ {field: 'count()'}, {field: 'count_unique(id)'}, {field: 'equation|count() / count_unique(id)'}, {field: 'sumArray(spans_exclusive_time)'}, {field: 'percentileArray(spans_exclusive_time, 0.50)'}, {field: 'percentileArray(spans_exclusive_time, 0.75)'}, {field: 'percentileArray(spans_exclusive_time, 0.95)'}, {field: 'percentileArray(spans_exclusive_time, 0.99)'}, ]; return eventView; }