Merge pull request #554 from ylei-tsubame/issues/413-manifest-suggest-ifn

Web UI: patch 485, 425, 413
main
Digimer 1 year ago committed by GitHub
commit 3438186b02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      striker-ui-api/out/index.js
  2. 8
      striker-ui-api/src/lib/request_handlers/manifest/buildManifest.ts
  3. 13
      striker-ui/components/BriefNetworkInterface.tsx
  4. 49
      striker-ui/components/InputWithRef.tsx
  5. 17
      striker-ui/components/ManageManifest/AddManifestInputGroup.tsx
  6. 69
      striker-ui/components/ManageManifest/AnHostConfigInputGroup.tsx
  7. 1
      striker-ui/components/ManageManifest/AnHostInputGroup.tsx
  8. 21
      striker-ui/components/ManageManifest/AnIdInputGroup.tsx
  9. 130
      striker-ui/components/ManageManifest/AnNetworkConfigInputGroup.tsx
  10. 49
      striker-ui/components/ManageManifest/AnNetworkInputGroup.tsx
  11. 7
      striker-ui/components/ManageManifest/ManageManifestPanel.tsx
  12. 2
      striker-ui/components/NetworkInitForm.tsx
  13. 8
      striker-ui/components/UncontrolledInput.tsx
  14. 1
      striker-ui/out/_next/static/Kz-iFpfWQR4uU-BQo8Tpi/_buildManifest.js
  15. 0
      striker-ui/out/_next/static/Kz-iFpfWQR4uU-BQo8Tpi/_middlewareManifest.js
  16. 0
      striker-ui/out/_next/static/Kz-iFpfWQR4uU-BQo8Tpi/_ssgManifest.js
  17. 1
      striker-ui/out/_next/static/L_YVfOsZ3q029Wna3HXeD/_buildManifest.js
  18. 1
      striker-ui/out/_next/static/chunks/336-33ece0c8120f3bd4.js
  19. 1
      striker-ui/out/_next/static/chunks/336-fc22c38ce3bd59c5.js
  20. 1
      striker-ui/out/_next/static/chunks/86-9d0634bddd7b8dc2.js
  21. 1
      striker-ui/out/_next/static/chunks/86-af7e2d6c5444a983.js
  22. 2
      striker-ui/out/_next/static/chunks/pages/config-0c3fc9e77c3ed0ed.js
  23. 1
      striker-ui/out/_next/static/chunks/pages/init-a4caa81141ec112f.js
  24. 1
      striker-ui/out/_next/static/chunks/pages/init-b774a276c8a4ad79.js
  25. 2
      striker-ui/out/_next/static/chunks/pages/login-452bcef79590e137.js
  26. 1
      striker-ui/out/_next/static/chunks/pages/manage-element-0c2dc758c633b42d.js
  27. 1
      striker-ui/out/_next/static/chunks/pages/manage-element-e577aadd99900dcb.js
  28. 2
      striker-ui/out/anvil.html
  29. 2
      striker-ui/out/config.html
  30. 2
      striker-ui/out/file-manager.html
  31. 2
      striker-ui/out/index.html
  32. 2
      striker-ui/out/init.html
  33. 2
      striker-ui/out/login.html
  34. 2
      striker-ui/out/manage-element.html
  35. 2
      striker-ui/out/server.html
  36. 30
      striker-ui/types/ManageManifest.d.ts
  37. 5
      striker-ui/types/UncontrolledInput.d.ts

File diff suppressed because one or more lines are too long

