|
|
@ -577,17 +577,33 @@ NetworkForm.defaultProps = { |
|
|
|
const NetworkInitForm = forwardRef< |
|
|
|
const NetworkInitForm = forwardRef< |
|
|
|
NetworkInitFormForwardedRefContent, |
|
|
|
NetworkInitFormForwardedRefContent, |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
expectHostDetail?: boolean; |
|
|
|
hostDetail?: APIHostDetail; |
|
|
|
hostDetail?: APIHostDetail; |
|
|
|
toggleSubmitDisabled?: (testResult: boolean) => void; |
|
|
|
toggleSubmitDisabled?: (testResult: boolean) => void; |
|
|
|
} |
|
|
|
} |
|
|
|
>(({ hostDetail, toggleSubmitDisabled }, ref) => { |
|
|
|
>(({ expectHostDetail = false, hostDetail, toggleSubmitDisabled }, ref) => { |
|
|
|
const { |
|
|
|
const { |
|
|
|
dns: xDns, |
|
|
|
dns: previousDns, |
|
|
|
gateway: xGateway, |
|
|
|
gateway: previousGateway, |
|
|
|
hostType, |
|
|
|
hostType, |
|
|
|
hostUUID = 'local', |
|
|
|
hostUUID = 'local', |
|
|
|
|
|
|
|
networks: previousNetworks, |
|
|
|
}: APIHostDetail = hostDetail ?? ({} as APIHostDetail); |
|
|
|
}: APIHostDetail = hostDetail ?? ({} as APIHostDetail); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const uninitRequiredNetworks: NetworkInput[] = useMemo( |
|
|
|
|
|
|
|
() => |
|
|
|
|
|
|
|
hostType === 'node' ? NODE_REQUIRED_NETWORKS : STRIKER_REQUIRED_NETWORKS, |
|
|
|
|
|
|
|
[hostType], |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const requiredNetworks = useMemo<Partial<Record<NetworkType, number>>>( |
|
|
|
|
|
|
|
() => |
|
|
|
|
|
|
|
hostType === 'node' ? { bcn: 1, ifn: 1, sn: 1 } : { bcn: 1, ifn: 1 }, |
|
|
|
|
|
|
|
[hostType], |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [isReadHostDetail, setIsReadHostDetail] = useState<boolean>(false); |
|
|
|
|
|
|
|
|
|
|
|
const [dragMousePosition, setDragMousePosition] = useState<{ |
|
|
|
const [dragMousePosition, setDragMousePosition] = useState<{ |
|
|
|
x: number; |
|
|
|
x: number; |
|
|
|
y: number; |
|
|
|
y: number; |
|
|
@ -595,7 +611,7 @@ const NetworkInitForm = forwardRef< |
|
|
|
const [networkInterfaceInputMap, setNetworkInterfaceInputMap] = |
|
|
|
const [networkInterfaceInputMap, setNetworkInterfaceInputMap] = |
|
|
|
useState<NetworkInterfaceInputMap>({}); |
|
|
|
useState<NetworkInterfaceInputMap>({}); |
|
|
|
const [networkInputs, setNetworkInputs] = useState<NetworkInput[]>( |
|
|
|
const [networkInputs, setNetworkInputs] = useState<NetworkInput[]>( |
|
|
|
hostType === 'node' ? NODE_REQUIRED_NETWORKS : STRIKER_REQUIRED_NETWORKS, |
|
|
|
uninitRequiredNetworks, |
|
|
|
); |
|
|
|
); |
|
|
|
const [networkInterfaceHeld, setNetworkInterfaceHeld] = useState< |
|
|
|
const [networkInterfaceHeld, setNetworkInterfaceHeld] = useState< |
|
|
|
NetworkInterfaceOverviewMetadata | undefined |
|
|
|
NetworkInterfaceOverviewMetadata | undefined |
|
|
@ -606,24 +622,31 @@ const NetworkInitForm = forwardRef< |
|
|
|
const dnsCSVInputRef = useRef<InputForwardedRefContent<'string'>>({}); |
|
|
|
const dnsCSVInputRef = useRef<InputForwardedRefContent<'string'>>({}); |
|
|
|
const messageGroupRef = useRef<MessageGroupForwardedRefContent>({}); |
|
|
|
const messageGroupRef = useRef<MessageGroupForwardedRefContent>({}); |
|
|
|
|
|
|
|
|
|
|
|
const { data: networkInterfaces = [], isLoading } = periodicFetch< |
|
|
|
const { |
|
|
|
NetworkInterfaceOverviewMetadata[] |
|
|
|
data: networkInterfaces = [], |
|
|
|
>(`${API_BASE_URL}/init/network-interface/${hostUUID}`, { |
|
|
|
isLoading: isLoadingNetworkInterfaces, |
|
|
|
refreshInterval: 2000, |
|
|
|
} = periodicFetch<NetworkInterfaceOverviewMetadata[]>( |
|
|
|
onSuccess: (data) => { |
|
|
|
`${API_BASE_URL}/init/network-interface/${hostUUID}`, |
|
|
|
const map = data.reduce<NetworkInterfaceInputMap>((result, metadata) => { |
|
|
|
{ |
|
|
|
const { networkInterfaceUUID } = metadata; |
|
|
|
refreshInterval: 2000, |
|
|
|
|
|
|
|
onSuccess: (data) => { |
|
|
|
result[networkInterfaceUUID] = networkInterfaceInputMap[ |
|
|
|
const map = data.reduce<NetworkInterfaceInputMap>( |
|
|
|
networkInterfaceUUID |
|
|
|
(result, metadata) => { |
|
|
|
] ?? { metadata }; |
|
|
|
const { networkInterfaceUUID } = metadata; |
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
result[networkInterfaceUUID] = networkInterfaceInputMap[ |
|
|
|
}, {}); |
|
|
|
networkInterfaceUUID |
|
|
|
|
|
|
|
] ?? { metadata }; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{}, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
setNetworkInterfaceInputMap(map); |
|
|
|
setNetworkInterfaceInputMap(map); |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const isDisableAddNetworkButton: boolean = useMemo( |
|
|
|
const isDisableAddNetworkButton: boolean = useMemo( |
|
|
|
() => |
|
|
|
() => |
|
|
@ -634,6 +657,10 @@ const NetworkInitForm = forwardRef< |
|
|
|
(hostType === 'node' && networkInterfaces.length <= 6), |
|
|
|
(hostType === 'node' && networkInterfaces.length <= 6), |
|
|
|
[hostType, networkInputs, networkInterfaces, networkInterfaceInputMap], |
|
|
|
[hostType, networkInputs, networkInterfaces, networkInterfaceInputMap], |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
const isLoadingHostDetail: boolean = useMemo( |
|
|
|
|
|
|
|
() => expectHostDetail && !hostDetail, |
|
|
|
|
|
|
|
[expectHostDetail, hostDetail], |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const setMessage = useCallback( |
|
|
|
const setMessage = useCallback( |
|
|
|
(key: string, message?: Message) => |
|
|
|
(key: string, message?: Message) => |
|
|
@ -986,20 +1013,31 @@ const NetworkInitForm = forwardRef< |
|
|
|
const clearNetworkInterfaceHeld = useCallback(() => { |
|
|
|
const clearNetworkInterfaceHeld = useCallback(() => { |
|
|
|
setNetworkInterfaceHeld(undefined); |
|
|
|
setNetworkInterfaceHeld(undefined); |
|
|
|
}, []); |
|
|
|
}, []); |
|
|
|
const createNetwork = useCallback(() => { |
|
|
|
const createNetwork = useCallback( |
|
|
|
networkInputs.unshift({ |
|
|
|
({ |
|
|
|
inputUUID: uuidv4(), |
|
|
|
inputUUID = uuidv4(), |
|
|
|
interfaces: [...INITIAL_IFACES], |
|
|
|
interfaces = [...INITIAL_IFACES], |
|
|
|
ipAddress: '', |
|
|
|
ipAddress = '', |
|
|
|
name: 'Unknown Network', |
|
|
|
name = 'Unknown Network', |
|
|
|
subnetMask: '', |
|
|
|
subnetMask = '', |
|
|
|
type: '', |
|
|
|
type = '', |
|
|
|
typeCount: 0, |
|
|
|
typeCount = 0, |
|
|
|
}); |
|
|
|
}: Partial<NetworkInput> = {}) => { |
|
|
|
|
|
|
|
networkInputs.unshift({ |
|
|
|
toggleSubmitDisabled?.call(null, false); |
|
|
|
inputUUID, |
|
|
|
setNetworkInputs([...networkInputs]); |
|
|
|
interfaces, |
|
|
|
}, [networkInputs, toggleSubmitDisabled]); |
|
|
|
ipAddress, |
|
|
|
|
|
|
|
name, |
|
|
|
|
|
|
|
subnetMask, |
|
|
|
|
|
|
|
type, |
|
|
|
|
|
|
|
typeCount, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
toggleSubmitDisabled?.call(null, false); |
|
|
|
|
|
|
|
setNetworkInputs([...networkInputs]); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
[networkInputs, toggleSubmitDisabled], |
|
|
|
|
|
|
|
); |
|
|
|
const removeNetwork = useCallback( |
|
|
|
const removeNetwork = useCallback( |
|
|
|
(networkIndex: number) => { |
|
|
|
(networkIndex: number) => { |
|
|
|
const [{ inputUUID, interfaces }] = networkInputs.splice(networkIndex, 1); |
|
|
|
const [{ inputUUID, interfaces }] = networkInputs.splice(networkIndex, 1); |
|
|
@ -1138,6 +1176,55 @@ const NetworkInitForm = forwardRef< |
|
|
|
[clearNetworkInterfaceHeld, networkInterfaceHeld], |
|
|
|
[clearNetworkInterfaceHeld, networkInterfaceHeld], |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
Object.keys(networkInterfaceInputMap).length > 0 && |
|
|
|
|
|
|
|
expectHostDetail && |
|
|
|
|
|
|
|
hostDetail && |
|
|
|
|
|
|
|
!isReadHostDetail |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
setNetworkInputs( |
|
|
|
|
|
|
|
Object.values(previousNetworks).reduce<NetworkInput[]>( |
|
|
|
|
|
|
|
(previous, { ip, link1Uuid, link2Uuid = '', subnetMask, type }) => { |
|
|
|
|
|
|
|
const name = NETWORK_TYPES[type]; |
|
|
|
|
|
|
|
const typeCount = |
|
|
|
|
|
|
|
getNetworkTypeCount(type, { inputs: previous }) + 1; |
|
|
|
|
|
|
|
const isRequired = requiredNetworks[type] === typeCount; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
previous.push({ |
|
|
|
|
|
|
|
inputUUID: uuidv4(), |
|
|
|
|
|
|
|
interfaces: [ |
|
|
|
|
|
|
|
networkInterfaceInputMap[link1Uuid]?.metadata, |
|
|
|
|
|
|
|
networkInterfaceInputMap[link2Uuid]?.metadata, |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
ipAddress: ip, |
|
|
|
|
|
|
|
isRequired, |
|
|
|
|
|
|
|
name, |
|
|
|
|
|
|
|
subnetMask, |
|
|
|
|
|
|
|
type, |
|
|
|
|
|
|
|
typeCount, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return previous; |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
[], |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setIsReadHostDetail(true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, [ |
|
|
|
|
|
|
|
createNetwork, |
|
|
|
|
|
|
|
expectHostDetail, |
|
|
|
|
|
|
|
getNetworkTypeCount, |
|
|
|
|
|
|
|
hostDetail, |
|
|
|
|
|
|
|
isReadHostDetail, |
|
|
|
|
|
|
|
networkInputs, |
|
|
|
|
|
|
|
networkInterfaceInputMap, |
|
|
|
|
|
|
|
previousNetworks, |
|
|
|
|
|
|
|
requiredNetworks, |
|
|
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
|
// Enable network mapping on component mount.
|
|
|
|
// Enable network mapping on component mount.
|
|
|
|
setMapNetwork(1); |
|
|
|
setMapNetwork(1); |
|
|
@ -1196,7 +1283,7 @@ const NetworkInitForm = forwardRef< |
|
|
|
const networkInputMinWidth = '13em'; |
|
|
|
const networkInputMinWidth = '13em'; |
|
|
|
const networkInputWidth = '25%'; |
|
|
|
const networkInputWidth = '25%'; |
|
|
|
|
|
|
|
|
|
|
|
return isLoading ? ( |
|
|
|
return isLoadingNetworkInterfaces ? ( |
|
|
|
<Spinner /> |
|
|
|
<Spinner /> |
|
|
|
) : ( |
|
|
|
) : ( |
|
|
|
<MUIBox |
|
|
|
<MUIBox |
|
|
@ -1288,65 +1375,67 @@ const NetworkInitForm = forwardRef< |
|
|
|
}, |
|
|
|
}, |
|
|
|
}} |
|
|
|
}} |
|
|
|
/> |
|
|
|
/> |
|
|
|
<FlexBox |
|
|
|
{!isLoadingHostDetail && ( |
|
|
|
row |
|
|
|
<FlexBox |
|
|
|
sx={{ |
|
|
|
row |
|
|
|
'& > :first-child': { |
|
|
|
|
|
|
|
alignSelf: 'start', |
|
|
|
|
|
|
|
marginTop: '.7em', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'& > :last-child': { |
|
|
|
|
|
|
|
flexGrow: 1, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<MUIBox |
|
|
|
|
|
|
|
sx={{ |
|
|
|
sx={{ |
|
|
|
alignItems: 'strech', |
|
|
|
'& > :first-child': { |
|
|
|
display: 'flex', |
|
|
|
alignSelf: 'start', |
|
|
|
flexDirection: 'row', |
|
|
|
marginTop: '.7em', |
|
|
|
overflowX: 'auto', |
|
|
|
|
|
|
|
paddingLeft: '.3em', |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'& > div': { |
|
|
|
|
|
|
|
marginBottom: '.8em', |
|
|
|
|
|
|
|
marginTop: '.4em', |
|
|
|
|
|
|
|
minWidth: networkInputMinWidth, |
|
|
|
|
|
|
|
width: networkInputWidth, |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
'& > :not(:first-child)': { |
|
|
|
'& > :last-child': { |
|
|
|
marginLeft: '1em', |
|
|
|
flexGrow: 1, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
{networkInputs.map((networkInput, networkIndex) => { |
|
|
|
<MUIBox |
|
|
|
const { inputUUID } = networkInput; |
|
|
|
sx={{ |
|
|
|
|
|
|
|
alignItems: 'strech', |
|
|
|
return ( |
|
|
|
display: 'flex', |
|
|
|
<NetworkForm |
|
|
|
flexDirection: 'row', |
|
|
|
key={`network-${inputUUID}`} |
|
|
|
overflowX: 'auto', |
|
|
|
{...{ |
|
|
|
paddingLeft: '.3em', |
|
|
|
createDropMouseUpHandler, |
|
|
|
|
|
|
|
getNetworkTypeCount, |
|
|
|
'& > div': { |
|
|
|
hostDetail, |
|
|
|
marginBottom: '.8em', |
|
|
|
networkIndex, |
|
|
|
marginTop: '.4em', |
|
|
|
networkInput, |
|
|
|
minWidth: networkInputMinWidth, |
|
|
|
networkInterfaceCount: networkInterfaces.length, |
|
|
|
width: networkInputWidth, |
|
|
|
networkInterfaceInputMap, |
|
|
|
}, |
|
|
|
removeNetwork, |
|
|
|
|
|
|
|
setMessageRe, |
|
|
|
'& > :not(:first-child)': { |
|
|
|
setNetworkInputs, |
|
|
|
marginLeft: '1em', |
|
|
|
setNetworkInterfaceInputMap, |
|
|
|
}, |
|
|
|
testInput, |
|
|
|
}} |
|
|
|
testInputToToggleSubmitDisabled, |
|
|
|
> |
|
|
|
}} |
|
|
|
{networkInputs.map((networkInput, networkIndex) => { |
|
|
|
/> |
|
|
|
const { inputUUID } = networkInput; |
|
|
|
); |
|
|
|
|
|
|
|
})} |
|
|
|
return ( |
|
|
|
</MUIBox> |
|
|
|
<NetworkForm |
|
|
|
</FlexBox> |
|
|
|
key={`network-${inputUUID}`} |
|
|
|
|
|
|
|
{...{ |
|
|
|
|
|
|
|
createDropMouseUpHandler, |
|
|
|
|
|
|
|
getNetworkTypeCount, |
|
|
|
|
|
|
|
hostDetail, |
|
|
|
|
|
|
|
networkIndex, |
|
|
|
|
|
|
|
networkInput, |
|
|
|
|
|
|
|
networkInterfaceCount: networkInterfaces.length, |
|
|
|
|
|
|
|
networkInterfaceInputMap, |
|
|
|
|
|
|
|
removeNetwork, |
|
|
|
|
|
|
|
setMessageRe, |
|
|
|
|
|
|
|
setNetworkInputs, |
|
|
|
|
|
|
|
setNetworkInterfaceInputMap, |
|
|
|
|
|
|
|
testInput, |
|
|
|
|
|
|
|
testInputToToggleSubmitDisabled, |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
})} |
|
|
|
|
|
|
|
</MUIBox> |
|
|
|
|
|
|
|
</FlexBox> |
|
|
|
|
|
|
|
)} |
|
|
|
<FlexBox |
|
|
|
<FlexBox |
|
|
|
sm="row" |
|
|
|
sm="row" |
|
|
|
sx={{ |
|
|
|
sx={{ |
|
|
@ -1360,7 +1449,9 @@ const NetworkInitForm = forwardRef< |
|
|
|
> |
|
|
|
> |
|
|
|
<IconButton |
|
|
|
<IconButton |
|
|
|
disabled={isDisableAddNetworkButton} |
|
|
|
disabled={isDisableAddNetworkButton} |
|
|
|
onClick={createNetwork} |
|
|
|
onClick={() => { |
|
|
|
|
|
|
|
createNetwork(); |
|
|
|
|
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
<MUIAddIcon /> |
|
|
|
<MUIAddIcon /> |
|
|
|
</IconButton> |
|
|
|
</IconButton> |
|
|
@ -1381,7 +1472,7 @@ const NetworkInitForm = forwardRef< |
|
|
|
setGatewayInputMessage(); |
|
|
|
setGatewayInputMessage(); |
|
|
|
}} |
|
|
|
}} |
|
|
|
label="Gateway" |
|
|
|
label="Gateway" |
|
|
|
value={xGateway} |
|
|
|
value={previousGateway} |
|
|
|
/> |
|
|
|
/> |
|
|
|
} |
|
|
|
} |
|
|
|
ref={gatewayInputRef} |
|
|
|
ref={gatewayInputRef} |
|
|
@ -1403,7 +1494,7 @@ const NetworkInitForm = forwardRef< |
|
|
|
setDnsInputMessage(); |
|
|
|
setDnsInputMessage(); |
|
|
|
}} |
|
|
|
}} |
|
|
|
label="Domain name server(s)" |
|
|
|
label="Domain name server(s)" |
|
|
|
value={xDns} |
|
|
|
value={previousDns} |
|
|
|
/> |
|
|
|
/> |
|
|
|
} |
|
|
|
} |
|
|
|
ref={dnsCSVInputRef} |
|
|
|
ref={dnsCSVInputRef} |
|
|
@ -1420,6 +1511,7 @@ const NetworkInitForm = forwardRef< |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
NetworkInitForm.defaultProps = { |
|
|
|
NetworkInitForm.defaultProps = { |
|
|
|
|
|
|
|
expectHostDetail: false, |
|
|
|
hostDetail: undefined, |
|
|
|
hostDetail: undefined, |
|
|
|
toggleSubmitDisabled: undefined, |
|
|
|
toggleSubmitDisabled: undefined, |
|
|
|
}; |
|
|
|
}; |
|
|
|