3
3
* SPDX-License-Identifier: Apache-2.0
4
4
*/
5
5
6
- import React , { useState } from 'react' ;
6
+ import React , { useEffect , useState } from 'react' ;
7
+ import { useSelector } from 'react-redux' ;
8
+ import { get } from 'lodash' ;
7
9
import {
8
10
EuiFlexItem ,
9
11
EuiFlyout ,
10
12
EuiFlyoutBody ,
11
13
EuiFlyoutHeader ,
14
+ EuiSpacer ,
12
15
EuiTab ,
13
16
EuiTabs ,
14
17
EuiTitle ,
15
18
} from '@elastic/eui' ;
16
19
import {
20
+ CONFIG_STEP ,
21
+ customStringify ,
17
22
WORKFLOW_RESOURCE_TYPE ,
23
+ WORKFLOW_STEP_TYPE ,
18
24
WorkflowResource ,
19
25
} from '../../../../../common' ;
20
26
import { ResourceFlyoutContent } from './resource_flyout_content' ;
21
- import { get } from 'lodash' ;
27
+ import { extractIdsByStepType , getDataSourceId } from '../../../../utils' ;
28
+ import {
29
+ AppState ,
30
+ getIndex ,
31
+ getIngestPipeline ,
32
+ getSearchPipeline ,
33
+ useAppDispatch ,
34
+ } from '../../../../store' ;
22
35
23
36
interface ResourcesFlyoutProps {
24
37
resources : WorkflowResource [ ] ;
25
- resourceDetails : string [ ] ;
38
+ selectedStep : CONFIG_STEP ;
26
39
onClose : ( ) => void ;
27
- errorMessage ?: string ;
28
40
}
29
41
30
42
/**
31
- * A simple flyout to display details for multiple workflow resources nested
32
- * under tabs.
43
+ * Flyout to display details for multiple workflow resources, depending on the context (ingest or search).
44
+ * Dynamically render data nested under tabs if there are multiple - e.g., an index and ingest pipeline under the ingest context .
33
45
*/
34
46
export function ResourcesFlyout ( props : ResourcesFlyoutProps ) {
47
+ const dispatch = useAppDispatch ( ) ;
48
+ const dataSourceId = getDataSourceId ( ) ;
49
+
50
+ const {
51
+ getIndexErrorMessage,
52
+ getIngestPipelineErrorMessage,
53
+ getSearchPipelineErrorMessage,
54
+ indexDetails,
55
+ ingestPipelineDetails,
56
+ searchPipelineDetails,
57
+ } = useSelector ( ( state : AppState ) => state . opensearch ) ;
58
+
59
+ // Fetch the filtered resource(s) based on ingest or search context
60
+ const [ allResources , setAllResources ] = useState < WorkflowResource [ ] > ( [ ] ) ;
61
+ useEffect ( ( ) => {
62
+ if ( props . resources ) {
63
+ const resourcesMap = { } as { [ id : string ] : WorkflowResource } ;
64
+ props . resources . forEach ( ( resource ) => {
65
+ if (
66
+ ( props . selectedStep === CONFIG_STEP . INGEST &&
67
+ ( resource . stepType === WORKFLOW_STEP_TYPE . CREATE_INDEX_STEP_TYPE ||
68
+ resource . stepType ===
69
+ WORKFLOW_STEP_TYPE . CREATE_INGEST_PIPELINE_STEP_TYPE ) ) ||
70
+ ( props . selectedStep === CONFIG_STEP . SEARCH &&
71
+ resource . stepType ===
72
+ WORKFLOW_STEP_TYPE . CREATE_SEARCH_PIPELINE_STEP_TYPE )
73
+ ) {
74
+ resourcesMap [ resource . id ] = resource ;
75
+ }
76
+ } ) ;
77
+ setAllResources ( Object . values ( resourcesMap || { } ) ) ;
78
+ }
79
+ } , [ props . resources ] ) ;
80
+
81
+ // fetch details for each resource type
82
+ useEffect ( ( ) => {
83
+ const {
84
+ indexIds,
85
+ ingestPipelineIds,
86
+ searchPipelineIds,
87
+ } = extractIdsByStepType ( allResources ) ;
88
+ if ( indexIds ) {
89
+ try {
90
+ dispatch ( getIndex ( { index : indexIds , dataSourceId } ) ) ;
91
+ } catch { }
92
+ }
93
+ if ( ingestPipelineIds ) {
94
+ try {
95
+ dispatch (
96
+ getIngestPipeline ( { pipelineId : ingestPipelineIds , dataSourceId } )
97
+ ) ;
98
+ } catch { }
99
+ }
100
+ if ( searchPipelineIds ) {
101
+ try {
102
+ dispatch (
103
+ getSearchPipeline ( { pipelineId : searchPipelineIds , dataSourceId } )
104
+ ) ;
105
+ } catch { }
106
+ }
107
+ } , [ allResources ] ) ;
108
+
109
+ // keep state for the resource index, and the selected tab ID (if applicable)
35
110
const [ selectedResourceIdx , setSelectedResourceIdx ] = useState < number > ( 0 ) ;
36
- const [ selectedTabId , setSelectedTabId ] = useState < string > (
37
- get ( props , `resources.${ selectedResourceIdx } .id` )
38
- ) ;
39
- const selectedResource = get (
40
- props ,
41
- `resources.${ selectedResourceIdx } ` ,
42
- undefined
43
- ) as WorkflowResource | undefined ;
44
- const selectedResourceDetails = get (
45
- props ,
46
- `resourceDetails.${ selectedResourceIdx } ` ,
47
- undefined
48
- ) as string | undefined ;
111
+ const [ selectedTabId , setSelectedTabId ] = useState < string > ( '' ) ;
112
+ useEffect ( ( ) => {
113
+ if ( allResources ) {
114
+ setSelectedTabId ( get ( allResources , `0.id` ) ) ;
115
+ }
116
+ } , [ allResources ] ) ;
117
+
118
+ // get the resource details, and any error message, based on the selected resource index
119
+ const selectedResource = get ( allResources , selectedResourceIdx , undefined ) as
120
+ | WorkflowResource
121
+ | undefined ;
122
+ const selectedResourceDetailsObj =
123
+ indexDetails [ selectedResource ?. id || '' ] ??
124
+ ingestPipelineDetails [ selectedResource ?. id || '' ] ??
125
+ searchPipelineDetails [ selectedResource ?. id || '' ] ??
126
+ '' ;
127
+ const selectedResourceDetails = customStringify ( {
128
+ [ selectedResource ?. id || '' ] : selectedResourceDetailsObj ,
129
+ } ) ;
130
+ const selectedResourceErrorMessage =
131
+ selectedResource ?. stepType === WORKFLOW_STEP_TYPE . CREATE_INDEX_STEP_TYPE
132
+ ? getIndexErrorMessage
133
+ : selectedResource ?. stepType ===
134
+ WORKFLOW_STEP_TYPE . CREATE_INGEST_PIPELINE_STEP_TYPE
135
+ ? getIngestPipelineErrorMessage
136
+ : selectedResource ?. stepType ===
137
+ WORKFLOW_STEP_TYPE . CREATE_SEARCH_PIPELINE_STEP_TYPE
138
+ ? getSearchPipelineErrorMessage
139
+ : ( undefined as string | undefined ) ;
49
140
50
141
return (
51
142
< EuiFlyout onClose = { props . onClose } >
@@ -55,33 +146,36 @@ export function ResourcesFlyout(props: ResourcesFlyoutProps) {
55
146
</ EuiTitle >
56
147
</ EuiFlyoutHeader >
57
148
< EuiFlyoutBody >
58
- < EuiFlexItem grow = { false } >
59
- < EuiTabs size = "s" expand = { false } >
60
- { props . resources ?. map ( ( tab , idx ) => {
61
- return (
62
- < EuiTab
63
- onClick = { ( ) => {
64
- setSelectedTabId ( tab . id ) ;
65
- setSelectedResourceIdx ( idx ) ;
66
- } }
67
- isSelected = { tab . id === selectedTabId }
68
- disabled = { false }
69
- key = { idx }
70
- >
71
- { tab ?. type === WORKFLOW_RESOURCE_TYPE . INDEX_NAME
72
- ? 'Index'
73
- : 'Pipeline' }
74
- </ EuiTab >
75
- ) ;
76
- } ) }
77
- </ EuiTabs >
78
- </ EuiFlexItem >
149
+ { allResources . length > 1 && (
150
+ < EuiFlexItem grow = { false } >
151
+ < EuiTabs size = "s" expand = { false } >
152
+ { allResources ?. map ( ( tab , idx ) => {
153
+ return (
154
+ < EuiTab
155
+ onClick = { ( ) => {
156
+ setSelectedTabId ( tab . id ) ;
157
+ setSelectedResourceIdx ( idx ) ;
158
+ } }
159
+ isSelected = { tab . id === selectedTabId }
160
+ disabled = { false }
161
+ key = { idx }
162
+ >
163
+ { tab ?. type === WORKFLOW_RESOURCE_TYPE . INDEX_NAME
164
+ ? 'Index'
165
+ : 'Pipeline' }
166
+ </ EuiTab >
167
+ ) ;
168
+ } ) }
169
+ </ EuiTabs >
170
+ < EuiSpacer size = "m" />
171
+ </ EuiFlexItem >
172
+ ) }
79
173
{ selectedResource !== undefined &&
80
174
selectedResourceDetails !== undefined && (
81
175
< ResourceFlyoutContent
82
176
resource = { selectedResource }
83
177
resourceDetails = { selectedResourceDetails }
84
- errorMessage = { props . errorMessage }
178
+ errorMessage = { selectedResourceErrorMessage }
85
179
/>
86
180
) }
87
181
</ EuiFlyoutBody >
0 commit comments