parent
af51edb97f
commit
916ec54dd0
2 changed files with 148 additions and 0 deletions
@ -0,0 +1,125 @@ |
||||
import { Box } from '@mui/material'; |
||||
import { FC, useMemo, useState } from 'react'; |
||||
import useIsFirstRender from '../hooks/useIsFirstRender'; |
||||
import useProtectedState from '../hooks/useProtectedState'; |
||||
import api from '../lib/api'; |
||||
import handleAPIError from '../lib/handleAPIError'; |
||||
import Autocomplete from './Autocomplete'; |
||||
import FlexBox from './FlexBox'; |
||||
import Spinner from './Spinner'; |
||||
import { BodyText } from './Text'; |
||||
|
||||
type FenceDeviceAutocompleteOption = { |
||||
fenceDeviceDescription: string; |
||||
fenceDeviceId: string; |
||||
label: string; |
||||
}; |
||||
|
||||
const AddFenceDeivceForm: FC = () => { |
||||
const isFirstRender = useIsFirstRender(); |
||||
|
||||
const [fenceDeviceTemplate, setFenceDeviceTemplate] = useProtectedState< |
||||
APIFenceTemplate | undefined |
||||
>(undefined); |
||||
const [inputFenceDeviceTypeValue, setInputFenceDeviceTypeValue] = |
||||
useState<FenceDeviceAutocompleteOption | null>(null); |
||||
const [isLoadingTemplate, setIsLoadingTemplate] = |
||||
useProtectedState<boolean>(true); |
||||
|
||||
const fenceDeviceTypeOptions = useMemo<FenceDeviceAutocompleteOption[]>( |
||||
() => |
||||
fenceDeviceTemplate |
||||
? Object.entries(fenceDeviceTemplate).map( |
||||
([id, { description: rawDescription }]) => { |
||||
const description = |
||||
typeof rawDescription === 'string' |
||||
? rawDescription |
||||
: 'No description.'; |
||||
|
||||
return { |
||||
fenceDeviceDescription: description, |
||||
fenceDeviceId: id, |
||||
label: id, |
||||
}; |
||||
}, |
||||
) |
||||
: [], |
||||
[fenceDeviceTemplate], |
||||
); |
||||
|
||||
const autocompleteFenceDeviceType = useMemo( |
||||
() => ( |
||||
<Autocomplete |
||||
id="add-fence-device-pick-type" |
||||
isOptionEqualToValue={(option, value) => |
||||
option.fenceDeviceId === value.fenceDeviceId |
||||
} |
||||
label="Fence device type" |
||||
onChange={(event, newFenceDeviceType) => { |
||||
setInputFenceDeviceTypeValue(newFenceDeviceType); |
||||
}} |
||||
openOnFocus |
||||
options={fenceDeviceTypeOptions} |
||||
renderOption={( |
||||
props, |
||||
{ fenceDeviceDescription, fenceDeviceId }, |
||||
{ selected }, |
||||
) => ( |
||||
<Box |
||||
component="li" |
||||
sx={{ |
||||
display: 'flex', |
||||
flexDirection: 'column', |
||||
|
||||
'& > *': { |
||||
width: '100%', |
||||
}, |
||||
}} |
||||
{...props} |
||||
> |
||||
<BodyText |
||||
inverted |
||||
sx={{ |
||||
fontSize: '1.2em', |
||||
fontWeight: selected ? 400 : undefined, |
||||
}} |
||||
> |
||||
{fenceDeviceId} |
||||
</BodyText> |
||||
<BodyText selected={false}>{fenceDeviceDescription}</BodyText> |
||||
</Box> |
||||
)} |
||||
value={inputFenceDeviceTypeValue} |
||||
/> |
||||
), |
||||
[fenceDeviceTypeOptions, inputFenceDeviceTypeValue], |
||||
); |
||||
|
||||
const formContent = useMemo( |
||||
() => |
||||
isLoadingTemplate ? ( |
||||
<Spinner mt={0} /> |
||||
) : ( |
||||
<>{autocompleteFenceDeviceType}</> |
||||
), |
||||
[autocompleteFenceDeviceType, isLoadingTemplate], |
||||
); |
||||
|
||||
if (isFirstRender) { |
||||
api |
||||
.get<APIFenceTemplate>(`/fence/template`) |
||||
.then(({ data }) => { |
||||
setFenceDeviceTemplate(data); |
||||
}) |
||||
.catch((error) => { |
||||
handleAPIError(error); |
||||
}) |
||||
.finally(() => { |
||||
setIsLoadingTemplate(false); |
||||
}); |
||||
} |
||||
|
||||
return <FlexBox>{formContent}</FlexBox>; |
||||
}; |
||||
|
||||
export default AddFenceDeivceForm; |
@ -0,0 +1,23 @@ |
||||
type APIFenceTemplate = { |
||||
[fenceId: string]: { |
||||
actions: string[]; |
||||
description: string; |
||||
parameters: { |
||||
[parameterId: string]: { |
||||
content_type: 'boolean' | 'integer' | 'second' | 'select' | 'string'; |
||||
default: string; |
||||
deprecated: number; |
||||
description: string; |
||||
obsoletes: number; |
||||
options?: string[]; |
||||
replacement: string; |
||||
required: '0' | '1'; |
||||
switches: string; |
||||
unique: '0' | '1'; |
||||
}; |
||||
}; |
||||
switch: { |
||||
[switchId: string]: { name: string }; |
||||
}; |
||||
}; |
||||
}; |
Loading…
Reference in new issue