fix(striker-ui): allow set host externally in PrepareNetworkForm

This commit is contained in:
Tsu-ba-me 2023-02-10 17:43:01 -05:00
parent 1248a5e14e
commit 67a14b20f8
2 changed files with 140 additions and 100 deletions

View File

@ -1,10 +1,11 @@
import { withRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useEffect, useMemo } from 'react'; import { FC, useCallback, useEffect, useMemo } from 'react';
import api from '../lib/api'; import api from '../lib/api';
import ContainedButton from './ContainedButton'; import ContainedButton from './ContainedButton';
import handleAPIError from '../lib/handleAPIError'; import handleAPIError from '../lib/handleAPIError';
import FlexBox from './FlexBox'; import FlexBox from './FlexBox';
import getQueryParam from '../lib/getQueryParam';
import InputWithRef from './InputWithRef'; import InputWithRef from './InputWithRef';
import MessageBox, { Message } from './MessageBox'; import MessageBox, { Message } from './MessageBox';
import NetworkInitForm from './NetworkInitForm'; import NetworkInitForm from './NetworkInitForm';
@ -15,113 +16,146 @@ import { HeaderText } from './Text';
import useProtect from '../hooks/useProtect'; import useProtect from '../hooks/useProtect';
import useProtectedState from '../hooks/useProtectedState'; import useProtectedState from '../hooks/useProtectedState';
const PrepareNetworkForm = withRouter( const PrepareNetworkForm: FC<PrepareNetworkFormProps> = ({
({ expectUUID: isExpectExternalHostUUID = false,
router: { hostUUID,
isReady, }) => {
query: { host_uuid: queryHostUUID }, const { protect } = useProtect();
},
}) => {
const { protect } = useProtect();
const [dataHostDetail, setHostDetail] = useProtectedState< const {
APIHostDetail | undefined isReady,
>(undefined, protect); query: { host_uuid: queryHostUUID },
const [fatalErrorMessage, setFatalErrorMessage] = useProtectedState< } = useRouter();
Message | undefined
>(undefined, protect);
const [isLoading, setIsLoading] = useProtectedState<boolean>(true, protect);
const panelHeaderElement = useMemo( const [dataHostDetail, setDataHostDetail] = useProtectedState<
() => ( APIHostDetail | undefined
<PanelHeader> >(undefined, protect);
<HeaderText> const [fatalErrorMessage, setFatalErrorMessage] = useProtectedState<
Prepare network on {dataHostDetail?.shortHostName} Message | undefined
</HeaderText> >(undefined, protect);
</PanelHeader> const [isLoading, setIsLoading] = useProtectedState<boolean>(true, protect);
), const [previousHostUUID, setPreviousHostUUID] = useProtectedState<
[dataHostDetail], PrepareNetworkFormProps['hostUUID']
); >(undefined, protect);
const contentElement = useMemo(() => {
let result; const isDifferentHostUUID = useMemo(
() => hostUUID !== previousHostUUID,
[hostUUID, previousHostUUID],
);
const isReloadHostDetail = useMemo(
() => Boolean(hostUUID) && isDifferentHostUUID,
[hostUUID, isDifferentHostUUID],
);
const panelHeaderElement = useMemo(
() => (
<PanelHeader>
<HeaderText>
Prepare network on {dataHostDetail?.shortHostName}
</HeaderText>
</PanelHeader>
),
[dataHostDetail],
);
const contentElement = useMemo(() => {
let result;
if (isLoading) {
result = <Spinner mt={0} />;
} else if (fatalErrorMessage) {
result = <MessageBox {...fatalErrorMessage} />;
} else {
result = (
<>
{panelHeaderElement}
<FlexBox>
<InputWithRef
input={
<OutlinedInputWithLabel
formControlProps={{ sx: { maxWidth: '20em' } }}
id="prepare-network-host-name"
label="Host name"
value={dataHostDetail?.hostName}
/>
}
required
/>
<NetworkInitForm hostDetail={dataHostDetail} />
<FlexBox row justifyContent="flex-end">
<ContainedButton>Prepare network</ContainedButton>
</FlexBox>
</FlexBox>
</>
);
}
return result;
}, [dataHostDetail, fatalErrorMessage, isLoading, panelHeaderElement]);
const getHostDetail = useCallback(
(uuid: string) => {
setIsLoading(true);
if (isLoading) { if (isLoading) {
result = <Spinner mt={0} />; api
} else if (fatalErrorMessage) { .get<APIHostDetail>(`/host/${uuid}`)
result = <MessageBox {...fatalErrorMessage} />; .then(({ data }) => {
} else { setPreviousHostUUID(data.hostUUID);
result = ( setDataHostDetail(data);
<> })
{panelHeaderElement} .catch((error) => {
<FlexBox> const { children } = handleAPIError(error);
<InputWithRef
input={
<OutlinedInputWithLabel
formControlProps={{ sx: { maxWidth: '20em' } }}
id="prepare-network-host-name"
label="Host name"
value={dataHostDetail?.hostName}
/>
}
required
/>
<NetworkInitForm hostDetail={dataHostDetail} />
<FlexBox row justifyContent="flex-end">
<ContainedButton>Prepare network</ContainedButton>
</FlexBox>
</FlexBox>
</>
);
}
return result; setFatalErrorMessage({
}, [dataHostDetail, fatalErrorMessage, isLoading, panelHeaderElement]); children: `Failed to get target host information; cannot continue. ${children}`,
type: 'error',
useEffect(() => {
if (isReady && !fatalErrorMessage) {
if (queryHostUUID) {
api
.get<APIHostDetail>(
`/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);
}); });
} else { })
setFatalErrorMessage({ .finally(() => {
children: `No host UUID provided; cannot continue.`, setIsLoading(false);
type: 'error',
}); });
setIsLoading(false);
}
} }
}, [ },
fatalErrorMessage, [
isReady,
queryHostUUID,
setFatalErrorMessage,
setHostDetail,
setIsLoading, setIsLoading,
]); isLoading,
setPreviousHostUUID,
setDataHostDetail,
setFatalErrorMessage,
],
);
return <Panel>{contentElement}</Panel>; 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 <Panel>{contentElement}</Panel>;
};
export default PrepareNetworkForm; export default PrepareNetworkForm;

View File

@ -0,0 +1,6 @@
type PrepareNetworkFormOptionalProps = {
expectUUID?: boolean;
hostUUID?: string;
};
type PrepareNetworkFormProps = PrepareNetworkFormOptionalProps;