1
- import { CSSProperties , memo , useCallback , useMemo } from 'react' ;
1
+ import { CSSProperties , memo , useCallback } from 'react' ;
2
2
import styled from '@emotion/styled' ;
3
3
import classNames from 'classnames' ;
4
4
5
5
import ErrorBoundary from 'sentry/components/errorBoundary' ;
6
- import { relativeTimeInMs } from 'sentry/components/replays/utils ' ;
7
- import { IconFire , IconWarning } from 'sentry/icons' ;
6
+ import { Tooltip } from 'sentry/components/tooltip ' ;
7
+ import { IconClose , IconInfo , IconWarning } from 'sentry/icons' ;
8
8
import { space } from 'sentry/styles/space' ;
9
- import type { BreadcrumbTypeDefault , Crumb } from 'sentry/types/breadcrumbs' ;
10
9
import { BreadcrumbLevelType } from 'sentry/types/breadcrumbs' ;
11
10
import useCrumbHandlers from 'sentry/utils/replays/hooks/useCrumbHandlers' ;
11
+ import type { BreadcrumbFrame , ConsoleFrame } from 'sentry/utils/replays/types' ;
12
12
import MessageFormatter from 'sentry/views/replays/detail/console/messageFormatter' ;
13
- import { breadcrumbHasIssue } from 'sentry/views/replays/detail/console/utils' ;
14
- import ViewIssueLink from 'sentry/views/replays/detail/console/viewIssueLink' ;
15
13
import TimestampButton from 'sentry/views/replays/detail/timestampButton' ;
16
-
17
- import { OnDimensionChange } from '../useVirtualizedInspector' ;
14
+ import { OnDimensionChange } from 'sentry/views/replays/detail/useVirtualizedInspector' ;
18
15
19
16
type Props = {
20
- breadcrumb : Extract < Crumb , BreadcrumbTypeDefault > ;
21
17
currentHoverTime : number | undefined ;
22
18
currentTime : number ;
19
+ frame : BreadcrumbFrame ;
23
20
index : number ;
24
21
startTimestampMs : number ;
25
22
style : CSSProperties ;
@@ -29,7 +26,7 @@ type Props = {
29
26
30
27
function UnmemoizedConsoleLogRow ( {
31
28
index,
32
- breadcrumb ,
29
+ frame ,
33
30
currentTime,
34
31
currentHoverTime,
35
32
startTimestampMs,
@@ -40,30 +37,24 @@ function UnmemoizedConsoleLogRow({
40
37
const { handleMouseEnter, handleMouseLeave, handleClick} =
41
38
useCrumbHandlers ( startTimestampMs ) ;
42
39
43
- const onClickTimestamp = useCallback (
44
- ( ) => handleClick ( breadcrumb ) ,
45
- [ handleClick , breadcrumb ]
46
- ) ;
40
+ const onClickTimestamp = useCallback ( ( ) => handleClick ( frame ) , [ handleClick , frame ] ) ;
47
41
const onMouseEnter = useCallback (
48
- ( ) => handleMouseEnter ( breadcrumb ) ,
49
- [ handleMouseEnter , breadcrumb ]
42
+ ( ) => handleMouseEnter ( frame ) ,
43
+ [ handleMouseEnter , frame ]
50
44
) ;
51
45
const onMouseLeave = useCallback (
52
- ( ) => handleMouseLeave ( breadcrumb ) ,
53
- [ handleMouseLeave , breadcrumb ]
46
+ ( ) => handleMouseLeave ( frame ) ,
47
+ [ handleMouseLeave , frame ]
54
48
) ;
55
49
const handleDimensionChange = useCallback (
56
50
( path , expandedState , e ) =>
57
51
onDimensionChange && onDimensionChange ( index , path , expandedState , e ) ,
58
52
[ onDimensionChange , index ]
59
53
) ;
60
54
61
- const crumbTime = useMemo (
62
- ( ) => relativeTimeInMs ( breadcrumb . timestamp || 0 , startTimestampMs ) ,
63
- [ breadcrumb . timestamp , startTimestampMs ]
64
- ) ;
65
- const hasOccurred = currentTime >= crumbTime ;
66
- const isBeforeHover = currentHoverTime === undefined || currentHoverTime >= crumbTime ;
55
+ const hasOccurred = currentTime >= frame . offsetMs ;
56
+ const isBeforeHover =
57
+ currentHoverTime === undefined || currentHoverTime >= frame . offsetMs ;
67
58
68
59
return (
69
60
< ConsoleLog
@@ -74,61 +65,53 @@ function UnmemoizedConsoleLogRow({
74
65
afterHoverTime : currentHoverTime !== undefined && ! isBeforeHover ,
75
66
} ) }
76
67
hasOccurred = { hasOccurred }
77
- level = { breadcrumb . level }
68
+ level = { ( frame as ConsoleFrame ) . level }
78
69
onMouseEnter = { onMouseEnter }
79
70
onMouseLeave = { onMouseLeave }
80
71
style = { style }
81
72
>
82
- < Icon level = { breadcrumb . level } />
73
+ < ConsoleLevelIcon level = { ( frame as ConsoleFrame ) . level } />
83
74
< Message >
84
- { breadcrumbHasIssue ( breadcrumb ) ? (
85
- < IssueLinkWrapper >
86
- < ViewIssueLink breadcrumb = { breadcrumb } />
87
- </ IssueLinkWrapper >
88
- ) : null }
89
75
< ErrorBoundary mini >
90
76
< MessageFormatter
91
77
expandPaths = { expandPaths }
92
- breadcrumb = { breadcrumb }
78
+ frame = { frame }
93
79
onExpand = { handleDimensionChange }
94
80
/>
95
81
</ ErrorBoundary >
96
82
</ Message >
97
83
< TimestampButton
98
84
onClick = { onClickTimestamp }
99
85
startTimestampMs = { startTimestampMs }
100
- timestampMs = { breadcrumb . timestamp || '' }
86
+ timestampMs = { frame . timestampMs }
101
87
/>
102
88
</ ConsoleLog >
103
89
) ;
104
90
}
105
91
106
- const IssueLinkWrapper = styled ( 'div' ) `
107
- float: right;
108
- ` ;
109
-
110
92
const ConsoleLog = styled ( 'div' ) < {
111
93
hasOccurred : boolean ;
112
- level : string ;
94
+ level : undefined | string ;
113
95
} > `
114
96
display: grid;
115
97
grid-template-columns: 12px 1fr max-content;
116
98
gap: ${ space ( 0.75 ) } ;
99
+ align-items: baseline;
117
100
padding: ${ space ( 0.5 ) } ${ space ( 1 ) } ;
118
101
font-size: ${ p => p . theme . fontSizeSmall } ;
119
102
120
103
background-color: ${ p =>
121
- [ 'warning' , 'error' ] . includes ( p . level )
122
- ? p . theme . alert [ p . level ] . backgroundLight
104
+ [ 'warning' , 'error' ] . includes ( String ( p . level ) )
105
+ ? p . theme . alert [ String ( p . level ) ] . backgroundLight
123
106
: 'inherit' } ;
124
107
125
108
/* Overridden in TabItemContainer, depending on *CurrentTime and *HoverTime classes */
126
109
border-top: 1px solid transparent;
127
110
border-bottom: 1px solid transparent;
128
111
129
112
color: ${ p =>
130
- [ 'warning' , 'error' ] . includes ( p . level )
131
- ? p . theme . alert [ p . level ] . iconColor
113
+ [ 'warning' , 'error' ] . includes ( String ( p . level ) )
114
+ ? p . theme . alert [ String ( p . level ) ] . iconColor
132
115
: p . hasOccurred
133
116
? 'inherit'
134
117
: p . theme . gray300 } ;
@@ -144,18 +127,35 @@ const ConsoleLog = styled('div')<{
144
127
` ;
145
128
146
129
const ICONS = {
147
- [ BreadcrumbLevelType . ERROR ] : < IconFire size = "xs" /> ,
148
- [ BreadcrumbLevelType . WARNING ] : < IconWarning size = "xs" /> ,
130
+ [ BreadcrumbLevelType . ERROR ] : (
131
+ < Tooltip title = { BreadcrumbLevelType . ERROR } >
132
+ < IconClose size = "xs" isCircled />
133
+ </ Tooltip >
134
+ ) ,
135
+ [ BreadcrumbLevelType . WARNING ] : (
136
+ < Tooltip title = { BreadcrumbLevelType . WARNING } >
137
+ < IconWarning size = "xs" />
138
+ </ Tooltip >
139
+ ) ,
140
+ [ BreadcrumbLevelType . INFO ] : (
141
+ < Tooltip title = { BreadcrumbLevelType . INFO } >
142
+ < IconInfo size = "xs" />
143
+ </ Tooltip >
144
+ ) ,
149
145
} ;
150
146
151
- const Icon = styled (
152
- ( { level, className} : { level : BreadcrumbLevelType ; className ?: string } ) => (
153
- < span className = { className } > { ICONS [ level ] } </ span >
154
- )
155
- ) `
147
+ const MediumFontSize = styled ( 'span' ) `
156
148
font-size: ${ p => p . theme . fontSizeMedium } ;
157
149
` ;
158
150
151
+ function ConsoleLevelIcon ( { level} : { level : string | undefined } ) {
152
+ return level && level in ICONS ? (
153
+ < MediumFontSize > { ICONS [ level ] } </ MediumFontSize >
154
+ ) : (
155
+ < i />
156
+ ) ;
157
+ }
158
+
159
159
const Message = styled ( 'div' ) `
160
160
font-family: ${ p => p . theme . text . familyMono } ;
161
161
0 commit comments