import React, { useEffect, useState } from 'react'; import { Alert, Button, FormGroup, MenuToggle, MenuToggleElement, Select, SelectList, SelectOption, Spinner, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, } from '@patternfly/react-core'; import { TimesIcon } from '@patternfly/react-icons'; import { useAppDispatch, useAppSelector } from '../../../../../store/hooks'; import { useGetSourceListQuery, useGetSourceUploadInfoQuery, } from '../../../../../store/provisioningApi'; import { changeAzureResourceGroup, changeAzureSource, changeAzureSubscriptionId, changeAzureTenantId, selectAzureSource, } from '../../../../../store/wizardSlice'; export const AzureSourcesSelect = () => { const azureSource = useAppSelector(selectAzureSource); const dispatch = useAppDispatch(); const [isOpen, setIsOpen] = useState(false); const [inputValue, setInputValue] = useState(''); const [filterValue, setFilterValue] = useState(''); const { data: rawSources, isFetching, isSuccess, isError, refetch, } = useGetSourceListQuery({ provider: 'azure' }); const { data: sourceDetails, isFetching: isFetchingDetails, isSuccess: isSuccessDetails, isError: isErrorDetails, } = useGetSourceUploadInfoQuery( { id: parseInt(azureSource as string) }, { skip: !azureSource, }, ); const [selectOptions, setSelectOptions] = useState<(string | undefined)[]>( rawSources?.data?.map((source) => source?.name) || [], ); useEffect(() => { if (isFetchingDetails || !isSuccessDetails) return; dispatch(changeAzureTenantId(sourceDetails?.azure?.tenant_id || '')); dispatch( changeAzureSubscriptionId(sourceDetails?.azure?.subscription_id || ''), ); }, [ isFetchingDetails, isSuccessDetails, sourceDetails?.azure?.tenant_id, sourceDetails?.azure?.subscription_id, dispatch, ]); useEffect(() => { let filteredSources = rawSources?.data?.map((source) => source?.name); if (filterValue) { filteredSources = rawSources?.data ?.map((source) => source?.name) .filter((source: string) => String(source).toLowerCase().includes(filterValue.toLowerCase()), ); if (!isOpen) { setIsOpen(true); } } if (filteredSources) { setSelectOptions(filteredSources); } // This useEffect hook should run *only* on when the filter value changes. // eslint's exhaustive-deps rule does not support this use. // eslint-disable-next-line react-hooks/exhaustive-deps }, [filterValue, rawSources?.data]); const onInputClick = () => { if (!isOpen) { setIsOpen(true); } else if (!inputValue) { setIsOpen(false); } }; const onTextInputChange = (_event: React.FormEvent, value: string) => { setInputValue(value); setFilterValue(value); if (value !== selectedSource) { dispatch(changeAzureSource('')); } }; const handleSelect = ( _event: React.MouseEvent, sourceName: string, ) => { const sourceId = rawSources?.data?.find( (source) => source?.name === sourceName, )?.id; dispatch(changeAzureSource(sourceId || '')); dispatch(changeAzureResourceGroup('')); setIsOpen(false); }; const handleClear = () => { dispatch(changeAzureSource('')); dispatch(changeAzureTenantId('')); dispatch(changeAzureSubscriptionId('')); dispatch(changeAzureResourceGroup('')); setInputValue(''); setFilterValue(''); }; const handleToggle = () => { // Refetch upon opening (but not upon closing) if (!isOpen) { refetch(); } setIsOpen(!isOpen); }; const selectedSource = azureSource ? rawSources?.data?.find((source) => source?.id === azureSource)?.name : undefined; const toggle = (toggleRef: React.Ref) => ( {selectedSource && (