import { useRouter } from 'next/router'; import { FC, useCallback, useEffect, useMemo } from 'react'; import api from '../lib/api'; import ContainedButton from './ContainedButton'; import handleAPIError from '../lib/handleAPIError'; import FlexBox from './FlexBox'; import getQueryParam from '../lib/getQueryParam'; import InputWithRef from './InputWithRef'; import MessageBox, { Message } from './MessageBox'; import NetworkInitForm from './NetworkInitForm'; import OutlinedInputWithLabel from './OutlinedInputWithLabel'; import { Panel, PanelHeader } from './Panels'; import Spinner from './Spinner'; import { HeaderText } from './Text'; import useProtect from '../hooks/useProtect'; import useProtectedState from '../hooks/useProtectedState'; const PrepareNetworkForm: FC = ({ expectUUID: isExpectExternalHostUUID = false, hostUUID, }) => { const { protect } = useProtect(); const { isReady, query: { host_uuid: queryHostUUID }, } = useRouter(); const [dataHostDetail, setDataHostDetail] = useProtectedState< APIHostDetail | undefined >(undefined, protect); const [fatalErrorMessage, setFatalErrorMessage] = useProtectedState< Message | undefined >(undefined, protect); const [isLoading, setIsLoading] = useProtectedState(true, protect); const [previousHostUUID, setPreviousHostUUID] = useProtectedState< PrepareNetworkFormProps['hostUUID'] >(undefined, protect); const isDifferentHostUUID = useMemo( () => hostUUID !== previousHostUUID, [hostUUID, previousHostUUID], ); const isReloadHostDetail = useMemo( () => Boolean(hostUUID) && isDifferentHostUUID, [hostUUID, isDifferentHostUUID], ); const panelHeaderElement = useMemo( () => ( Prepare network on {dataHostDetail?.shortHostName} ), [dataHostDetail], ); const contentElement = useMemo(() => { let result; if (isLoading) { result = ; } else if (fatalErrorMessage) { result = ; } else { result = ( <> {panelHeaderElement} } required /> Prepare network ); } return result; }, [dataHostDetail, fatalErrorMessage, isLoading, panelHeaderElement]); const getHostDetail = useCallback( (uuid: string) => { setIsLoading(true); if (isLoading) { api .get(`/host/${uuid}`) .then(({ data }) => { setPreviousHostUUID(data.hostUUID); setDataHostDetail(data); }) .catch((error) => { const { children } = handleAPIError(error); setFatalErrorMessage({ children: `Failed to get target host information; cannot continue. ${children}`, type: 'error', }); }) .finally(() => { setIsLoading(false); }); } }, [ setIsLoading, isLoading, setPreviousHostUUID, setDataHostDetail, setFatalErrorMessage, ], ); useEffect(() => { if (isExpectExternalHostUUID) { if (isReloadHostDetail) { getHostDetail(hostUUID as string); } } else if (isReady && !fatalErrorMessage) { if (queryHostUUID) { getHostDetail(getQueryParam(queryHostUUID)); } else { setFatalErrorMessage({ children: `No host UUID provided; cannot continue.`, type: 'error', }); setIsLoading(false); } } }, [ fatalErrorMessage, getHostDetail, hostUUID, isExpectExternalHostUUID, isReady, queryHostUUID, setFatalErrorMessage, setDataHostDetail, setIsLoading, isReloadHostDetail, ]); return {contentElement}; }; export default PrepareNetworkForm;