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;
}