Local modifications to ClusterLabs/Anvil by Alteeve
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.5 KiB

import { Box } from '@mui/material';
import { ReactElement, useEffect, useMemo, useState } from 'react';
import Autocomplete from '../Autocomplete';
import CommonFenceInputGroup from './CommonFenceInputGroup';
import FlexBox from '../FlexBox';
import Spinner from '../Spinner';
import { BodyText } from '../Text';
import useIsFirstRender from '../../hooks/useIsFirstRender';
const INPUT_ID_FENCE_AGENT = 'add-fence-input-agent';
const AddFenceInputGroup = <M extends Record<string, string>>({
fenceTemplate: externalFenceTemplate,
formUtils,
loading: isExternalLoading,
}: AddFenceInputGroupProps<M>): ReactElement => {
const { setValidity } = formUtils;
const isFirstRender = useIsFirstRender();
const [inputFenceTypeValue, setInputFenceTypeValue] =
useState<FenceAutocompleteOption | null>(null);
const fenceTypeOptions = useMemo<FenceAutocompleteOption[]>(
() =>
externalFenceTemplate
? Object.entries(externalFenceTemplate)
.sort(([a], [b]) => (a > b ? 1 : -1))
.map(([id, { description: rawDescription }]) => {
const description =
typeof rawDescription === 'string'
? rawDescription
: 'No description.';
return {
fenceDescription: description,
fenceId: id,
label: id,
};
})
: [],
[externalFenceTemplate],
);
const fenceTypeElement = useMemo(
() => (
<Autocomplete
id={INPUT_ID_FENCE_AGENT}
isOptionEqualToValue={(option, value) =>
option.fenceId === value.fenceId
}
label="Fence device type"
onChange={(event, newFenceType) => {
setValidity(INPUT_ID_FENCE_AGENT, newFenceType !== null);
setInputFenceTypeValue(newFenceType);
}}
openOnFocus
options={fenceTypeOptions}
renderOption={(props, { fenceDescription, fenceId }, { selected }) => (
<Box
component="li"
sx={{
display: 'flex',
flexDirection: 'column',
'& > *': {
width: '100%',
},
}}
{...props}
>
<BodyText
inverted
sx={{
fontSize: '1.2em',
fontWeight: selected ? 400 : undefined,
}}
>
{fenceId}
</BodyText>
<BodyText selected={false}>{fenceDescription}</BodyText>
</Box>
)}
sx={{ marginTop: '.3em' }}
value={inputFenceTypeValue}
/>
),
[fenceTypeOptions, inputFenceTypeValue, setValidity],
);
const fenceParameterElements = useMemo(
() => (
<CommonFenceInputGroup
fenceId={inputFenceTypeValue?.fenceId}
fenceTemplate={externalFenceTemplate}
formUtils={formUtils}
/>
),
[externalFenceTemplate, inputFenceTypeValue?.fenceId, formUtils],
);
const content = useMemo(
() =>
isExternalLoading ? (
<Spinner />
) : (
<FlexBox>
{fenceTypeElement}
{fenceParameterElements}
</FlexBox>
),
[fenceTypeElement, fenceParameterElements, isExternalLoading],
);
useEffect(() => {
if (isFirstRender) {
setValidity(INPUT_ID_FENCE_AGENT, inputFenceTypeValue !== null);
}
}, [inputFenceTypeValue, isFirstRender, setValidity]);
return <>{content}</>;
};
export { INPUT_ID_FENCE_AGENT };
export default AddFenceInputGroup;