1
1
import { useTheme } from '@emotion/react' ;
2
2
3
3
import { Button } from 'sentry/components/button' ;
4
+ import { TransactionToProfileButton } from 'sentry/components/profiling/transactionToProfileButton' ;
4
5
import { IconSpan } from 'sentry/icons' ;
5
6
import { t } from 'sentry/locale' ;
6
7
import { getDuration } from 'sentry/utils/formatters' ;
8
+ import useProjects from 'sentry/utils/useProjects' ;
9
+ import { ProfilePreview } from 'sentry/views/performance/newTraceDetails/traceDrawer/details/profiling/profilePreview' ;
7
10
import type { TraceTreeNodeDetailsProps } from 'sentry/views/performance/newTraceDetails/traceDrawer/tabs/traceTreeNodeDetails' ;
8
11
import { getTraceTabTitle } from 'sentry/views/performance/newTraceDetails/traceState/traceTabs' ;
9
12
import { Row } from 'sentry/views/performance/traceDetails/styles' ;
13
+ import { ProfileGroupProvider } from 'sentry/views/profiling/profileGroupProvider' ;
14
+ import { ProfileContext , ProfilesProvider } from 'sentry/views/profiling/profilesProvider' ;
10
15
11
16
import {
12
17
makeTraceNodeBarColor ,
@@ -19,9 +24,15 @@ export function MissingInstrumentationNodeDetails({
19
24
node,
20
25
onParentClick,
21
26
onTabScrollToNode,
27
+ organization,
22
28
} : TraceTreeNodeDetailsProps < MissingInstrumentationNode > ) {
23
29
const theme = useTheme ( ) ;
30
+ const { projects} = useProjects ( ) ;
31
+
24
32
const parentTransaction = node . parent_transaction ;
33
+ const event = node . previous . value . event || node . next . value . event || null ;
34
+ const project = projects . find ( proj => proj . slug === event ?. projectSlug ) ;
35
+ const profileId = event ?. contexts ?. profile ?. profile_id ?? null ;
25
36
26
37
return (
27
38
< TraceDrawerComponents . DetailContainer >
@@ -42,6 +53,25 @@ export function MissingInstrumentationNodeDetails({
42
53
</ Button >
43
54
</ TraceDrawerComponents . Actions >
44
55
</ TraceDrawerComponents . HeaderContainer >
56
+ { event . projectSlug ? (
57
+ < ProfilesProvider
58
+ orgSlug = { organization . slug }
59
+ projectSlug = { event . projectSlug }
60
+ profileId = { profileId || '' }
61
+ >
62
+ < ProfileContext . Consumer >
63
+ { profiles => (
64
+ < ProfileGroupProvider
65
+ type = "flamechart"
66
+ input = { profiles ?. type === 'resolved' ? profiles . data : null }
67
+ traceID = { profileId || '' }
68
+ >
69
+ < ProfilePreview event = { event } node = { node } />
70
+ </ ProfileGroupProvider >
71
+ ) }
72
+ </ ProfileContext . Consumer >
73
+ </ ProfilesProvider >
74
+ ) : null }
45
75
< TraceDrawerComponents . Table className = "table key-value" >
46
76
< tbody >
47
77
{ parentTransaction ? (
@@ -53,9 +83,25 @@ export function MissingInstrumentationNodeDetails({
53
83
</ td >
54
84
</ Row >
55
85
) : null }
56
- < Row title = { t ( 'Gap Duration' ) } >
86
+ < Row title = { t ( 'Duration' ) } >
57
87
{ getDuration ( node . value . timestamp - node . value . start_timestamp , 2 , true ) }
58
88
</ Row >
89
+ { profileId && project ?. slug && (
90
+ < Row
91
+ title = "Profile ID"
92
+ extra = {
93
+ < TransactionToProfileButton
94
+ size = "xs"
95
+ projectSlug = { project . slug }
96
+ event = { event }
97
+ >
98
+ { t ( 'View Profile' ) }
99
+ </ TransactionToProfileButton >
100
+ }
101
+ >
102
+ { profileId }
103
+ </ Row >
104
+ ) }
59
105
< Row title = { t ( 'Previous Span' ) } >
60
106
{ node . previous . value . op } - { node . previous . value . description }
61
107
</ Row >
0 commit comments