parent
47d4a29bd7
commit
9bfd5ec672
7 changed files with 249 additions and 0 deletions
@ -0,0 +1,78 @@ |
||||
import { FC, ReactElement, useMemo, useState } from 'react'; |
||||
|
||||
import CommonUpsInputGroup from './CommonUpsInputGroup'; |
||||
import FlexBox from '../FlexBox'; |
||||
import SelectWithLabel from '../SelectWithLabel'; |
||||
import Spinner from '../Spinner'; |
||||
import { BodyText } from '../Text'; |
||||
|
||||
const AddUpsInputGroup: FC<AddUpsInputGroupProps> = ({ |
||||
loading: isExternalLoading, |
||||
upsTemplate, |
||||
}) => { |
||||
const [inputUpsAgentValue, setInputUpsAgentValue] = useState<string>(''); |
||||
|
||||
const upsAgentOptions = useMemo<SelectItem[]>( |
||||
() => |
||||
upsTemplate |
||||
? Object.entries(upsTemplate).map<SelectItem>( |
||||
([upsTypeId, { brand, description }]) => ({ |
||||
displayValue: ( |
||||
<FlexBox spacing={0}> |
||||
<BodyText inverted>{brand}</BodyText> |
||||
<BodyText inverted>{description}</BodyText> |
||||
</FlexBox> |
||||
), |
||||
value: upsTypeId, |
||||
}), |
||||
) |
||||
: [], |
||||
[upsTemplate], |
||||
); |
||||
|
||||
const pickUpsAgentElement = useMemo( |
||||
() => |
||||
upsTemplate && ( |
||||
<SelectWithLabel |
||||
formControlProps={{ sx: { marginTop: '.3em' } }} |
||||
id="add-ups-select-agent" |
||||
label="UPS type" |
||||
onChange={({ target: { value: rawNewValue } }) => { |
||||
const newValue = String(rawNewValue); |
||||
|
||||
setInputUpsAgentValue(newValue); |
||||
}} |
||||
selectItems={upsAgentOptions} |
||||
selectProps={{ |
||||
onClearIndicatorClick: () => { |
||||
setInputUpsAgentValue(''); |
||||
}, |
||||
renderValue: (rawValue) => { |
||||
const upsTypeId = String(rawValue); |
||||
const { brand } = upsTemplate[upsTypeId]; |
||||
|
||||
return brand; |
||||
}, |
||||
}} |
||||
value={inputUpsAgentValue} |
||||
/> |
||||
), |
||||
[inputUpsAgentValue, upsAgentOptions, upsTemplate], |
||||
); |
||||
const content = useMemo<ReactElement>( |
||||
() => |
||||
isExternalLoading ? ( |
||||
<Spinner /> |
||||
) : ( |
||||
<FlexBox> |
||||
{pickUpsAgentElement} |
||||
{inputUpsAgentValue && <CommonUpsInputGroup />} |
||||
</FlexBox> |
||||
), |
||||
[inputUpsAgentValue, isExternalLoading, pickUpsAgentElement], |
||||
); |
||||
|
||||
return content; |
||||
}; |
||||
|
||||
export default AddUpsInputGroup; |
@ -0,0 +1,58 @@ |
||||
import { FC } from 'react'; |
||||
|
||||
import Grid from '../Grid'; |
||||
import InputWithRef from '../InputWithRef'; |
||||
import OutlinedInputWithLabel from '../OutlinedInputWithLabel'; |
||||
|
||||
const CommonUpsInputGroup: FC<CommonUpsInputGroupProps> = ({ |
||||
previous: { |
||||
hostName: previousHostName, |
||||
ipAddress: previousIpAddress, |
||||
upsName: previousUpsName, |
||||
} = {}, |
||||
}) => ( |
||||
<> |
||||
<Grid |
||||
columns={{ xs: 1, sm: 2 }} |
||||
layout={{ |
||||
'common-ups-input-cell-host-name': { |
||||
children: ( |
||||
<InputWithRef |
||||
input={ |
||||
<OutlinedInputWithLabel |
||||
id="common-ups-input-host-name" |
||||
label="Host name" |
||||
value={previousHostName} |
||||
/> |
||||
} |
||||
required |
||||
/> |
||||
), |
||||
}, |
||||
'common-ups-input-cell-ip-address': { |
||||
children: ( |
||||
<InputWithRef |
||||
input={ |
||||
<OutlinedInputWithLabel |
||||
id="common-ups-input-ip-address" |
||||
label="IP address" |
||||
value={previousIpAddress} |
||||
/> |
||||
} |
||||
required |
||||
/> |
||||
), |
||||
}, |
||||
}} |
||||
spacing="1em" |
||||
/> |
||||
<input |
||||
hidden |
||||
id="common-ups-input-ups-name" |
||||
readOnly |
||||
value={previousUpsName} |
||||
/> |
||||
</> |
||||
); |
||||
|
||||
export default CommonUpsInputGroup; |
@ -0,0 +1,88 @@ |
||||
import { FC, useMemo, useRef, useState } from 'react'; |
||||
|
||||
import AddUpsInputGroup from './AddUpsInputGroup'; |
||||
import api from '../../lib/api'; |
||||
import ConfirmDialog from '../ConfirmDialog'; |
||||
import FormDialog from '../FormDialog'; |
||||
import handleAPIError from '../../lib/handleAPIError'; |
||||
import List from '../List'; |
||||
import { Panel, PanelHeader } from '../Panels'; |
||||
import Spinner from '../Spinner'; |
||||
import { HeaderText } from '../Text'; |
||||
import useConfirmDialogProps from '../../hooks/useConfirmDialogProps'; |
||||
import useIsFirstRender from '../../hooks/useIsFirstRender'; |
||||
import useProtectedState from '../../hooks/useProtectedState'; |
||||
|
||||
const ManageUpsPanel: FC = () => { |
||||
const isFirstRender = useIsFirstRender(); |
||||
|
||||
const confirmDialogRef = useRef<ConfirmDialogForwardedRefContent>({}); |
||||
const formDialogRef = useRef<ConfirmDialogForwardedRefContent>({}); |
||||
|
||||
const [confirmDialogProps] = useConfirmDialogProps(); |
||||
const [formDialogProps, setFormDialogProps] = useConfirmDialogProps(); |
||||
const [isEditUpses, setIsEditUpses] = useState<boolean>(false); |
||||
const [isLoadingUpsTemplate, setIsLoadingUpsTemplate] = |
||||
useProtectedState<boolean>(true); |
||||
const [upsTemplate, setUpsTemplate] = useProtectedState< |
||||
APIUpsTemplate | undefined |
||||
>(undefined); |
||||
|
||||
const listElement = useMemo( |
||||
() => ( |
||||
<List |
||||
allowEdit |
||||
allowItemButton={isEditUpses} |
||||
edit={isEditUpses} |
||||
header |
||||
listEmpty="No Ups(es) registered." |
||||
onAdd={() => { |
||||
setFormDialogProps({ |
||||
actionProceedText: 'Add', |
||||
content: <AddUpsInputGroup upsTemplate={upsTemplate} />, |
||||
titleText: 'Add a UPS', |
||||
}); |
||||
|
||||
formDialogRef.current.setOpen?.call(null, true); |
||||
}} |
||||
onEdit={() => { |
||||
setIsEditUpses((previous) => !previous); |
||||
}} |
||||
/> |
||||
), |
||||
[isEditUpses, setFormDialogProps, upsTemplate], |
||||
); |
||||
const panelContent = useMemo( |
||||
() => (isLoadingUpsTemplate ? <Spinner /> : listElement), |
||||
[isLoadingUpsTemplate, listElement], |
||||
); |
||||
|
||||
if (isFirstRender) { |
||||
api |
||||
.get<APIUpsTemplate>('/ups/template') |
||||
.then(({ data }) => { |
||||
setUpsTemplate(data); |
||||
}) |
||||
.catch((error) => { |
||||
handleAPIError(error); |
||||
}) |
||||
.finally(() => { |
||||
setIsLoadingUpsTemplate(false); |
||||
}); |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<Panel> |
||||
<PanelHeader> |
||||
<HeaderText>Manage Upses</HeaderText> |
||||
</PanelHeader> |
||||
{panelContent} |
||||
</Panel> |
||||
<FormDialog {...formDialogProps} ref={formDialogRef} /> |
||||
<ConfirmDialog {...confirmDialogProps} ref={confirmDialogRef} /> |
||||
</> |
||||
); |
||||
}; |
||||
|
||||
export default ManageUpsPanel; |
@ -0,0 +1,3 @@ |
||||
import ManageUpsPanel from './ManageUpsPanel'; |
||||
|
||||
export default ManageUpsPanel; |
@ -0,0 +1,7 @@ |
||||
type APIUpsTemplate = { |
||||
[upsTypeId: string]: { |
||||
agent: string; |
||||
brand: string; |
||||
description: string; |
||||
}; |
||||
}; |
@ -0,0 +1,6 @@ |
||||
type AddUpsInputGroupOptionalProps = { |
||||
loading?: boolean; |
||||
upsTemplate?: APIUpsTemplate; |
||||
}; |
||||
|
||||
type AddUpsInputGroupProps = AddUpsInputGroupOptionalProps; |
@ -0,0 +1,9 @@ |
||||
type CommonUpsInputGroupOptionalProps = { |
||||
previous?: { |
||||
hostName?: string; |
||||
ipAddress?: string; |
||||
upsName?: string; |
||||
}; |
||||
}; |
||||
|
||||
type CommonUpsInputGroupProps = CommonUpsInputGroupOptionalProps; |
Loading…
Reference in new issue