1
1
import React , { useEffect , useState } from 'react' ;
2
2
3
3
import { SelectableValue } from '@grafana/data' ;
4
- import { Button , Drawer , Field , HorizontalGroup , Select , VerticalGroup } from '@grafana/ui' ;
4
+ import { Button , Drawer , Field , HorizontalGroup , Icon , Select , VerticalGroup } from '@grafana/ui' ;
5
5
import cn from 'classnames/bind' ;
6
6
import { observer } from 'mobx-react' ;
7
7
@@ -12,9 +12,12 @@ import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_
12
12
import { SelectOption } from 'state/types' ;
13
13
import { useStore } from 'state/useStore' ;
14
14
import { withMobXProviderContext } from 'state/withStore' ;
15
+ import { openNotification } from 'utils' ;
15
16
import { UserActions } from 'utils/authorization' ;
16
17
17
- const cx = cn . bind ( { } ) ;
18
+ import styles from './IntegrationHeartbeatForm.module.scss' ;
19
+
20
+ const cx = cn . bind ( styles ) ;
18
21
19
22
interface IntegrationHeartbeatFormProps {
20
23
alertReceveChannelId : AlertReceiveChannel [ 'id' ] ;
@@ -27,88 +30,94 @@ const IntegrationHeartbeatForm = observer(({ alertReceveChannelId, onClose }: In
27
30
const { heartbeatStore, alertReceiveChannelStore } = useStore ( ) ;
28
31
29
32
const alertReceiveChannel = alertReceiveChannelStore . items [ alertReceveChannelId ] ;
33
+ const heartbeatId = alertReceiveChannelStore . alertReceiveChannelToHeartbeat [ alertReceiveChannel . id ] ;
34
+ const heartbeat = heartbeatStore . items [ heartbeatId ] ;
30
35
31
36
useEffect ( ( ) => {
32
37
heartbeatStore . updateTimeoutOptions ( ) ;
33
- } , [ heartbeatStore ] ) ;
38
+ } , [ ] ) ;
34
39
35
40
useEffect ( ( ) => {
36
- if ( alertReceiveChannel . heartbeat ) {
37
- setInterval ( alertReceiveChannel . heartbeat . timeout_seconds ) ;
38
- }
39
- } , [ alertReceiveChannel ] ) ;
41
+ setInterval ( heartbeat . timeout_seconds ) ;
42
+ } , [ heartbeat ] ) ;
40
43
41
44
const timeoutOptions = heartbeatStore . timeoutOptions ;
42
45
43
46
return (
44
47
< Drawer width = { '640px' } scrollableContent title = { 'Heartbeat' } onClose = { onClose } closeOnMaskClick = { false } >
45
- < VerticalGroup spacing = { 'lg' } >
46
- < Text type = "secondary" >
47
- A heartbeat acts as a healthcheck for alert group monitoring. You can configure you monitoring to regularly
48
- send alerts to the heartbeat endpoint. If OnCall doen't receive one of these alerts, it will create an new
49
- alert group and escalate it
50
- </ Text >
51
-
52
- < VerticalGroup spacing = "md" >
53
- < div className = { cx ( 'u-width-100' ) } >
54
- < Field label = { 'Setup heartbeat interval' } >
55
- < WithPermissionControlTooltip userAction = { UserActions . IntegrationsWrite } >
56
- < Select
57
- className = { cx ( 'select' , 'timeout' ) }
58
- onChange = { ( value : SelectableValue ) => setInterval ( value . value ) }
59
- placeholder = "Heartbeat Timeout"
60
- value = { interval }
61
- options = { ( timeoutOptions || [ ] ) . map ( ( timeoutOption : SelectOption ) => ( {
62
- value : timeoutOption . value ,
63
- label : timeoutOption . display_name ,
64
- } ) ) }
65
- />
66
- </ WithPermissionControlTooltip >
67
- </ Field >
68
- </ div >
69
-
70
- < div className = { cx ( 'u-width-100' ) } >
71
- < Field label = "Endpoint" description = "Use the following unique Grafana link to send GET and POST requests" >
72
- < IntegrationInputField value = { alertReceiveChannel ?. integration_url } showEye = { false } isMasked = { false } />
73
- </ Field >
74
- </ div >
75
- </ VerticalGroup >
76
-
77
- < VerticalGroup style = { { marginTop : 'auto' } } >
78
- < HorizontalGroup className = { cx ( 'buttons' ) } justify = "flex-end" >
79
- < Button variant = { 'secondary' } onClick = { onClose } >
80
- Cancel
81
- </ Button >
82
- < WithPermissionControlTooltip key = "ok" userAction = { UserActions . IntegrationsWrite } >
83
- < Button variant = "primary" onClick = { onSave } >
84
- { alertReceiveChannel . heartbeat ? 'Save' : 'Create' }
48
+ < div data-testid = "heartbeat-settings-form" >
49
+ < VerticalGroup spacing = { 'lg' } >
50
+ < Text type = "secondary" >
51
+ A heartbeat acts as a healthcheck for alert group monitoring. You can configure you monitoring to regularly
52
+ send alerts to the heartbeat endpoint. If OnCall doen't receive one of these alerts, it will create an new
53
+ alert group and escalate it
54
+ </ Text >
55
+
56
+ < VerticalGroup spacing = "md" >
57
+ < div className = { cx ( 'u-width-100' ) } >
58
+ < Field label = { 'Setup heartbeat interval' } >
59
+ < WithPermissionControlTooltip userAction = { UserActions . IntegrationsWrite } >
60
+ < Select
61
+ className = { cx ( 'select' , 'timeout' ) }
62
+ onChange = { ( value : SelectableValue ) => setInterval ( value . value ) }
63
+ placeholder = "Heartbeat Timeout"
64
+ value = { interval }
65
+ isLoading = { ! timeoutOptions }
66
+ options = { timeoutOptions ?. map ( ( timeoutOption : SelectOption ) => ( {
67
+ value : timeoutOption . value ,
68
+ label : timeoutOption . display_name ,
69
+ } ) ) }
70
+ />
71
+ </ WithPermissionControlTooltip >
72
+ </ Field >
73
+ </ div >
74
+ < div className = { cx ( 'u-width-100' ) } >
75
+ < Field label = "Endpoint" description = "Use the following unique Grafana link to send GET and POST requests" >
76
+ < IntegrationInputField value = { heartbeat ?. link } showEye = { false } isMasked = { false } />
77
+ </ Field >
78
+ </ div >
79
+ < a
80
+ href = "https://grafana.com/docs/oncall/latest/integrations/alertmanager/#configuring-oncall-heartbeats-optional"
81
+ target = "_blank"
82
+ rel = "noreferrer"
83
+ >
84
+ < Text type = "link" size = "small" >
85
+ < HorizontalGroup >
86
+ How to configure heartbeats
87
+ < Icon name = "external-link-alt" />
88
+ </ HorizontalGroup >
89
+ </ Text >
90
+ </ a >
91
+ </ VerticalGroup >
92
+
93
+ < VerticalGroup style = { { marginTop : 'auto' } } >
94
+ < HorizontalGroup className = { cx ( 'buttons' ) } justify = "flex-end" >
95
+ < Button variant = { 'secondary' } onClick = { onClose } data-testid = "close-heartbeat-form" >
96
+ Close
85
97
</ Button >
86
- </ WithPermissionControlTooltip >
87
- </ HorizontalGroup >
98
+ < WithPermissionControlTooltip key = "ok" userAction = { UserActions . IntegrationsWrite } >
99
+ < Button variant = "primary" onClick = { onSave } data-testid = "update-heartbeat" >
100
+ Update
101
+ </ Button >
102
+ </ WithPermissionControlTooltip >
103
+ </ HorizontalGroup >
104
+ </ VerticalGroup >
88
105
</ VerticalGroup >
89
- </ VerticalGroup >
106
+ </ div >
90
107
</ Drawer >
91
108
) ;
92
109
93
110
async function onSave ( ) {
94
- const heartbeat = alertReceiveChannel . heartbeat ;
95
-
96
- if ( heartbeat ) {
97
- await heartbeatStore . saveHeartbeat ( heartbeat . id , {
98
- alert_receive_channel : heartbeat . alert_receive_channel ,
99
- timeout_seconds : interval ,
100
- } ) ;
111
+ await heartbeatStore . saveHeartbeat ( heartbeat . id , {
112
+ alert_receive_channel : heartbeat . alert_receive_channel ,
113
+ timeout_seconds : interval ,
114
+ } ) ;
101
115
102
- onClose ( ) ;
103
- } else {
104
- await heartbeatStore . createHeartbeat ( alertReceveChannelId , {
105
- timeout_seconds : interval ,
106
- } ) ;
116
+ onClose ( ) ;
107
117
108
- onClose ( ) ;
109
- }
118
+ openNotification ( 'Heartbeat settings have been updated' ) ;
110
119
111
- await alertReceiveChannelStore . updateItem ( alertReceveChannelId ) ;
120
+ await alertReceiveChannelStore . loadItem ( alertReceveChannelId ) ;
112
121
}
113
122
} ) ;
114
123
0 commit comments