From 67a14b20f8eabf9f273e6db93e3f0018a4524207 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 10 Feb 2023 17:43:01 -0500 Subject: [PATCH] fix(striker-ui): allow set host externally in PrepareNetworkForm --- striker-ui/components/PrepareNetworkForm.tsx | 234 +++++++++++-------- striker-ui/types/PrepareNetworkForm.d.ts | 6 + 2 files changed, 140 insertions(+), 100 deletions(-) create mode 100644 striker-ui/types/PrepareNetworkForm.d.ts diff --git a/striker-ui/components/PrepareNetworkForm.tsx b/striker-ui/components/PrepareNetworkForm.tsx index 74a6d534..7bfdb64a 100644 --- a/striker-ui/components/PrepareNetworkForm.tsx +++ b/striker-ui/components/PrepareNetworkForm.tsx @@ -1,10 +1,11 @@ -import { withRouter } from 'next/router'; -import { useEffect, useMemo } from 'react'; +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'; @@ -15,113 +16,146 @@ import { HeaderText } from './Text'; import useProtect from '../hooks/useProtect'; import useProtectedState from '../hooks/useProtectedState'; -const PrepareNetworkForm = withRouter( - ({ - router: { - isReady, - query: { host_uuid: queryHostUUID }, - }, - }) => { - const { protect } = useProtect(); +const PrepareNetworkForm: FC = ({ + expectUUID: isExpectExternalHostUUID = false, + hostUUID, +}) => { + const { protect } = useProtect(); - const [dataHostDetail, setHostDetail] = useProtectedState< - APIHostDetail | undefined - >(undefined, protect); - const [fatalErrorMessage, setFatalErrorMessage] = useProtectedState< - Message | undefined - >(undefined, protect); - const [isLoading, setIsLoading] = useProtectedState(true, protect); + const { + isReady, + query: { host_uuid: queryHostUUID }, + } = useRouter(); - const panelHeaderElement = useMemo( - () => ( - - - Prepare network on {dataHostDetail?.shortHostName} - - - ), - [dataHostDetail], - ); - const contentElement = useMemo(() => { - let result; + 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) { - result = ; - } else if (fatalErrorMessage) { - result = ; - } else { - result = ( - <> - {panelHeaderElement} - - - } - required - /> - - - Prepare network - - - - ); - } + api + .get(`/host/${uuid}`) + .then(({ data }) => { + setPreviousHostUUID(data.hostUUID); + setDataHostDetail(data); + }) + .catch((error) => { + const { children } = handleAPIError(error); - return result; - }, [dataHostDetail, fatalErrorMessage, isLoading, panelHeaderElement]); - - useEffect(() => { - if (isReady && !fatalErrorMessage) { - if (queryHostUUID) { - api - .get( - `/host/${ - queryHostUUID instanceof Array - ? queryHostUUID[0] - : queryHostUUID - }`, - ) - .then(({ data }) => { - setHostDetail(data); - }) - .catch((error) => { - const { children } = handleAPIError(error); - - setFatalErrorMessage({ - children: `Failed to get target host information; cannot continue. ${children}`, - type: 'error', - }); - }) - .finally(() => { - setIsLoading(false); + setFatalErrorMessage({ + children: `Failed to get target host information; cannot continue. ${children}`, + type: 'error', }); - } else { - setFatalErrorMessage({ - children: `No host UUID provided; cannot continue.`, - type: 'error', + }) + .finally(() => { + setIsLoading(false); }); - - setIsLoading(false); - } } - }, [ - fatalErrorMessage, - isReady, - queryHostUUID, - setFatalErrorMessage, - setHostDetail, + }, + [ setIsLoading, - ]); + isLoading, + setPreviousHostUUID, + setDataHostDetail, + setFatalErrorMessage, + ], + ); - return {contentElement}; - }, -); + 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; diff --git a/striker-ui/types/PrepareNetworkForm.d.ts b/striker-ui/types/PrepareNetworkForm.d.ts new file mode 100644 index 00000000..7638a17e --- /dev/null +++ b/striker-ui/types/PrepareNetworkForm.d.ts @@ -0,0 +1,6 @@ +type PrepareNetworkFormOptionalProps = { + expectUUID?: boolean; + hostUUID?: string; +}; + +type PrepareNetworkFormProps = PrepareNetworkFormOptionalProps;