@@ -22,21 +22,24 @@ import {
22
22
EuiText ,
23
23
EuiFieldText ,
24
24
EuiLoadingSpinner ,
25
+ EuiButton ,
25
26
} from '@elastic/eui' ;
26
27
import { CoreStart } from '../../../../../../src/core/public' ;
27
28
import { CoreServicesContext } from '../../../components/CoreServices/CoreServices' ;
28
29
import { get , isEmpty } from 'lodash' ;
29
30
import { RouteComponentProps , Switch , Route , Redirect } from 'react-router-dom' ;
30
- import { useDispatch } from 'react-redux' ;
31
+ import { useDispatch , useSelector } from 'react-redux' ;
31
32
import { useFetchDetectorInfo } from '../../CreateDetectorSteps/hooks/useFetchDetectorInfo' ;
32
33
import { useHideSideNavBar } from '../../main/hooks/useHideSideNavBar' ;
34
+ import { AppState } from '../../../redux/reducers' ;
33
35
import {
34
36
deleteDetector ,
35
37
startDetector ,
36
38
stopDetector ,
37
39
getDetector ,
38
40
stopHistoricalDetector ,
39
41
} from '../../../redux/reducers/ad' ;
42
+ import { getIndices } from '../../../redux/reducers/opensearch' ;
40
43
import { getErrorMessage , Listener } from '../../../utils/utils' ;
41
44
import { darkModeEnabled } from '../../../utils/opensearchDashboardsUtils' ;
42
45
import { BREADCRUMBS } from '../../../utils/constants' ;
@@ -53,6 +56,8 @@ import {
53
56
prettifyErrorMessage ,
54
57
} from '../../../../server/utils/helpers' ;
55
58
import { DETECTOR_STATE } from '../../../../server/utils/constants' ;
59
+ import { CatIndex } from '../../../../server/models/types' ;
60
+ import { containsIndex } from '../utils/helpers' ;
56
61
57
62
export interface DetectorRouterProps {
58
63
detectorId ?: string ;
@@ -102,6 +107,15 @@ export const DetectorDetail = (props: DetectorDetailProps) => {
102
107
useFetchDetectorInfo ( detectorId ) ;
103
108
const { monitor, fetchMonitorError, isLoadingMonitor } =
104
109
useFetchMonitorInfo ( detectorId ) ;
110
+ const visibleIndices = useSelector (
111
+ ( state : AppState ) => state . opensearch . indices
112
+ ) as CatIndex [ ] ;
113
+ const isResultIndexMissing = isLoadingDetector
114
+ ? false
115
+ : isEmpty ( get ( detector , 'resultIndex' , '' ) )
116
+ ? false
117
+ : ! containsIndex ( get ( detector , 'resultIndex' , '' ) , visibleIndices ) ;
118
+
105
119
// String to set in the modal if the realtime detector and/or historical analysis
106
120
// are running when the user tries to edit the detector details or model config
107
121
const isRTJobRunning = get ( detector , 'enabled' ) ;
@@ -138,6 +152,18 @@ export const DetectorDetail = (props: DetectorDetailProps) => {
138
152
scroll ( 0 , 0 ) ;
139
153
} , [ ] ) ;
140
154
155
+ // Getting all visible indices. Will re-fetch if changes to the detector (e.g.,
156
+ // detector starts, result index recreated or user switches tabs to re-fetch detector)
157
+ useEffect ( ( ) => {
158
+ const getInitialIndices = async ( ) => {
159
+ await dispatch ( getIndices ( '' ) ) . catch ( ( error : any ) => {
160
+ console . error ( error ) ;
161
+ core . notifications . toasts . addDanger ( 'Error getting all indices' ) ;
162
+ } ) ;
163
+ } ;
164
+ getInitialIndices ( ) ;
165
+ } , [ detector ] ) ;
166
+
141
167
useEffect ( ( ) => {
142
168
if ( hasError ) {
143
169
core . notifications . toasts . addDanger (
@@ -365,6 +391,22 @@ export const DetectorDetail = (props: DetectorDetailProps) => {
365
391
/>
366
392
</ EuiFlexItem >
367
393
</ EuiFlexGroup >
394
+ { isResultIndexMissing ? (
395
+ < EuiCallOut
396
+ style = { {
397
+ marginLeft : '10px' ,
398
+ marginRight : '10px' ,
399
+ marginBottom : '10px' ,
400
+ } }
401
+ title = { `Your detector is using custom result index '${ get (
402
+ detector ,
403
+ 'resultIndex' ,
404
+ ''
405
+ ) } ', but is not found in the cluster. The index will be recreated when you start a real-time or historical job.`}
406
+ color = "danger"
407
+ iconType = "alert"
408
+ > </ EuiCallOut >
409
+ ) : null }
368
410
369
411
< EuiFlexGroup >
370
412
< EuiFlexItem >
0 commit comments