1
- import { Fragment , useCallback } from 'react' ;
1
+ import { Fragment , useCallback , useMemo } from 'react' ;
2
2
3
3
import { Button } from 'sentry/components/core/button' ;
4
+ import { LinkButton } from 'sentry/components/core/button/linkButton' ;
4
5
import type { SelectOption } from 'sentry/components/core/compactSelect' ;
5
6
import { CompactSelect } from 'sentry/components/core/compactSelect' ;
6
- import { IconSliders } from 'sentry/icons' ;
7
+ import { IconChevron , IconSliders } from 'sentry/icons' ;
7
8
import { t } from 'sentry/locale' ;
8
9
import type { CanvasPoolManager } from 'sentry/utils/profiling/canvasScheduler' ;
9
10
import type { FlamegraphPreferences } from 'sentry/utils/profiling/flamegraph/flamegraphStateProvider/reducers/flamegraphPreferences' ;
10
11
import { useFlamegraphPreferences } from 'sentry/utils/profiling/flamegraph/hooks/useFlamegraphPreferences' ;
11
12
import { useDispatchFlamegraphState } from 'sentry/utils/profiling/flamegraph/hooks/useFlamegraphState' ;
13
+ import { useLocation } from 'sentry/utils/useLocation' ;
12
14
13
15
interface FlamegraphOptionsMenuProps {
14
16
canvasPoolManager : CanvasPoolManager ;
@@ -17,6 +19,7 @@ interface FlamegraphOptionsMenuProps {
17
19
function FlamegraphOptionsMenu ( {
18
20
canvasPoolManager,
19
21
} : FlamegraphOptionsMenuProps ) : React . ReactElement {
22
+ const location = useLocation ( ) ;
20
23
const { colorCoding} = useFlamegraphPreferences ( ) ;
21
24
const dispatch = useDispatchFlamegraphState ( ) ;
22
25
@@ -34,6 +37,22 @@ function FlamegraphOptionsMenu({
34
37
canvasPoolManager . dispatch ( 'reset zoom' , [ ] ) ;
35
38
} , [ canvasPoolManager ] ) ;
36
39
40
+ const continuousLocationDescriptor : { end : string ; start : string } | null =
41
+ useMemo ( ( ) => {
42
+ if (
43
+ typeof location . query . start !== 'string' ||
44
+ typeof location . query . end !== 'string' ||
45
+ typeof location . query . profilerId !== 'string'
46
+ ) {
47
+ return null ;
48
+ }
49
+
50
+ return {
51
+ start : new Date ( location . query . start ) . toISOString ( ) ,
52
+ end : new Date ( location . query . end ) . toISOString ( ) ,
53
+ } ;
54
+ } , [ location . query ] ) ;
55
+
37
56
return (
38
57
< Fragment >
39
58
< Button size = "xs" onClick = { onResetZoom } >
@@ -48,6 +67,40 @@ function FlamegraphOptionsMenu({
48
67
closeOnSelect = { false }
49
68
onChange = { onColorChange }
50
69
/>
70
+ { continuousLocationDescriptor ? (
71
+ < LinkButton
72
+ to = { {
73
+ ...location ,
74
+ query : {
75
+ ...location . query ,
76
+ start : new Date (
77
+ new Date ( continuousLocationDescriptor . start ) . getTime ( ) - 30 * 60 * 1000
78
+ ) . toISOString ( ) ,
79
+ } ,
80
+ } }
81
+ size = "xs"
82
+ icon = { < IconChevron direction = "left" /> }
83
+ aria-label = { t ( 'View Previous 30 Minutes' ) }
84
+ title = { t ( 'View Previous 30 Minutes' ) }
85
+ />
86
+ ) : null }
87
+ { continuousLocationDescriptor ? (
88
+ < LinkButton
89
+ to = { {
90
+ ...location ,
91
+ query : {
92
+ ...location . query ,
93
+ end : new Date (
94
+ new Date ( continuousLocationDescriptor . end ) . getTime ( ) + 30 * 60 * 1000
95
+ ) . toISOString ( ) ,
96
+ } ,
97
+ } }
98
+ size = "xs"
99
+ icon = { < IconChevron direction = "right" /> }
100
+ aria-label = { t ( 'View Next 30 Minutes' ) }
101
+ title = { t ( 'View Next 30 Minutes' ) }
102
+ />
103
+ ) : null }
51
104
</ Fragment >
52
105
) ;
53
106
}
0 commit comments