@@ -2,6 +2,7 @@ import {Fragment} from 'react';
2
2
import styled from '@emotion/styled' ;
3
3
4
4
import { SectionHeading } from 'sentry/components/charts/styles' ;
5
+ import { Tag } from 'sentry/components/core/badge/tag' ;
5
6
import { Tooltip } from 'sentry/components/core/tooltip' ;
6
7
import { DateTime } from 'sentry/components/dateTime' ;
7
8
import Duration from 'sentry/components/duration' ;
@@ -29,6 +30,8 @@ import {CheckInStatus} from 'sentry/views/insights/crons/types';
29
30
import { statusToText } from 'sentry/views/insights/crons/utils' ;
30
31
import { useMonitorCheckIns } from 'sentry/views/insights/crons/utils/useMonitorCheckIns' ;
31
32
33
+ import { DEFAULT_MAX_RUNTIME } from './monitorForm' ;
34
+
32
35
type Props = {
33
36
monitor : Monitor ;
34
37
monitorEnvs : MonitorEnvironment [ ] ;
@@ -133,11 +136,14 @@ export function MonitorCheckIns({monitor, monitorEnvs}: Props) {
133
136
</ div >
134
137
) }
135
138
{ defined ( checkIn . duration ) ? (
136
- < div >
139
+ < DurationContainer >
137
140
< Tooltip title = { < Duration exact seconds = { checkIn . duration / 1000 } /> } >
138
141
< Duration seconds = { checkIn . duration / 1000 } />
139
142
</ Tooltip >
140
- </ div >
143
+ { checkIn . status === CheckInStatus . TIMEOUT && (
144
+ < TimeoutLateBy monitor = { monitor } duration = { checkIn . duration } />
145
+ ) }
146
+ </ DurationContainer >
141
147
) : (
142
148
emptyCell
143
149
) }
@@ -198,10 +204,51 @@ export function MonitorCheckIns({monitor, monitorEnvs}: Props) {
198
204
) ;
199
205
}
200
206
207
+ interface TimeoutLateByProps {
208
+ duration : number ;
209
+ monitor : Monitor ;
210
+ }
211
+
212
+ function TimeoutLateBy ( { monitor, duration} : TimeoutLateByProps ) {
213
+ const maxRuntimeSeconds = ( monitor . config . max_runtime ?? DEFAULT_MAX_RUNTIME ) * 60 ;
214
+ const lateBySecond = duration / 1000 - maxRuntimeSeconds ;
215
+
216
+ const maxRuntime = (
217
+ < strong >
218
+ < Duration seconds = { ( monitor . config . max_runtime ?? DEFAULT_MAX_RUNTIME ) * 60 } />
219
+ </ strong >
220
+ ) ;
221
+
222
+ const lateBy = (
223
+ < strong >
224
+ < Duration seconds = { lateBySecond } />
225
+ </ strong >
226
+ ) ;
227
+
228
+ return (
229
+ < Tooltip
230
+ title = { tct (
231
+ 'The closing check-in occurred [lateBy] after this check-in was marked as timed out. The configured maximum allowed runtime is [maxRuntime].' ,
232
+ { lateBy, maxRuntime}
233
+ ) }
234
+ >
235
+ < Tag type = "error" >
236
+ { t ( '%s late' , < Duration abbreviation seconds = { lateBySecond } /> ) }
237
+ </ Tag >
238
+ </ Tooltip >
239
+ ) ;
240
+ }
241
+
201
242
const Status = styled ( 'div' ) `
202
243
line-height: 1.1;
203
244
` ;
204
245
246
+ const DurationContainer = styled ( 'div' ) `
247
+ display: flex;
248
+ gap: ${ space ( 0.5 ) } ;
249
+ align-items: center;
250
+ ` ;
251
+
205
252
const IssuesContainer = styled ( 'div' ) `
206
253
display: flex;
207
254
flex-direction: column;
0 commit comments