11import React , { useEffect , useState } from 'react' ;
22
33import {
4- Button ,
54 FormGroup ,
65 MenuToggle ,
76 MenuToggleElement ,
87 Select ,
98 SelectList ,
109 SelectOption ,
1110 Spinner ,
12- TextInputGroup ,
13- TextInputGroupMain ,
14- TextInputGroupUtilities ,
1511} from '@patternfly/react-core' ;
16- import { TimesIcon } from '@patternfly/react-icons' ;
1712
1813import {
1914 DistributionProfileItem ,
@@ -31,7 +26,6 @@ import {
3126 changeFscMode ,
3227 clearKernelAppend ,
3328 selectComplianceProfileID ,
34- selectComplianceType ,
3529 selectDistribution ,
3630 setOscapProfile ,
3731} from '@/store/slices/wizard' ;
@@ -68,21 +62,13 @@ const ProfileSelector = ({
6862 ) ;
6963 const dispatch = useAppDispatch ( ) ;
7064 const [ isOpen , setIsOpen ] = useState ( false ) ;
71- const [ inputValue , setInputValue ] = useState < string > ( '' ) ;
72- const [ filterValue , setFilterValue ] = useState < string > ( '' ) ;
73- const [ selectOptions , setSelectOptions ] = useState <
74- {
75- id : DistributionProfileItem ;
76- name : string | undefined ;
77- } [ ]
78- > ( [ ] ) ;
65+ const [ isApplying , setIsApplying ] = useState ( false ) ;
7966 const [ profileDetails , setProfileDetails ] = useState <
8067 {
8168 id : DistributionProfileItem ;
8269 name : string | undefined ;
8370 } [ ]
8471 > ( [ ] ) ;
85- const complianceType = useAppSelector ( selectComplianceType ) ;
8672 const prefetchProfile = useBackendPrefetch ( 'getOscapCustomizations' ) ;
8773 const {
8874 clearCompliancePackages,
@@ -103,14 +89,6 @@ const ProfileSelector = ({
10389
10490 const [ trigger ] = useLazyGetOscapCustomizationsQuery ( ) ;
10591
106- useEffect ( ( ) => {
107- if ( ! profileID ) {
108- setInputValue ( '' ) ;
109- setFilterValue ( '' ) ;
110- setIsOpen ( false ) ;
111- }
112- } , [ profileID ] ) ;
113-
11492 // prefetch the profiles customizations for on-prem
11593 // and save the results to the cache, since the request
11694 // is quite slow
@@ -148,30 +126,13 @@ const ProfileSelector = ({
148126
149127 const resolvedProfiles = await Promise . all ( promises ) ;
150128 setProfileDetails ( resolvedProfiles ) ;
151- setSelectOptions ( resolvedProfiles ) ;
152129 } ;
153130
154131 fetchProfileDetails ( ) ;
155132 } , [ profiles , release , trigger ] ) ;
156133
157- useEffect ( ( ) => {
158- if ( ! filterValue ) {
159- setSelectOptions ( profileDetails ) ;
160- return ;
161- }
162- const trimmedFilter = filterValue . toLowerCase ( ) . trim ( ) ;
163- const filtered = profileDetails . filter ( ( { name } ) =>
164- name ?. toLowerCase ( ) . includes ( trimmedFilter ) ,
165- ) ;
166-
167- setSelectOptions ( filtered ) ;
168- if ( ! isOpen && filtered . length > 0 ) {
169- setIsOpen ( true ) ;
170- }
171- } , [ filterValue , profileDetails , isOpen ] ) ;
172-
173134 const handleToggle = ( ) => {
174- if ( ! isOpen && complianceType === 'openscap' ) {
135+ if ( ! isOpen ) {
175136 refetch ( ) ;
176137 }
177138 setIsOpen ( ! isOpen ) ;
@@ -184,53 +145,13 @@ const ProfileSelector = ({
184145 handleServices ( undefined ) ;
185146 dispatch ( clearKernelAppend ( ) ) ;
186147 dispatch ( changeFips ( false ) ) ;
187- setInputValue ( '' ) ;
188- setFilterValue ( '' ) ;
189- } ;
190-
191- const onInputClick = ( ) => {
192- if ( ! isOpen ) {
193- setIsOpen ( true ) ;
194- } else if ( ! inputValue ) {
195- setIsOpen ( false ) ;
196- }
197- } ;
198-
199- const onTextInputChange = ( _event : React . FormEvent , value : string ) => {
200- setInputValue ( value ) ;
201- setFilterValue ( value ) ;
202-
203- if ( value !== profileID ) {
204- dispatch ( setOscapProfile ( undefined ) ) ;
205- }
206- } ;
207-
208- const onKeyDown = ( event : React . KeyboardEvent ) => {
209- if ( event . key === 'Enter' ) {
210- event . preventDefault ( ) ;
211-
212- if ( ! isOpen ) {
213- setIsOpen ( true ) ;
214- } else if ( selectOptions . length === 1 ) {
215- const singleProfile = selectOptions [ 0 ] ;
216- const selection : OScapSelectOptionValueType = {
217- profileID : singleProfile . id ,
218- toString : ( ) => singleProfile . name || '' ,
219- } ;
220-
221- setInputValue ( singleProfile . name || '' ) ;
222- setFilterValue ( '' ) ;
223- applyChanges ( selection ) ;
224- setIsOpen ( false ) ;
225- }
226- }
227148 } ;
228149
229150 const applyChanges = ( selection : OScapSelectOptionValueType ) => {
230151 if ( selection . profileID === undefined ) {
231- // handle user has selected 'None' case
232152 handleClear ( ) ;
233153 } else {
154+ setIsApplying ( true ) ;
234155 const oldOscapPackages = currentProfileData ?. packages || [ ] ;
235156 trigger (
236157 {
@@ -253,7 +174,8 @@ const ProfileSelector = ({
253174 handleKernelAppend ( response . kernel ?. append ) ;
254175 dispatch ( setOscapProfile ( selection . profileID ) ) ;
255176 dispatch ( changeFips ( response . fips ?. enabled || false ) ) ;
256- } ) ;
177+ } )
178+ . finally ( ( ) => setIsApplying ( false ) ) ;
257179 }
258180 } ;
259181
@@ -263,49 +185,56 @@ const ProfileSelector = ({
263185 ) => {
264186 if ( selection === undefined ) return ;
265187
266- setInputValue ( ( selection as OScapSelectOptionValueType [ 'profileID' ] ) || '' ) ;
267- setFilterValue ( '' ) ;
268188 applyChanges ( selection as unknown as OScapSelectOptionValueType ) ;
269189 setIsOpen ( false ) ;
270190 } ;
271191
192+ const selectedProfileName = profileID
193+ ? profileDetails . find ( ( { id } ) => id === profileID ) ?. name || profileID
194+ : undefined ;
195+
196+ const profileOptions = ( ) => {
197+ if ( isFetching ) {
198+ return [
199+ < SelectOption key = 'oscap-loader' value = 'loader' >
200+ < Spinner size = 'lg' />
201+ </ SelectOption > ,
202+ ] ;
203+ }
204+
205+ const res = profileDetails . map ( ( { id, name } ) => (
206+ < SelectOption
207+ key = { id }
208+ value = { {
209+ profileID : id ,
210+ toString : ( ) => name ,
211+ } }
212+ isSelected = { profileID === id }
213+ >
214+ { name }
215+ </ SelectOption >
216+ ) ) ;
217+ return res ;
218+ } ;
219+
272220 const toggleOpenSCAP = ( toggleRef : React . Ref < MenuToggleElement > ) => (
273221 < MenuToggle
274222 data-testid = 'profileSelect'
275223 ref = { toggleRef }
276- variant = 'typeahead'
224+ isPlaceholder = { ! selectedProfileName && ! isApplying }
277225 onClick = { ( ) => setIsOpen ( ! isOpen ) }
278226 isExpanded = { isOpen }
279- isDisabled = { isDisabled || ! isSuccess }
227+ isDisabled = { isDisabled || ! isSuccess || isApplying }
280228 isFullWidth
229+ style = { { maxWidth : 'none' } }
281230 >
282- < TextInputGroup isPlain >
283- < TextInputGroupMain
284- value = {
285- profileID
286- ? profileDetails . find ( ( { id } ) => id === profileID ) ?. name ||
287- profileID
288- : inputValue
289- }
290- onClick = { onInputClick }
291- onChange = { onTextInputChange }
292- onKeyDown = { onKeyDown }
293- autoComplete = 'off'
294- placeholder = 'Select a profile'
295- isExpanded = { isOpen }
296- />
297-
298- { profileID && (
299- < TextInputGroupUtilities >
300- < Button
301- icon = { < TimesIcon /> }
302- variant = 'plain'
303- onClick = { handleClear }
304- aria-label = 'Clear input'
305- />
306- </ TextInputGroupUtilities >
307- ) }
308- </ TextInputGroup >
231+ { isApplying ? (
232+ < >
233+ < Spinner size = 'sm' /> Applying profile...
234+ </ >
235+ ) : (
236+ selectedProfileName || 'Select a profile'
237+ ) }
309238 </ MenuToggle >
310239 ) ;
311240
@@ -319,35 +248,8 @@ const ProfileSelector = ({
319248 onOpenChange = { handleToggle }
320249 toggle = { toggleOpenSCAP }
321250 shouldFocusFirstItemOnOpen = { false }
322- popperProps = { {
323- maxWidth : '50vw' ,
324- } }
325251 >
326- < SelectList >
327- { isFetching && (
328- < SelectOption value = 'loader' >
329- < Spinner size = 'lg' />
330- </ SelectOption >
331- ) }
332- { selectOptions . length > 0 &&
333- selectOptions . map ( ( { id, name } ) => (
334- < SelectOption
335- key = { id }
336- value = { {
337- profileID : id ,
338- toString : ( ) => name ,
339- } }
340- isSelected = { profileID === id }
341- >
342- { name }
343- </ SelectOption >
344- ) ) }
345- { isSuccess && selectOptions . length === 0 && (
346- < SelectOption isDisabled >
347- { `No results found for "${ filterValue } "` }
348- </ SelectOption >
349- ) }
350- </ SelectList >
252+ < SelectList > { profileOptions ( ) } </ SelectList >
351253 </ Select >
352254 </ FormGroup >
353255 ) ;
0 commit comments