import { ReactElement, useMemo } from 'react'; import NETWORK_TYPES from '../../lib/consts/NETWORK_TYPES'; import FlexBox from '../FlexBox'; import Grid from '../Grid'; import InputWithRef from '../InputWithRef'; import OutlinedInputWithLabel from '../OutlinedInputWithLabel'; import { InnerPanel, InnerPanelBody, InnerPanelHeader } from '../Panels'; import SwitchWithLabel from '../SwitchWithLabel'; import { buildIPAddressTestBatch, buildPeacefulStringTestBatch, } from '../../lib/test_input'; import { BodyText } from '../Text'; const INPUT_ID_PREFIX_AN_HOST = 'an-host-input'; const INPUT_CELL_ID_PREFIX_AH = `${INPUT_ID_PREFIX_AN_HOST}-cell`; const MAP_TO_AH_INPUT_HANDLER: MapToManifestFormInputHandler = { fence: (container, input) => { const { dataset: { hostId = '', fenceId = '', fenceName = '' }, value: fencePort, } = input; const { hostConfig: { hosts: { [hostId]: host }, }, } = container; const { fences = {} } = host; fences[fenceId] = { fenceName, fencePort, }; host.fences = fences; }, host: (container, input) => { const { dataset: { hostId = '', hostNumber: rawHostNumber = '', hostType = '' }, } = input; const hostNumber = Number.parseInt(rawHostNumber, 10); container.hostConfig.hosts[hostId] = { hostNumber, hostType, }; }, network: (container, input) => { const { dataset: { hostId = '', networkId = '', networkNumber: rawNetworkNumber = '', networkType = '', }, value: networkIp, } = input; const { hostConfig: { hosts: { [hostId]: host }, }, } = container; const { networks = {} } = host; const networkNumber = Number.parseInt(rawNetworkNumber, 10); networks[networkId] = { networkIp, networkNumber, networkType, }; host.networks = networks; }, ups: (container, input) => { const { checked: isUsed, dataset: { hostId = '', upsId = '', upsName = '' }, } = input; const { hostConfig: { hosts: { [hostId]: host }, }, } = container; const { upses = {} } = host; upses[upsId] = { isUsed, upsName, }; host.upses = upses; }, }; const GRID_COLUMNS = { xs: 1, sm: 2, md: 3 }; const GRID_SPACING = '1em'; const buildInputIdAHFencePort = (hostId: string, fenceId: string): string => `${INPUT_ID_PREFIX_AN_HOST}-${hostId}-${fenceId}-port`; const buildInputIdAHNetworkIp = (hostId: string, networkId: string): string => `${INPUT_ID_PREFIX_AN_HOST}-${hostId}-${networkId}-ip`; const buildInputIdAHUpsPowerHost = (hostId: string, upsId: string): string => `${INPUT_ID_PREFIX_AN_HOST}-${hostId}-${upsId}-power-host`; const AnHostInputGroup = ({ formUtils: { buildFinishInputTestBatchFunction, buildInputFirstRenderFunction, msgSetters, }, hostId, hostNumber, hostType, previous: { fences: fenceList = {}, networks: networkList = {}, upses: upsList = {}, } = {}, // Props that depend on others. hostLabel = `${hostType} ${hostNumber}`, }: AnHostInputGroupProps): ReactElement => { const fenceListEntries = useMemo( () => Object.entries(fenceList), [fenceList], ); const networkListEntries = useMemo( () => Object.entries(networkList), [networkList], ); const upsListEntries = useMemo(() => Object.entries(upsList), [upsList]); const isShowUpsListGrid = useMemo( () => Boolean(upsListEntries.length), [upsListEntries.length], ); const inputIdAHHost = useMemo( () => `${INPUT_ID_PREFIX_AN_HOST}-${hostId}`, [hostId], ); const fenceListGridLayout = useMemo( () => fenceListEntries.reduce( (previous, [fenceId, { fenceName, fencePort }]) => { const cellId = `${INPUT_CELL_ID_PREFIX_AH}-${hostId}-${fenceId}-port`; const inputId = buildInputIdAHFencePort(hostId, fenceId); const inputLabel = `Port on ${fenceName}`; previous[cellId] = { children: ( } inputTestBatch={buildPeacefulStringTestBatch( inputLabel, () => { msgSetters[inputId](); }, { onFinishBatch: buildFinishInputTestBatchFunction(inputId) }, (message) => { msgSetters[inputId]({ children: message }); }, )} onFirstRender={buildInputFirstRenderFunction(inputId)} required /> ), }; return previous; }, {}, ), [ buildFinishInputTestBatchFunction, buildInputFirstRenderFunction, fenceListEntries, hostId, msgSetters, ], ); const networkListGridLayout = useMemo( () => networkListEntries.reduce( (previous, [networkId, { networkIp, networkNumber, networkType }]) => { const cellId = `${INPUT_CELL_ID_PREFIX_AH}-${hostId}-${networkId}-ip`; const inputId = buildInputIdAHNetworkIp(hostId, networkId); const inputLabel = `${NETWORK_TYPES[networkType]} ${networkNumber}`; previous[cellId] = { children: ( } inputTestBatch={buildIPAddressTestBatch( inputLabel, () => { msgSetters[inputId](); }, { onFinishBatch: buildFinishInputTestBatchFunction(inputId) }, (message) => { msgSetters[inputId]({ children: message }); }, )} onFirstRender={buildInputFirstRenderFunction(inputId)} required /> ), }; return previous; }, {}, ), [ networkListEntries, hostId, buildFinishInputTestBatchFunction, buildInputFirstRenderFunction, msgSetters, ], ); const upsListGridLayout = useMemo( () => upsListEntries.reduce( (previous, [upsId, { isUsed, upsName }]) => { const cellId = `${INPUT_CELL_ID_PREFIX_AH}-${hostId}-${upsId}-power-host`; const inputId = buildInputIdAHUpsPowerHost(hostId, upsId); const inputLabel = `Uses ${upsName}`; previous[cellId] = { children: ( } valueType="boolean" /> ), }; return previous; }, {}, ), [hostId, upsListEntries], ); const upsListGrid = useMemo( () => isShowUpsListGrid && ( ), [isShowUpsListGrid, upsListGridLayout], ); return ( {hostLabel} {upsListGrid} ); }; export { INPUT_ID_PREFIX_AN_HOST, MAP_TO_AH_INPUT_HANDLER, buildInputIdAHFencePort, buildInputIdAHNetworkIp, buildInputIdAHUpsPowerHost, }; export default AnHostInputGroup;