index.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import {useMemo} from 'react';
  2. import {EventContexts} from 'sentry/components/events/contexts';
  3. import {SpanProfileDetails} from 'sentry/components/events/interfaces/spans/spanProfileDetails';
  4. import {getSpanOperation} from 'sentry/components/events/interfaces/spans/utils';
  5. import ProjectBadge from 'sentry/components/idBadge/projectBadge';
  6. import {Tooltip} from 'sentry/components/tooltip';
  7. import {t} from 'sentry/locale';
  8. import type {Organization, Project} from 'sentry/types';
  9. import useProjects from 'sentry/utils/useProjects';
  10. import {CustomMetricsEventData} from 'sentry/views/metrics/customMetricsEventData';
  11. import type {TraceTreeNodeDetailsProps} from 'sentry/views/performance/newTraceDetails/traceDrawer/tabs/traceTreeNodeDetails';
  12. import type {
  13. TraceTree,
  14. TraceTreeNode,
  15. } from 'sentry/views/performance/newTraceDetails/traceModels/traceTree';
  16. import {ProfileGroupProvider} from 'sentry/views/profiling/profileGroupProvider';
  17. import {ProfileContext, ProfilesProvider} from 'sentry/views/profiling/profilesProvider';
  18. import {TraceDrawerComponents} from '.././styles';
  19. import {IssueList} from '../issues/issues';
  20. import Alerts from './sections/alerts';
  21. import SpanNodeDetailTable from './sections/table/index';
  22. function SpanNodeDetailHeader({
  23. node,
  24. organization,
  25. onTabScrollToNode,
  26. project,
  27. }: {
  28. node: TraceTreeNode<TraceTree.Span>;
  29. onTabScrollToNode: (node: TraceTreeNode<any>) => void;
  30. organization: Organization;
  31. project: Project | undefined;
  32. }) {
  33. const span = node.value;
  34. const {event} = span;
  35. return (
  36. <TraceDrawerComponents.HeaderContainer>
  37. <TraceDrawerComponents.Title>
  38. <Tooltip title={event.projectSlug}>
  39. <ProjectBadge
  40. project={project ? project : {slug: event.projectSlug || ''}}
  41. avatarSize={30}
  42. hideName
  43. />
  44. </Tooltip>
  45. <TraceDrawerComponents.TitleText>
  46. <div>{t('span')}</div>
  47. <TraceDrawerComponents.TitleOp>
  48. {' '}
  49. {getSpanOperation(span) + ' - ' + (span.description ?? span.span_id)}
  50. </TraceDrawerComponents.TitleOp>
  51. </TraceDrawerComponents.TitleText>
  52. </TraceDrawerComponents.Title>
  53. <TraceDrawerComponents.NodeActions
  54. node={node}
  55. organization={organization}
  56. onTabScrollToNode={onTabScrollToNode}
  57. />
  58. </TraceDrawerComponents.HeaderContainer>
  59. );
  60. }
  61. export function SpanNodeDetails({
  62. node,
  63. organization,
  64. onTabScrollToNode,
  65. onParentClick,
  66. }: TraceTreeNodeDetailsProps<TraceTreeNode<TraceTree.Span>>) {
  67. const {projects} = useProjects();
  68. const {event} = node.value;
  69. const issues = useMemo(() => {
  70. return [...node.errors, ...node.performance_issues];
  71. }, [node.errors, node.performance_issues]);
  72. const project = projects.find(proj => proj.slug === event?.projectSlug);
  73. const profileId = event?.contexts?.profile?.profile_id ?? null;
  74. return (
  75. <TraceDrawerComponents.DetailContainer>
  76. <SpanNodeDetailHeader
  77. node={node}
  78. organization={organization}
  79. project={project}
  80. onTabScrollToNode={onTabScrollToNode}
  81. />
  82. {event.projectSlug ? (
  83. <ProfilesProvider
  84. orgSlug={organization.slug}
  85. projectSlug={event.projectSlug}
  86. profileId={profileId || ''}
  87. >
  88. <ProfileContext.Consumer>
  89. {profiles => (
  90. <ProfileGroupProvider
  91. type="flamechart"
  92. input={profiles?.type === 'resolved' ? profiles.data : null}
  93. traceID={profileId || ''}
  94. >
  95. <Alerts node={node} />
  96. {issues.length > 0 ? (
  97. <IssueList organization={organization} issues={issues} node={node} />
  98. ) : null}
  99. <SpanNodeDetailTable
  100. node={node}
  101. openPanel="open"
  102. organization={organization}
  103. onParentClick={onParentClick}
  104. />
  105. {node.value._metrics_summary ? (
  106. <CustomMetricsEventData
  107. projectId={project?.id || ''}
  108. metricsSummary={node.value._metrics_summary}
  109. startTimestamp={node.value.start_timestamp}
  110. />
  111. ) : null}
  112. <EventContexts event={event} />
  113. {organization.features.includes('profiling') ? (
  114. <SpanProfileDetails span={node.value} event={event} />
  115. ) : null}
  116. </ProfileGroupProvider>
  117. )}
  118. </ProfileContext.Consumer>
  119. </ProfilesProvider>
  120. ) : null}
  121. </TraceDrawerComponents.DetailContainer>
  122. );
  123. }