import {Fragment, useMemo} from 'react'; import styled from '@emotion/styled'; import type {Location} from 'history'; import { SpanProfileDetails, useSpanProfileDetails, } from 'sentry/components/events/interfaces/spans/spanProfileDetails'; import type {SpanType} from 'sentry/components/events/interfaces/spans/types'; import {getSpanOperation} from 'sentry/components/events/interfaces/spans/utils'; import ProjectBadge from 'sentry/components/idBadge/projectBadge'; import {Tooltip} from 'sentry/components/tooltip'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import type {EventTransaction} from 'sentry/types/event'; import type {Organization} from 'sentry/types/organization'; import type {Project} from 'sentry/types/project'; import {defined} from 'sentry/utils'; import {useLocation} from 'sentry/utils/useLocation'; import useProjects from 'sentry/utils/useProjects'; import {InterimSection} from 'sentry/views/issueDetails/streamline/interimSection'; import {ProfileGroupProvider} from 'sentry/views/profiling/profileGroupProvider'; import {ProfileContext, ProfilesProvider} from 'sentry/views/profiling/profilesProvider'; import type {TraceTreeNodeDetailsProps} from '../../../traceDrawer/tabs/traceTreeNodeDetails'; import type {TraceTree} from '../../../traceModels/traceTree'; import type {TraceTreeNode} from '../../../traceModels/traceTreeNode'; import {useHasTraceNewUi} from '../../../useHasTraceNewUi'; import {TraceDrawerComponents} from '.././styles'; import {IssueList} from '../issues/issues'; import Alerts from './sections/alerts'; import {SpanDescription} from './sections/description'; import {GeneralInfo} from './sections/generalInfo'; import {hasSpanHTTPInfo, SpanHTTPInfo} from './sections/http'; import {hasSpanKeys, SpanKeys} from './sections/keys'; import {hasSpanTags, Tags} from './sections/tags'; function SpanNodeDetailHeader({ node, organization, onTabScrollToNode, project, }: { node: TraceTreeNode; onTabScrollToNode: (node: TraceTreeNode) => void; organization: Organization; project: Project | undefined; }) { const hasNewTraceUi = useHasTraceNewUi(); if (!hasNewTraceUi) { return ( ); } return ( {t('Span')} ); } function LegacySpanNodeDetailHeader({ node, organization, onTabScrollToNode, project, }: { node: TraceTreeNode; onTabScrollToNode: (node: TraceTreeNode) => void; organization: Organization; project: Project | undefined; }) { const span = node.value; return (
{t('span')}
); } function SpanSections({ node, organization, location, onParentClick, }: { location: Location; node: TraceTreeNode; onParentClick: (node: TraceTreeNode) => void; organization: Organization; project: Project | undefined; }) { const hasTraceNewUi = useHasTraceNewUi(); if (!hasTraceNewUi) { return ( ); } const hasSpanSpecificData = hasSpanHTTPInfo(node.value) || hasSpanKeys(node) || hasSpanTags(node.value); return ( {hasSpanSpecificData ? ( {hasSpanKeys(node) ? : null} {hasSpanHTTPInfo(node.value) ? : null} {hasSpanTags(node.value) ? : null} ) : null} ); } function LegacySpanSections({ node, organization, location, onParentClick, }: { location: Location; node: TraceTreeNode; onParentClick: (node: TraceTreeNode) => void; organization: Organization; }) { return ( {hasSpanHTTPInfo(node.value) ? : null} {hasSpanTags(node.value) ? : null} {hasSpanKeys(node) ? : null} ); } function ProfileDetails({ event, span, }: { event: Readonly; span: Readonly; }) { const hasNewTraceUi = useHasTraceNewUi(); const {profile, frames} = useSpanProfileDetails(event, span); if (!hasNewTraceUi) { return ; } if (!defined(profile) || frames.length === 0) { return null; } return ( ); } const EmbededContentWrapper = styled('div')` margin-top: ${space(0.5)}; `; export function SpanNodeDetails({ node, organization, onTabScrollToNode, onParentClick, }: TraceTreeNodeDetailsProps>) { const location = useLocation(); const hasNewTraceUi = useHasTraceNewUi(); const {projects} = useProjects(); const issues = useMemo(() => { return [...node.errors, ...node.performance_issues]; }, [node.errors, node.performance_issues]); const project = projects.find(proj => proj.slug === node.event?.projectSlug); const profileId = node.event?.contexts?.profile?.profile_id ?? null; return ( {node.event?.projectSlug ? ( {profiles => ( {issues.length > 0 ? ( ) : null} {organization.features.includes('profiling') ? ( ) : null} )} ) : null} ); }