1
1
/* Copyright Contributors to the Open Cluster Management project */
2
+ import { V1CustomResourceDefinitionCondition } from '@kubernetes/client-node'
2
3
import {
3
4
Card ,
4
5
CardBody ,
@@ -14,28 +15,31 @@ import {
14
15
Title ,
15
16
} from '@patternfly/react-core'
16
17
import { CogIcon , ExclamationCircleIcon } from '@patternfly/react-icons'
17
- import { Fragment } from 'react'
18
+ import { Fragment , useEffect , useState } from 'react'
18
19
import { Link } from 'react-router-dom'
19
20
import { useTranslation } from '../../../lib/acm-i18next'
20
21
import { NavigationPath } from '../../../NavigationPath'
21
- import { SavedSearch } from '../../../resources'
22
+ import { IResource , listResources , SavedSearch } from '../../../resources'
22
23
import { useSharedAtoms } from '../../../shared-recoil'
23
24
import { convertStringToQuery } from '../Search/search-helper'
24
25
import { searchClient } from '../Search/search-sdk/search-client'
25
26
import { useSearchResultCountQuery } from '../Search/search-sdk/search-sdk'
26
27
27
- const CardHeader = ( ) => {
28
+ const CardHeader = ( props : { isSearchDisabled : boolean } ) => {
29
+ const { isSearchDisabled } = props
28
30
const { t } = useTranslation ( )
29
31
return (
30
32
< CardTitle >
31
33
< div style = { { display : 'flex' , justifyContent : 'space-between' } } >
32
34
< span > { t ( 'Saved searches' ) } </ span >
33
- < Link style = { { display : 'flex' , alignItems : 'center' } } to = { NavigationPath . search } >
34
- < CogIcon />
35
- < Text style = { { paddingLeft : '.25rem' } } component = { TextVariants . small } >
36
- { t ( 'Manage' ) }
37
- </ Text >
38
- </ Link >
35
+ { ! isSearchDisabled && (
36
+ < Link style = { { display : 'flex' , alignItems : 'center' } } to = { NavigationPath . search } >
37
+ < CogIcon />
38
+ < Text style = { { paddingLeft : '.25rem' } } component = { TextVariants . small } >
39
+ { t ( 'Manage' ) }
40
+ </ Text >
41
+ </ Link >
42
+ ) }
39
43
</ div >
40
44
</ CardTitle >
41
45
)
@@ -48,18 +52,44 @@ export default function SavedSearchesCard(
48
52
const { t } = useTranslation ( )
49
53
const { useSearchResultLimit } = useSharedAtoms ( )
50
54
const searchResultLimit = useSearchResultLimit ( )
55
+ const [ isSearchDisabledLoading , setIsSearchDisabledLoading ] = useState < boolean > ( false )
56
+ const [ isSearchDisabled , setIsSearchDisabled ] = useState < boolean > ( )
51
57
52
58
const { data, error, loading } = useSearchResultCountQuery ( {
53
59
variables : { input : savedSearches . map ( ( query ) => convertStringToQuery ( query . searchText , searchResultLimit ) ) } ,
54
60
skip : isUserPreferenceLoading || savedSearches . length === 0 ,
55
61
client : process . env . NODE_ENV === 'test' ? undefined : searchClient ,
56
62
} )
57
63
58
- if ( isUserPreferenceLoading || loading ) {
64
+ useEffect ( ( ) => {
65
+ if ( error ) {
66
+ setIsSearchDisabledLoading ( true )
67
+ listResources < IResource > ( {
68
+ apiVersion : 'search.open-cluster-management.io/v1alpha1' ,
69
+ kind : 'Search' ,
70
+ } )
71
+ . promise . then ( ( response ) => {
72
+ const operatorConditions : V1CustomResourceDefinitionCondition [ ] = response [ 0 ] ?. status ?. conditions ?? [ ]
73
+ const searchApiCondition = operatorConditions . find ( ( c : V1CustomResourceDefinitionCondition ) => {
74
+ return c . type . toLowerCase ( ) === 'ready--search-api' && c . status === 'False'
75
+ } )
76
+ if ( searchApiCondition ) {
77
+ setIsSearchDisabled ( true )
78
+ }
79
+ setIsSearchDisabledLoading ( false )
80
+ } )
81
+ . catch ( ( err ) => {
82
+ console . error ( 'Error getting resource: ' , err )
83
+ setIsSearchDisabledLoading ( false )
84
+ } )
85
+ }
86
+ } , [ error ] )
87
+
88
+ if ( isUserPreferenceLoading || loading || isSearchDisabledLoading ) {
59
89
return (
60
90
< div >
61
91
< Card isRounded >
62
- < CardHeader />
92
+ < CardHeader isSearchDisabled = { false } />
63
93
< CardBody >
64
94
< div style = { { display : 'flex' , justifyContent : 'space-between' } } >
65
95
< Skeleton width = "45%" />
@@ -75,19 +105,23 @@ export default function SavedSearchesCard(
75
105
</ div >
76
106
)
77
107
} else if ( error ) {
108
+ const searchDisabledTitle = 'This view is disabled with the current configuration.'
109
+ const searchDisabledMessage = 'Enable the search service to see this view.'
78
110
return (
79
111
< Card isRounded >
80
- < CardHeader />
112
+ < CardHeader isSearchDisabled />
81
113
< EmptyState style = { { paddingTop : 0 , marginTop : 'auto' } } >
82
- < EmptyStateIcon
83
- style = { { fontSize : '36px' , marginBottom : '1rem' } }
84
- icon = { ExclamationCircleIcon }
85
- color = { 'var(--pf-global--danger-color--100)' }
86
- />
114
+ { ! isSearchDisabled && (
115
+ < EmptyStateIcon
116
+ style = { { fontSize : '36px' , marginBottom : '1rem' } }
117
+ icon = { ExclamationCircleIcon }
118
+ color = { 'var(--pf-global--danger-color--100)' }
119
+ />
120
+ ) }
87
121
< Title size = "md" headingLevel = "h4" >
88
- { t ( 'Error occurred while getting the result count.' ) }
122
+ { isSearchDisabled ? searchDisabledTitle : t ( 'Error occurred while getting the result count.' ) }
89
123
</ Title >
90
- < EmptyStateBody > { error . message } </ EmptyStateBody >
124
+ < EmptyStateBody > { isSearchDisabled ? searchDisabledMessage : error . message } </ EmptyStateBody >
91
125
</ EmptyState >
92
126
</ Card >
93
127
)
@@ -116,7 +150,7 @@ export default function SavedSearchesCard(
116
150
return (
117
151
< div >
118
152
< Card isRounded >
119
- < CardHeader />
153
+ < CardHeader isSearchDisabled = { false } />
120
154
< CardBody >
121
155
< div style = { { display : 'grid' , gridTemplateColumns : 'auto auto auto auto auto' , columnGap : 16 } } >
122
156
{ savedSearches . map ( ( savedSearch : SavedSearch , index : number ) => {
0 commit comments