fix(striker-ui): complete edit/remove network(s) in manifest network config

main
Tsu-ba-me 2 years ago
parent 81139bb1ad
commit adf01f9bdd
  1. 131
      striker-ui/components/ManageManifest/AnvilNetworkConfigInputGroup.tsx
  2. 27
      striker-ui/components/ManageManifest/AnvilNetworkInputGroup.tsx
  3. 9
      striker-ui/types/ManageManifest.d.ts
  4. 5
      striker-ui/types/Select.d.ts

@ -1,6 +1,8 @@
import { ReactElement, useCallback, useMemo, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import NETWORK_TYPES from '../../lib/consts/NETWORK_TYPES';
import AnvilNetworkInputGroup from './AnvilNetworkInputGroup';
import buildObjectStateSetterCallback from '../../lib/buildObjectStateSetterCallback';
import Grid from '../Grid';
@ -21,6 +23,8 @@ const INPUT_LABEL_ANVIL_NETWORK_CONFIG_DNS = 'DNS';
const INPUT_LABEL_ANVIL_NETWORK_CONFIG_MTU = 'MTU';
const INPUT_LABEL_ANVIL_NETWORK_CONFIG_NTP = 'NTP';
const NETWORK_TYPE_ENTRIES = Object.entries(NETWORK_TYPES);
const DEFAULT_NETWORKS: AnvilNetworkConfigNetworkList = {
bcn1: {
networkMinIp: '',
@ -42,7 +46,8 @@ const DEFAULT_NETWORKS: AnvilNetworkConfigNetworkList = {
},
};
const isIfn = (type: string) => type === 'ifn';
const assertIfn = (type: string) => type === 'ifn';
const assertMn = (type: string) => type === 'mn';
const AnvilNetworkConfigInputGroup = <
M extends MapToInputTestID & {
@ -69,7 +74,7 @@ const AnvilNetworkConfigInputGroup = <
const [networkList, setNetworkList] =
useState<AnvilNetworkConfigNetworkList>(previousNetworks);
const networkListArray = useMemo(
const networkListEntries = useMemo(
() => Object.entries(networkList),
[networkList],
);
@ -78,13 +83,15 @@ const AnvilNetworkConfigInputGroup = <
(
type: string,
{
input = networkListArray,
end = networkListArray.length,
input = networkListEntries,
end = networkListEntries.length,
}: {
input?: Array<[string, AnvilNetworkConfigNetwork]>;
end?: number;
} = {},
) => {
const limit = end - 1;
let netNum = 0;
input.every(([, { networkType }], networkIndex) => {
@ -92,12 +99,21 @@ const AnvilNetworkConfigInputGroup = <
netNum += 1;
}
return networkIndex < end;
return networkIndex < limit;
});
return netNum;
},
[networkListArray],
[networkListEntries],
);
const networkTypeOptions = useMemo<SelectItem[]>(
() =>
NETWORK_TYPE_ENTRIES.map(([key, value]) => ({
displayValue: value,
value: key,
})),
[],
);
const buildNetwork = useCallback(
@ -106,7 +122,7 @@ const AnvilNetworkConfigInputGroup = <
networkSubnetMask = '',
networkType = 'ifn',
// Params that depend on others.
networkGateway = isIfn(networkType) ? '' : undefined,
networkGateway = assertIfn(networkType) ? '' : undefined,
networkNumber = getNetworkNumber(networkType) + 1,
}: Partial<AnvilNetworkConfigNetwork> = {}): {
network: AnvilNetworkConfigNetwork;
@ -130,30 +146,80 @@ const AnvilNetworkConfigInputGroup = <
[],
);
const removeNetwork = useCallback<AnvilNetworkCloseHandler>(
const handleNetworkTypeChange = useCallback<AnvilNetworkTypeChangeHandler>(
(
{ networkId: targetId, networkType: previousType },
{ target: { value } },
) => {
const newType = String(value);
let isIdMatch = false;
let newTypeNumber = 0;
const newList = networkListEntries.reduce<AnvilNetworkConfigNetworkList>(
(previous, [networkId, networkValue]) => {
const { networkNumber: initnn, networkType: initnt } = networkValue;
let networkNumber = initnn;
let networkType = initnt;
if (networkId === targetId) {
isIdMatch = true;
networkType = newType;
}
const isTypeMatch = networkType === newType;
if (isTypeMatch) {
newTypeNumber += 1;
}
if (isIdMatch) {
if (isTypeMatch) {
networkNumber = newTypeNumber;
} else if (networkType === previousType) {
networkNumber -= 1;
}
previous[networkId] = {
...networkValue,
networkNumber,
networkType,
};
} else {
previous[networkId] = networkValue;
}
return previous;
},
{},
);
setNetworkList(newList);
},
[networkListEntries],
);
const handleNetworkRemove = useCallback<AnvilNetworkCloseHandler>(
({ networkId: rmId, networkType: rmType }) => {
let isIdMatch = false;
let networkNumber = 0;
const newList = networkListArray.reduce<AnvilNetworkConfigNetworkList>(
const newList = networkListEntries.reduce<AnvilNetworkConfigNetworkList>(
(previous, [networkId, networkValue]) => {
const { networkType } = networkValue;
if (networkId === rmId) {
isIdMatch = true;
} else {
const { networkType } = networkValue;
if (networkType === rmType) {
networkNumber += 1;
}
if (isIdMatch) {
previous[networkId] = {
...networkValue,
networkNumber,
};
} else {
previous[networkId] = networkValue;
}
previous[networkId] = isIdMatch
? { ...networkValue, networkNumber }
: networkValue;
}
return previous;
@ -163,13 +229,13 @@ const AnvilNetworkConfigInputGroup = <
setNetworkList(newList);
},
[networkListArray],
[networkListEntries],
);
const networksGridLayout = useMemo<GridLayout>(() => {
let result: GridLayout = {};
result = networkListArray.reduce<GridLayout>(
result = networkListEntries.reduce<GridLayout>(
(
previous,
[
@ -190,10 +256,13 @@ const AnvilNetworkConfigInputGroup = <
const inputIdPrefix = `${INPUT_ID_PREFIX_ANVIL_NETWORK_CONFIG}-${networkId}`;
const inputGatewayId = `${inputIdPrefix}-gateway`;
const inputMinIpId = `${inputIdPrefix}-min-ip`;
const inputNetworkTypeId = `${inputIdPrefix}-network-type`;
const inputSubnetMaskId = `${inputIdPrefix}-subnet-mask`;
const isFirstNetwork = networkNumber === 1;
const isShowGateway = isIfn(networkType);
const isIfn = assertIfn(networkType);
const isMn = assertMn(networkType);
const isOptional = isMn || !isFirstNetwork;
previous[cellId] = {
children: (
@ -202,18 +271,22 @@ const AnvilNetworkConfigInputGroup = <
idPrefix={idPrefix}
inputGatewayId={inputGatewayId}
inputMinIpId={inputMinIpId}
inputNetworkTypeId={inputNetworkTypeId}
inputSubnetMaskId={inputSubnetMaskId}
networkId={networkId}
networkNumber={networkNumber}
networkType={networkType}
onClose={removeNetwork}
networkTypeOptions={networkTypeOptions}
onClose={handleNetworkRemove}
onNetworkTypeChange={handleNetworkTypeChange}
previous={{
gateway: networkGateway,
minIp: networkMinIp,
subnetMask: networkSubnetMask,
}}
showCloseButton={!isFirstNetwork}
showGateway={isShowGateway}
readonlyNetworkName={!isOptional}
showCloseButton={isOptional}
showGateway={isIfn}
/>
),
md: 3,
@ -226,7 +299,13 @@ const AnvilNetworkConfigInputGroup = <
);
return result;
}, [formUtils, networkListArray, removeNetwork]);
}, [
formUtils,
networkListEntries,
networkTypeOptions,
handleNetworkRemove,
handleNetworkTypeChange,
]);
return (
<Grid

@ -7,8 +7,8 @@ import IconButton from '../IconButton';
import InputWithRef from '../InputWithRef';
import OutlinedInputWithLabel from '../OutlinedInputWithLabel';
import { InnerPanel, InnerPanelBody, InnerPanelHeader } from '../Panels';
import SelectWithLabel from '../SelectWithLabel';
import { buildIPAddressTestBatch } from '../../lib/test_input';
import { BodyText } from '../Text';
const AnvilNetworkInputGroup = <M extends MapToInputTestID>({
formUtils: {
@ -22,17 +22,21 @@ const AnvilNetworkInputGroup = <M extends MapToInputTestID>({
inputGatewayLabel = 'Gateway',
inputMinIpId,
inputMinIpLabel = 'IP address',
inputNetworkTypeId,
inputSubnetMaskId,
inputSubnetMaskLabel = 'Subnet mask',
networkId,
networkNumber,
networkType,
networkTypeOptions,
onClose,
onNetworkTypeChange,
previous: {
gateway: previousGateway,
minIp: previousIpAddress,
subnetMask: previousSubnetMask,
} = {},
readonlyNetworkName: isReadonlyNetworkName,
showCloseButton: isShowCloseButton,
showGateway: isShowGateway,
}: AnvilNetworkInputGroupProps<M>): ReactElement => {
@ -132,7 +136,26 @@ const AnvilNetworkInputGroup = <M extends MapToInputTestID>({
return (
<InnerPanel mv={0}>
<InnerPanelHeader>
<BodyText>{networkName}</BodyText>
<InputWithRef
input={
<SelectWithLabel
id={inputNetworkTypeId}
isReadOnly={isReadonlyNetworkName}
onChange={(...args) => {
onNetworkTypeChange?.call(
null,
{ networkId, networkType },
...args,
);
}}
selectItems={networkTypeOptions}
selectProps={{
renderValue: () => networkName,
}}
value={networkType}
/>
}
/>
{closeButtonElement}
</InnerPanelHeader>
<InnerPanelBody>

@ -28,17 +28,24 @@ type AnvilNetworkCloseHandler = (
...handlerArgs: Parameters<IconButtonMouseEventHandler>
) => ReturnType<IconButtonMouseEventHandler>;
type AnvilNetworkTypeChangeHandler = (
args: { networkId: string } & Pick<AnvilNetworkConfigNetwork, 'networkType'>,
...handlerArgs: Parameters<SelectChangeEventHandler>
) => ReturnType<SelectChangeEventHandler>;
type AnvilNetworkInputGroupOptionalProps = {
inputGatewayId?: string;
inputGatewayLabel?: string;
inputMinIpLabel?: string;
inputSubnetMaskLabel?: string;
onClose?: AnvilNetworkCloseHandler;
onNetworkTypeChange?: AnvilNetworkTypeChangeHandler;
previous?: {
gateway?: string;
minIp?: string;
subnetMask?: string;
};
readonlyNetworkName?: boolean;
showCloseButton?: boolean;
showGateway?: boolean;
};
@ -48,10 +55,12 @@ type AnvilNetworkInputGroupProps<M extends MapToInputTestID> =
formUtils: FormUtils<M>;
idPrefix: string;
inputMinIpId: string;
inputNetworkTypeId: string;
inputSubnetMaskId: string;
networkId: string;
networkNumber: number;
networkType: string;
networkTypeOptions: SelectItem[];
};
type AnvilHostInputGroupOptionalProps = {

@ -1,3 +1,8 @@
type SelectChangeEventHandler = Exclude<
import('@mui/material').SelectProps['onChange'],
undefined
>;
type SelectOptionalProps = {
onClearIndicatorClick?: import('@mui/material').IconButtonProps['onClick'];
};

Loading…
Cancel
Save