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