1
- import React , { useContext , useEffect , useRef , useState } from 'react' ;
1
+ import React , { useContext , useEffect , useState } from 'react' ;
2
2
import PropTypes from 'prop-types' ;
3
3
4
4
import {
@@ -12,15 +12,17 @@ import {
12
12
navigation ,
13
13
} from 'nr1' ;
14
14
15
- import { SIGNAL_TYPES , STATUSES } from '../../constants' ;
16
-
17
15
import Incidents from './incidents' ;
18
16
import GoldenMetrics from './golden-metrics' ;
19
17
import { AppContext } from '../../contexts' ;
18
+ import {
19
+ workloadEntitiesQuery ,
20
+ workloadEntitiesViolationsFromGuidsArray ,
21
+ } from '../../queries' ;
22
+ import { formatTimestamp , isWorkload } from '../../utils' ;
23
+ import { MAX_PARAMS_IN_QUERY , SIGNAL_TYPES , STATUSES } from '../../constants' ;
20
24
21
25
import typesList from '../../../nerdlets/signal-selection/types.json' ;
22
- import { formatTimestamp , isWorkload } from '../../utils' ;
23
- import { statusesFromGuidsArray , workloadEntitiesQuery } from '../../queries' ;
24
26
25
27
const NO_ENTITY_TYPE = '(unknown entity type)' ;
26
28
@@ -33,13 +35,27 @@ const entityTypeFromData = (entityData) => {
33
35
) ;
34
36
} ;
35
37
38
+ const isWorkloadNotOK = ( { statusValueCode, alertSeverity } = { } ) => {
39
+ const notOKStatusValueCodes = [ 2 , 3 ] ;
40
+ const notOKAlertSeveritiesRE = new RegExp (
41
+ `${ STATUSES . CRITICAL } |${ STATUSES . WARNING } ` ,
42
+ 'i'
43
+ ) ;
44
+
45
+ return (
46
+ notOKStatusValueCodes . includes ( statusValueCode ) ||
47
+ notOKAlertSeveritiesRE . test ( alertSeverity )
48
+ ) ;
49
+ } ;
50
+
36
51
const SignalDetailSidebar = ( { guid, name, type, data, timeWindow } ) => {
37
52
const { account = { } , accounts = [ ] } = useContext ( AppContext ) ;
38
53
const [ hasAccessToEntity , setHasAccessToEntity ] = useState ( false ) ;
39
54
const [ signalAccount , setSignalAccount ] = useState ( ) ;
40
55
const [ detailLinkText , setDetailLinkText ] = useState ( 'View entity details' ) ;
41
56
const [ incidentsData , setIncidentsData ] = useState ( null ) ;
42
- const prevTimeWindow = useRef ( { } ) ;
57
+ const [ isLoadingWorkloadViolations , setIsLoadingWorkloadViolations ] =
58
+ useState ( false ) ;
43
59
44
60
useEffect ( ( ) => {
45
61
const [ acctId , condId ] = ( ( atob ( guid ) || '' ) . split ( '|' ) || [ ] ) . reduce (
@@ -64,27 +80,19 @@ const SignalDetailSidebar = ({ guid, name, type, data, timeWindow }) => {
64
80
} , [ guid , type , account , accounts ] ) ;
65
81
66
82
useEffect ( ( ) => {
83
+ if ( ! guid || ! type ) return ;
84
+ let curData = { ...data } ;
67
85
if (
86
+ ! data ||
68
87
type !== SIGNAL_TYPES . ENTITY ||
69
88
! isWorkload ( data ) ||
70
- ! (
71
- data . statusValueCode === 3 ||
72
- data . statusValueCode === 2 ||
73
- data . alertSeverity === STATUSES . CRITICAL ||
74
- data . alertSeverity === STATUSES . WARNING
75
- )
89
+ ! isWorkloadNotOK ( data )
76
90
) {
77
91
setIncidentsData ( data ) ;
78
92
return ;
79
93
}
80
94
81
- let shouldClearData = false ;
82
- const { start : prevStart , end : prevEnd } = prevTimeWindow . current || { } ;
83
- if ( timeWindow . start !== prevStart || timeWindow . end !== prevEnd ) {
84
- shouldClearData = true ;
85
- prevTimeWindow . current = timeWindow ;
86
- }
87
-
95
+ setIsLoadingWorkloadViolations ( true ) ;
88
96
const loadWorkloadIncidents = async ( g ) => {
89
97
const {
90
98
data : {
@@ -101,15 +109,27 @@ const SignalDetailSidebar = ({ guid, name, type, data, timeWindow }) => {
101
109
console . error ( 'Error listing workload entities' , error ) ;
102
110
return ;
103
111
}
104
- const workloadEntitiesGuids = results ?. reduce (
105
- ( acc , { target : { guid : g } = { } } ) => ( g ? [ ...acc , g ] : acc ) ,
106
- [ ]
107
- ) ;
112
+ let workloadEntitiesGuids = [ ] ;
113
+ for ( let i = 0 ; i < results ?. length ; i += MAX_PARAMS_IN_QUERY ) {
114
+ const guidsArr = results
115
+ . slice ( i , i + MAX_PARAMS_IN_QUERY )
116
+ . map ( ( { target : { guid : g } = { } } ) => g )
117
+ . filter ( ( g ) => ! ! g ) ;
118
+ workloadEntitiesGuids = [ ...workloadEntitiesGuids , guidsArr ] ;
119
+ }
120
+ if ( ! workloadEntitiesGuids . length ) {
121
+ console . error ( 'Unable to fetch workload entities' ) ;
122
+ setIsLoadingWorkloadViolations ( false ) ;
123
+ return ;
124
+ }
108
125
const {
109
126
data : { actor : { __typename, ...entitiesObj } = { } } = { } , // eslint-disable-line no-unused-vars
110
127
error : error2 ,
111
128
} = await NerdGraphQuery . query ( {
112
- query : statusesFromGuidsArray ( [ workloadEntitiesGuids ] , timeWindow ) ,
129
+ query : workloadEntitiesViolationsFromGuidsArray (
130
+ workloadEntitiesGuids ,
131
+ timeWindow
132
+ ) ,
113
133
} ) ;
114
134
if ( error2 ) {
115
135
console . error ( 'Error loading workload entities' , error2 ) ;
@@ -127,26 +147,18 @@ const SignalDetailSidebar = ({ guid, name, type, data, timeWindow }) => {
127
147
}
128
148
const violations = entity ?. [ violationsKey ] || [ ] ;
129
149
if ( violations . length ) {
130
- setIncidentsData ( ( d ) =>
131
- d && ! shouldClearData
132
- ? {
133
- ...d ,
134
- [ violationsKey ] : [
135
- ...( d [ violationsKey ] || [ ] ) ,
136
- ...violations ,
137
- ] ,
138
- }
139
- : {
140
- ...data ,
141
- [ violationsKey ] : [
142
- ...( data [ violationsKey ] || [ ] ) ,
143
- ...violations ,
144
- ] ,
145
- }
146
- ) ;
150
+ curData = {
151
+ ...curData ,
152
+ [ violationsKey ] : [
153
+ ...( curData [ violationsKey ] || [ ] ) ,
154
+ ...violations ,
155
+ ] ,
156
+ } ;
147
157
}
148
158
} ) ;
149
159
} ) ;
160
+ setIncidentsData ( curData ) ;
161
+ setIsLoadingWorkloadViolations ( false ) ;
150
162
} ;
151
163
loadWorkloadIncidents ( guid ) ;
152
164
} , [ guid , type , data , timeWindow ] ) ;
@@ -190,7 +202,12 @@ const SignalDetailSidebar = ({ guid, name, type, data, timeWindow }) => {
190
202
</ div >
191
203
{ hasAccessToEntity ? (
192
204
< >
193
- < Incidents type = { type } data = { incidentsData } timeWindow = { timeWindow } />
205
+ < Incidents
206
+ type = { type }
207
+ data = { incidentsData }
208
+ timeWindow = { timeWindow }
209
+ isLoading = { isLoadingWorkloadViolations }
210
+ />
194
211
{ type === SIGNAL_TYPES . ENTITY ? (
195
212
< GoldenMetrics guid = { guid } data = { data } timeWindow = { timeWindow } />
196
213
) : null }
0 commit comments