@ -173,16 +173,16 @@ export const buildManifest = async (
`Host number must be an integer; got [${hostNumber}]`,
);
if (ipmiIp) {
assert(
REP_IPV4.test(ipmiIp),
`IPMI IP of ${hostId} must be an IPv4; got [${ipmiIp}]`,
);
assert.ok(networks, `Host networks is required`);
const ipmiIpKey = `${hostId}_ipmi_ip`;
hosts[`${hostId}_ipmi_ip`] = ipmiIp;
}
hosts[ipmiIpKey] = ipmiIp;
assert.ok(networks, `Host networks is required`);
try {
Object.values(networks).forEach(

@ -9,8 +9,7 @@ import { Close as MUICloseIcon } from '@mui/icons-material';
import { BLACK, BORDER_RADIUS, GREY } from '../lib/consts/DEFAULT_THEME';
import Decorator from './Decorator';
import { BodyText } from './Text';
import { MonoText } from './Text';
type BriefNetworkInterfaceOptionalProps = {
isFloating?: boolean;
@ -32,7 +31,7 @@ const BriefNetworkInterface: FC<
}
> = ({
isFloating,
networkInterface: { networkInterfaceName, networkInterfaceState },
networkInterface: { networkInterfaceName },
onClose,
sx: rootSx,
...restRootProps
@ -54,9 +53,9 @@ const BriefNetworkInterface: FC<
sx: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
'& > :not(:first-child)': {
alignSelf: 'center',
marginLeft: '.5em',
},
@ -67,11 +66,7 @@ const BriefNetworkInterface: FC<
...restRootProps,
}}
>
<Decorator
colour={networkInterfaceState === 'up' ? 'ok' : 'off'}
sx={{ height: 'auto' }}
/>
<BodyText text={networkInterfaceName} />
<MonoText>{networkInterfaceName}</MonoText>
{onClose && (
<MUIIconButton onClick={onClose} size="small" sx={{ color: GREY }}>
<MUICloseIcon />

@ -1,4 +1,5 @@
import { InputBaseProps } from '@mui/material';
import { debounce } from 'lodash';
import {
cloneElement,
ForwardedRef,
@ -24,6 +25,7 @@ type InputWithRefOptionalPropsWithDefault<
type InputWithRefOptionalPropsWithoutDefault<
TypeName extends keyof MapToInputType,
> = {
debounceWait?: number;
inputTestBatch?: InputTestBatch;
onBlurAppend?: InputBaseProps['onBlur'];
onFirstRender?: InputFirstRenderFunction;
@ -62,6 +64,7 @@ const INPUT_WITH_REF_DEFAULT_PROPS: Required<
> &
InputWithRefOptionalPropsWithoutDefault<'string'> = {
createInputOnChangeHandlerOptions: {},
debounceWait: 500,
required: false,
valueType: 'string',
};
@ -69,6 +72,7 @@ const INPUT_WITH_REF_DEFAULT_PROPS: Required<
const InputWithRef = forwardRef(
<TypeName extends keyof MapToInputType, InputComponent extends ReactElement>(
{
debounceWait = INPUT_WITH_REF_DEFAULT_PROPS.debounceWait,
input,
inputTestBatch,
onBlurAppend,
@ -125,6 +129,25 @@ const InputWithRef = forwardRef(
return result;
}, [inputTestBatch, isRequired]);
const doTestAndSet = useCallback(
(value: MapToInputType[TypeName]) => {
const valid =
testInput?.call(null, {
inputs: { [INPUT_TEST_ID]: { value } },
isIgnoreOnCallbacks: true,
}) ?? false;
onFirstRender?.call(null, { isValid: valid });
setIsInputValid(valid);
},
[onFirstRender, testInput],
);
const debounceDoTestAndSet = useMemo(
() => debounce(doTestAndSet, debounceWait),
[debounceWait, doTestAndSet],
);
const onBlur = useMemo<InputBaseProps['onBlur']>(
() =>
initOnBlur ??
@ -152,12 +175,16 @@ const InputWithRef = forwardRef(
initOnChange?.call(null, ...args);
postSetAppend?.call(null, ...args);
},
set: setValue,
set: (value) => {
setValue(value);
debounceDoTestAndSet(value as MapToInputType[TypeName]);
},
setType: valueType,
valueKey: vKey,
...restCreateInputOnChangeHandlerOptions,
}),
[
debounceDoTestAndSet,
initOnChange,
postSetAppend,
restCreateInputOnChangeHandlerOptions,
@ -185,19 +212,25 @@ const InputWithRef = forwardRef(
* render function completes.
*/
useEffect(() => {
const isValid =
testInput?.call(null, {
inputs: { [INPUT_TEST_ID]: { value: inputValue } },
isIgnoreOnCallbacks: true,
}) ?? false;
onFirstRender?.call(null, { isValid });
doTestAndSet(inputValue);
return onUnmount;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
/**
* Update the input value to the init value until it's changed by the user.
* This allows us to populate the input based on value from other field(s).
*/
useEffect(() => {
if (isChangedByUser || inputValue === initValue || !initValue) return;
doTestAndSet(initValue);
setInputValue(initValue);
}, [doTestAndSet, initValue, inputValue, isChangedByUser]);
useImperativeHandle(
ref,
() => ({

@ -57,6 +57,10 @@ const AddManifestInputGroup = <
const { networks: previousNetworkList = DEFAULT_NETWORK_LIST } =
previousNetworkConfig;
const [anSequence, setAnSequence] = useState<number>(
previousAnId?.sequence ?? 0,
);
const [networkList, setNetworkList] =
useState<ManifestNetworkList>(previousNetworkList);
@ -67,7 +71,17 @@ const AddManifestInputGroup = <
return (
<FlexBox>
<AnIdInputGroup formUtils={formUtils} previous={previousAnId} />
<AnIdInputGroup
formUtils={formUtils}
onSequenceChange={(event) => {
const {
target: { value },
} = event;
setAnSequence(Number(value));
}}
previous={previousAnId}
/>
<AnNetworkConfigInputGroup
formUtils={formUtils}
networkListEntries={networkListEntries}
@ -75,6 +89,7 @@ const AddManifestInputGroup = <
setNetworkList={setNetworkList}
/>
<AnHostConfigInputGroup
anSequence={anSequence}
formUtils={formUtils}
knownFences={knownFences}
knownUpses={knownUpses}

@ -1,3 +1,4 @@
import { Netmask } from 'netmask';
import { ReactElement, useMemo } from 'react';
import AnHostInputGroup from './AnHostInputGroup';
@ -19,7 +20,39 @@ const DEFAULT_HOST_LIST: ManifestHostList = {
},
};
const guessHostIpOnNetwork = ({
anSeq,
minIp,
offset3 = 10,
step3 = 2,
subnetMask,
subSeq,
}: {
anSeq: number;
minIp: string;
offset3?: number;
step3?: number;
subnetMask: string;
subSeq: number;
}): string => {
try {
const block = new Netmask(`${minIp}/${subnetMask}`);
if (block.bitmask !== 16) {
return `${block.base.replace(/\.0/g, '')}.`;
}
const third = (anSeq - 1) * step3 + offset3;
const fourth = subSeq;
return minIp.replace(/^((\d+\.){2})\d+\.\d+$/, `$1${third}.${fourth}`);
} catch (error) {
return '';
}
};
const AnHostConfigInputGroup = <M extends MapToInputTestID>({
anSequence,
formUtils,
knownFences = {},
knownUpses = {},
@ -47,11 +80,13 @@ const AnHostConfigInputGroup = <M extends MapToInputTestID>({
fences: previousFenceList = {},
hostNumber,
hostType,
ipmiIp,
ipmiIp: previousIpmiIp,
networks: previousNetworkList = {},
upses: previousUpsList = {},
}: ManifestHost = previousHostArgs;
let ipmiIp = previousIpmiIp;
const fences = knownFenceListValues.reduce<ManifestHostFenceList>(
(fenceList, { fenceName }) => {
const { [fenceName]: { fencePort = '' } = {} } =
@ -63,11 +98,37 @@ const AnHostConfigInputGroup = <M extends MapToInputTestID>({
},
{},
);
const networks = networkListEntries.reduce<ManifestHostNetworkList>(
(networkList, [networkId, { networkNumber, networkType }]) => {
const { [networkId]: { networkIp = '' } = {} } =
(
networkList,
[
networkId,
{ networkMinIp, networkNumber, networkSubnetMask, networkType },
],
) => {
let { [networkId]: { networkIp = '' } = {} } =
previousNetworkList;
if (!networkIp) {
networkIp = guessHostIpOnNetwork({
anSeq: anSequence,
minIp: networkMinIp,
subnetMask: networkSubnetMask,
subSeq: hostNumber,
});
}
if (!ipmiIp && networkType === 'bcn' && networkNumber === 1) {
ipmiIp = guessHostIpOnNetwork({
anSeq: anSequence,
minIp: networkMinIp,
offset3: 11,
subnetMask: networkSubnetMask,
subSeq: hostNumber,
});
}
networkList[networkId] = {
networkIp,
networkNumber,
@ -78,6 +139,7 @@ const AnHostConfigInputGroup = <M extends MapToInputTestID>({
},
{},
);
const upses = knownUpsListValues.reduce<ManifestHostUpsList>(
(upsList, { upsName }) => {
const { [upsName]: { isUsed = true } = {} } = previousUpsList;
@ -110,6 +172,7 @@ const AnHostConfigInputGroup = <M extends MapToInputTestID>({
{},
),
[
anSequence,
formUtils,
hostListEntries,
knownFenceListValues,

@ -377,7 +377,6 @@ const AnHostInputGroup = <M extends MapToInputTestID>({
inputIdAHIpmiIp,
)}
onUnmount={buildInputUnmountFunction(inputIdAHIpmiIp)}
required
/>
),
},

@ -1,4 +1,5 @@
import { ReactElement } from 'react';
import { debounce } from 'lodash';
import { ReactElement, useMemo } from 'react';
import Grid from '../Grid';
import InputWithRef from '../InputWithRef';
@ -26,17 +27,25 @@ const AnIdInputGroup = <
| typeof INPUT_ID_AI_SEQUENCE]: string;
},
>({
debounceWait = 500,
formUtils: {
buildFinishInputTestBatchFunction,
buildInputFirstRenderFunction,
setMessage,
},
onSequenceChange,
previous: {
domain: previousDomain,
prefix: previousPrefix,
sequence: previousSequence,
} = {},
}: AnIdInputGroupProps<M>): ReactElement => (
}: AnIdInputGroupProps<M>): ReactElement => {
const debounceSequenceChangeHandler = useMemo(
() => onSequenceChange && debounce(onSequenceChange, debounceWait),
[debounceWait, onSequenceChange],
);
return (
<Grid
columns={{ xs: 1, sm: 2, md: 3 }}
layout={{
@ -99,6 +108,9 @@ const AnIdInputGroup = <
'an-id-input-cell-sequence': {
children: (
<InputWithRef
createInputOnChangeHandlerOptions={{
postSet: debounceSequenceChangeHandler,
}}
input={
<OutlinedInputWithLabel
id={INPUT_ID_AI_SEQUENCE}
@ -119,7 +131,9 @@ const AnIdInputGroup = <
setMessage(INPUT_ID_AI_SEQUENCE, { children: message });
},
)}
onFirstRender={buildInputFirstRenderFunction(INPUT_ID_AI_SEQUENCE)}
onFirstRender={buildInputFirstRenderFunction(
INPUT_ID_AI_SEQUENCE,
)}
required
valueType="number"
/>
@ -129,6 +143,7 @@ const AnIdInputGroup = <
spacing="1em"
/>
);
};
export { INPUT_ID_AI_DOMAIN, INPUT_ID_AI_PREFIX, INPUT_ID_AI_SEQUENCE };

@ -1,3 +1,4 @@
import { Netmask } from 'netmask';
import { ReactElement, useCallback, useMemo } from 'react';
import { v4 as uuidv4 } from 'uuid';
@ -30,9 +31,46 @@ const DEFAULT_DNS_CSV = '8.8.8.8,8.8.4.4';
const NETWORK_TYPE_ENTRIES = Object.entries(NETWORK_TYPES);
const MAP_TO_NETWORK_DEFAULTS: Record<string, { base: string; mask: string }> =
{
bcn: { base: '10.201.0.0', mask: '255.255.0.0' },
mn: { base: '10.199.0.0', mask: '255.255.0.0' },
sn: { base: '10.101.0.0', mask: '255.255.0.0' },
};
const assertIfn = (type: string) => type === 'ifn';
const assertMn = (type: string) => type === 'mn';
const guessNetworkMinIp = ({
entries,
type,
}: {
entries: [string, ManifestNetwork][];
type: string;
}): { base?: string; mask?: string } => {
const last = entries
.filter(([, { networkType }]) => networkType === type)
.sort(([, { networkNumber: a }], [, { networkNumber: b }]) =>
a > b ? 1 : -1,
)
.pop();
if (!last) {
return MAP_TO_NETWORK_DEFAULTS[type] ?? {};
}
const [, { networkMinIp, networkSubnetMask }] = last;
try {
const block = new Netmask(`${networkMinIp}/${networkSubnetMask}`);
const { base, mask } = block.next();
return { base, mask };
} catch (error) {
return {};
}
};
const AnNetworkConfigInputGroup = <
M extends MapToInputTestID & {
[K in
@ -98,24 +136,36 @@ const AnNetworkConfigInputGroup = <
({
networkMinIp = '',
networkSubnetMask = '',
networkType = 'ifn',
networkType = networkListEntries.some(([, { networkType: nt }]) =>
assertMn(nt),
)
? 'ifn'
: 'mn',
// Params that depend on others.
networkGateway = assertIfn(networkType) ? '' : undefined,
networkNumber = getNetworkNumber(networkType) + 1,
}: Partial<ManifestNetwork> = {}): {
network: ManifestNetwork;
networkId: string;
} => ({
} => {
const { base = networkMinIp, mask = networkSubnetMask } =
guessNetworkMinIp({
entries: networkListEntries,
type: networkType,
});
return {
network: {
networkGateway,
networkMinIp,
networkMinIp: base,
networkNumber,
networkSubnetMask,
networkSubnetMask: mask,
networkType,
},
networkId: uuidv4(),
}),
[getNetworkNumber],
};
},
[getNetworkNumber, networkListEntries],
);
const setNetwork = useCallback(
@ -124,6 +174,26 @@ const AnNetworkConfigInputGroup = <
[setNetworkList],
);
const setNetworkProp = useCallback(
<P extends keyof ManifestNetwork>(
nkey: string,
pkey: P,
value: ManifestNetwork[P],
) =>
setNetworkList((previous) => {
const nyu = { ...previous };
const { [nkey]: nw } = nyu;
if (nw) {
nw[pkey] = value;
}
return nyu;
}),
[setNetworkList],
);
const handleNetworkTypeChange = useCallback<AnNetworkTypeChangeEventHandler>(
(
{ networkId: targetId, networkType: previousType },
@ -136,7 +206,13 @@ const AnNetworkConfigInputGroup = <
const newList = networkListEntries.reduce<ManifestNetworkList>(
(previous, [networkId, networkValue]) => {
const { networkNumber: initnn, networkType: initnt } = networkValue;
const {
networkNumber: initnn,
networkType: initnt,
networkMinIp: initbase,
networkSubnetMask: initmask,
...restNetworkValue
} = networkValue;
let networkNumber = initnn;
let networkType = initnt;
@ -160,8 +236,18 @@ const AnNetworkConfigInputGroup = <
networkNumber -= 1;
}
const {
base: networkMinIp = initbase,
mask: networkSubnetMask = initmask,
} = guessNetworkMinIp({
entries: networkListEntries,
type: networkType,
});
previous[networkId] = {
...networkValue,
...restNetworkValue,
networkMinIp,
networkSubnetMask,
networkNumber,
networkType,
};
@ -181,24 +267,29 @@ const AnNetworkConfigInputGroup = <
const handleNetworkRemove = useCallback<AnNetworkCloseEventHandler>(
({ networkId: rmId, networkType: rmType }) => {
let isIdMatch = false;
let postMatch = false;
let networkNumber = 0;
const newList = networkListEntries.reduce<ManifestNetworkList>(
(previous, [networkId, networkValue]) => {
if (networkId === rmId) {
isIdMatch = true;
} else {
postMatch = true;
return previous;
}
const { networkType } = networkValue;
if (networkType === rmType) {
const change = networkType === rmType;
if (change) {
networkNumber += 1;
}
previous[networkId] = isIdMatch
previous[networkId] =
postMatch && change
? { ...networkValue, networkNumber }
: networkValue;
}
return previous;
},
@ -243,6 +334,14 @@ const AnNetworkConfigInputGroup = <
networkType={networkType}
networkTypeOptions={networkTypeOptions}
onClose={handleNetworkRemove}
onNetworkMinIpChange={(
{ networkId: nid },
{ target: { value } },
) => setNetworkProp(nid, 'networkMinIp', value)}
onNetworkSubnetMaskChange={(
{ networkId: nid },
{ target: { value } },
) => setNetworkProp(nid, 'networkSubnetMask', value)}
onNetworkTypeChange={handleNetworkTypeChange}
previous={{
gateway: networkGateway,
@ -265,11 +364,12 @@ const AnNetworkConfigInputGroup = <
return result;
}, [
formUtils,
networkListEntries,
formUtils,
networkTypeOptions,
handleNetworkRemove,
handleNetworkTypeChange,
setNetworkProp,
]);
return (

@ -1,3 +1,4 @@
import { debounce } from 'lodash';
import { ReactElement, ReactNode, useMemo } from 'react';
import NETWORK_TYPES from '../../lib/consts/NETWORK_TYPES';
@ -77,6 +78,7 @@ const buildInputIdANSubnetMask = (networkId: string): string =>
`${INPUT_ID_PREFIX_AN_NETWORK}-${networkId}-subnet-mask`;
const AnNetworkInputGroup = <M extends MapToInputTestID>({
debounceWait = 500,
formUtils: {
buildFinishInputTestBatchFunction,
buildInputFirstRenderFunction,
@ -91,6 +93,9 @@ const AnNetworkInputGroup = <M extends MapToInputTestID>({
networkType,
networkTypeOptions,
onClose,
onNetworkGatewayChange,
onNetworkMinIpChange,
onNetworkSubnetMaskChange,
onNetworkTypeChange,
previous: {
gateway: previousGateway,
@ -146,6 +151,24 @@ const AnNetworkInputGroup = <M extends MapToInputTestID>({
[isShowGateway],
);
const debounceNetworkGatewayChangeHandler = useMemo(
() =>
onNetworkGatewayChange && debounce(onNetworkGatewayChange, debounceWait),
[debounceWait, onNetworkGatewayChange],
);
const debounceNetworkMinIpChangeHandler = useMemo(
() => onNetworkMinIpChange && debounce(onNetworkMinIpChange, debounceWait),
[debounceWait, onNetworkMinIpChange],
);
const debounceNetworkSubnetMaskChangeHandler = useMemo(
() =>
onNetworkSubnetMaskChange &&
debounce(onNetworkSubnetMaskChange, debounceWait),
[debounceWait, onNetworkSubnetMaskChange],
);
const closeButtonElement = useMemo<ReactNode>(
() =>
isShowCloseButton && (
@ -172,6 +195,14 @@ const AnNetworkInputGroup = <M extends MapToInputTestID>({
if (isShowGateway && inputIdGateway) {
result = (
<InputWithRef
createInputOnChangeHandlerOptions={{
postSet: (...args) =>
debounceNetworkGatewayChangeHandler?.call(
null,
{ networkId, networkType },
...args,
),
}}
input={
<OutlinedInputWithLabel
baseInputProps={{
@ -213,6 +244,8 @@ const AnNetworkInputGroup = <M extends MapToInputTestID>({
buildFinishInputTestBatchFunction,
buildInputFirstRenderFunction,
buildInputUnmountFunction,
debounceNetworkGatewayChangeHandler,
networkType,
setMessage,
]);
@ -256,6 +289,14 @@ const AnNetworkInputGroup = <M extends MapToInputTestID>({
[inputCellIdIp]: {
children: (
<InputWithRef
createInputOnChangeHandlerOptions={{
postSet: (...args) =>
debounceNetworkMinIpChangeHandler?.call(
null,
{ networkId, networkType },
...args,
),
}}
input={
<OutlinedInputWithLabel
baseInputProps={{
@ -289,6 +330,14 @@ const AnNetworkInputGroup = <M extends MapToInputTestID>({
[inputCellIdSubnetMask]: {
children: (
<InputWithRef
createInputOnChangeHandlerOptions={{
postSet: (...args) =>
debounceNetworkSubnetMaskChangeHandler?.call(
null,
{ networkId, networkType },
...args,
),
}}
input={
<OutlinedInputWithLabel
baseInputProps={{

@ -47,6 +47,8 @@ import useFormUtils from '../../hooks/useFormUtils';
import useIsFirstRender from '../../hooks/useIsFirstRender';
import useProtectedState from '../../hooks/useProtectedState';
const REQ_BODY_MAX_DEPTH = 6;
const getFormData = (
...[{ target }]: DivFormEventHandlerParameters
): APIBuildManifestRequestBody => {
@ -262,7 +264,7 @@ const ManageManifestPanel: FC = () => {
setConfirmDialogProps({
actionProceedText: 'Add',
content: <FormSummary entries={body} />,
content: <FormSummary entries={body} maxDepth={REQ_BODY_MAX_DEPTH} />,
onProceedAppend: () => {
submitForm({
body,
@ -311,7 +313,7 @@ const ManageManifestPanel: FC = () => {
setConfirmDialogProps({
actionProceedText: 'Edit',
content: <FormSummary entries={body} />,
content: <FormSummary entries={body} maxDepth={REQ_BODY_MAX_DEPTH} />,
onProceedAppend: () => {
submitForm({
body,
@ -605,6 +607,7 @@ const ManageManifestPanel: FC = () => {
{...confirmDialogProps}
ref={confirmDialogRef}
scrollContent
wide
/>
</>
);

@ -233,7 +233,7 @@ const createNetworkInterfaceTableColumns = (
colour={networkInterfaceState === 'up' ? 'ok' : 'off'}
sx={{ height: 'auto' }}
/>
<SmallText text={value} />
<MonoText>{value}</MonoText>
</MUIBox>
),
},

@ -54,7 +54,9 @@ const UncontrolledInput = forwardRef(
const [value, setValue] = useState<MapToInputType[ValueType]>(inputValue);
const baseChangeEventHandler = useCallback<ReactChangeEventHandler>(
const baseChangeEventHandler = useCallback<
React.ChangeEventHandler<HTMLInputElement>
>(
({ target: { [valueKey]: changed } }) => {
const converted = MAP_TO_VALUE_CONVERTER[valueType](
changed,
@ -65,7 +67,9 @@ const UncontrolledInput = forwardRef(
[valueKey, valueType],
);
const changeEventHandler = useCallback<ReactChangeEventHandler>(
const changeEventHandler = useCallback<
React.ChangeEventHandler<HTMLInputElement>
>(
(...args) =>
onChange?.call(
null,

@ -0,0 +1 @@
self.__BUILD_MANIFEST=function(s,c,a,e,t,n,i,f,u,k,h,j,b,d,r,g,l,_,o,p){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[s,a,e,i,u,h,r,"static/chunks/936-f64829e0e2013921.js",c,t,n,f,g,l,"static/chunks/pages/index-8766524a2b0384fc.js"],"/_error":["static/chunks/pages/_error-2280fa386d040b66.js"],"/anvil":[s,a,e,i,u,h,"static/chunks/638-13a283c3a7da370b.js",c,t,n,f,g,"static/chunks/pages/anvil-7fb5cba6fcb66e8c.js"],"/config":[k,s,a,e,b,"static/chunks/519-4b7761e884c88eb9.js",c,t,n,f,j,d,_,"static/chunks/pages/config-0c3fc9e77c3ed0ed.js"],"/file-manager":[k,s,a,e,i,u,"static/chunks/176-7308c25ba374961e.js",c,t,n,j,"static/chunks/pages/file-manager-ef725a93a3e227aa.js"],"/init":[k,s,a,i,u,h,b,o,c,t,n,f,p,"static/chunks/pages/init-a4caa81141ec112f.js"],"/login":[k,s,a,e,c,t,f,j,d,"static/chunks/pages/login-452bcef79590e137.js"],"/manage-element":[k,s,a,e,i,u,h,b,o,"static/chunks/195-d5fd184cc249f755.js",c,t,n,f,j,d,p,_,"static/chunks/pages/manage-element-0c2dc758c633b42d.js"],"/server":[s,e,i,r,c,n,l,"static/chunks/pages/server-97d4cafd19cb2e9d.js"],sortedPages:["/","/_app","/_error","/anvil","/config","/file-manager","/init","/login","/manage-element","/server"]}}("static/chunks/498-e1933a5461cd8607.js","static/chunks/668-b264bf73f0c1b5eb.js","static/chunks/910-2a0e86a170f6eb77.js","static/chunks/894-e57948de523bcf96.js","static/chunks/284-03dc30df5d459e72.js","static/chunks/157-0528651bf3cd10a7.js","static/chunks/839-dabd319a60c8df83.js","static/chunks/27-7790e406eb2ea28d.js","static/chunks/213-a0488f84cc98f172.js","static/chunks/29107295-fbcfe2172188e46f.js","static/chunks/209-4e2794319babfeec.js","static/chunks/48-d4400834d0a31c6e.js","static/chunks/644-4eec2b397fdacb0c.js","static/chunks/336-fc22c38ce3bd59c5.js","static/chunks/570-6bad4610969fc14b.js","static/chunks/707-ee38ab2abcd0aa3f.js","static/chunks/170-357f4683929223df.js","static/chunks/560-a9c9ecda0eca25a9.js","static/chunks/404-b8e9ff2043a0d30c.js","static/chunks/86-9d0634bddd7b8dc2.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();

@ -1 +0,0 @@
self.__BUILD_MANIFEST=function(s,c,e,a,t,n,i,f,u,k,h,j,b,d,r,g,l,_,o){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[s,e,a,i,u,k,d,"static/chunks/936-f64829e0e2013921.js",c,t,n,f,r,g,"static/chunks/pages/index-8766524a2b0384fc.js"],"/_error":["static/chunks/pages/_error-2280fa386d040b66.js"],"/anvil":[s,e,a,i,u,k,"static/chunks/638-13a283c3a7da370b.js",c,t,n,f,r,"static/chunks/pages/anvil-7fb5cba6fcb66e8c.js"],"/config":[s,e,a,j,"static/chunks/519-4b7761e884c88eb9.js",c,t,n,f,h,b,l,"static/chunks/pages/config-e3aa9a84a8baacc1.js"],"/file-manager":["static/chunks/29107295-fbcfe2172188e46f.js",s,e,a,i,u,"static/chunks/176-7308c25ba374961e.js",c,t,n,h,"static/chunks/pages/file-manager-ef725a93a3e227aa.js"],"/init":[s,e,i,u,k,j,_,c,t,n,f,o,"static/chunks/pages/init-b774a276c8a4ad79.js"],"/login":[s,e,a,c,t,f,h,b,"static/chunks/pages/login-270fe7adf9f44c67.js"],"/manage-element":[s,e,a,i,u,k,j,_,"static/chunks/195-d5fd184cc249f755.js",c,t,n,f,h,b,o,l,"static/chunks/pages/manage-element-e577aadd99900dcb.js"],"/server":[s,a,i,d,c,n,g,"static/chunks/pages/server-97d4cafd19cb2e9d.js"],sortedPages:["/","/_app","/_error","/anvil","/config","/file-manager","/init","/login","/manage-element","/server"]}}("static/chunks/498-e1933a5461cd8607.js","static/chunks/668-b264bf73f0c1b5eb.js","static/chunks/910-2a0e86a170f6eb77.js","static/chunks/894-e57948de523bcf96.js","static/chunks/284-03dc30df5d459e72.js","static/chunks/157-0528651bf3cd10a7.js","static/chunks/839-dabd319a60c8df83.js","static/chunks/27-7790e406eb2ea28d.js","static/chunks/213-a0488f84cc98f172.js","static/chunks/209-4e2794319babfeec.js","static/chunks/48-d4400834d0a31c6e.js","static/chunks/644-4eec2b397fdacb0c.js","static/chunks/336-33ece0c8120f3bd4.js","static/chunks/570-6bad4610969fc14b.js","static/chunks/707-ee38ab2abcd0aa3f.js","static/chunks/170-357f4683929223df.js","static/chunks/560-a9c9ecda0eca25a9.js","static/chunks/404-b8e9ff2043a0d30c.js","static/chunks/86-af7e2d6c5444a983.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -74,6 +74,10 @@ type MapToManifestFormInputHandler = Record<string, ManifestFormInputHandler>;
/** ---------- Component types ---------- */
type AnIdInputGroupOptionalProps = {
debounceWait?: number;
onSequenceChange?: import('react').ChangeEventHandler<
HTMLInputElement | HTMLTextAreaElement
>;
previous?: Partial<ManifestAnId>;
};
@ -86,21 +90,32 @@ type AnNetworkEventHandlerPreviousArgs = {
networkId: string;
} & Pick<ManifestNetwork, 'networkType'>;
type AnNetworkCloseEventHandler = (
type AnNetworkChangeEventHandler<Handler> = (
args: AnNetworkEventHandlerPreviousArgs,
...handlerArgs: Parameters<IconButtonMouseEventHandler>
) => ReturnType<IconButtonMouseEventHandler>;
...handlerArgs: Parameters<Handler>
) => ReturnType<Handler>;
type AnNetworkTypeChangeEventHandler = (
args: AnNetworkEventHandlerPreviousArgs,
...handlerArgs: Parameters<SelectChangeEventHandler>
) => ReturnType<SelectChangeEventHandler>;
type AnNetworkCloseEventHandler =
AnNetworkChangeEventHandler<IconButtonMouseEventHandler>;
type AnNetworkTypeChangeEventHandler =
AnNetworkChangeEventHandler<SelectChangeEventHandler>;
type AnNetworkInputGroupOptionalProps = {
debounceWait?: number;
inputGatewayLabel?: string;
inputMinIpLabel?: string;
inputSubnetMaskLabel?: string;
onClose?: AnNetworkCloseEventHandler;
onNetworkGatewayChange?: AnNetworkChangeEventHandler<
import('react').ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>
>;
onNetworkMinIpChange?: AnNetworkChangeEventHandler<
import('react').ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>
>;
onNetworkSubnetMaskChange?: AnNetworkChangeEventHandler<
import('react').ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>
>;
onNetworkTypeChange?: AnNetworkTypeChangeEventHandler;
previous?: {
gateway?: string;
@ -155,6 +170,7 @@ type AnHostConfigInputGroupOptionalProps = {
type AnHostConfigInputGroupProps<M extends MapToInputTestID> =
AnHostConfigInputGroupOptionalProps & {
anSequence: number;
formUtils: FormUtils<M>;
networkListEntries: Array<[string, ManifestNetwork]>;
};

@ -1,8 +1,5 @@
type MuiInputBaseProps = import('@mui/material').InputBaseProps;
type ReactChangeEventHandler =
import('react').ChangeEventHandler<HTMLInputElement>;
type MuiInputBasePropsBlurEventHandler = Exclude<
MuiInputBaseProps['onBlur'],
undefined
@ -19,7 +16,7 @@ type UncontrolledInputComponentUnmountEventHandler = () => void;
type UncontrolledInputOptionalProps = {
onBlur?: ExtendableEventHandler<MuiInputBasePropsBlurEventHandler>;
onChange?: ExtendableEventHandler<ReactChangeEventHandler>;
onChange?: ExtendableEventHandler<React.ChangeEventHandler<HTMLInputElement>>;
onFocus?: ExtendableEventHandler<MuiInputBasePropsFocusEventHandler>;
onMount?: UncontrolledInputComponentMountEventHandler;
onUnmount?: UncontrolledInputComponentUnmountEventHandler;

Loading…
Cancel
Save