import { Box, styled, Tooltip } from '@mui/material'; import { FC, ReactElement, ReactNode, useMemo } from 'react'; import INPUT_TYPES from '../lib/consts/INPUT_TYPES'; import FlexBox from './FlexBox'; import InputWithRef from './InputWithRef'; import OutlinedInputWithLabel from './OutlinedInputWithLabel'; import { ExpandablePanel } from './Panels'; import SelectWithLabel from './SelectWithLabel'; import SwitchWithLabel from './SwitchWithLabel'; import { BodyText } from './Text'; const CHECKED_STATES: Array = ['1', 'on']; const ID_SEPARATOR = '-'; const MAP_TO_INPUT_BUILDER: MapToInputBuilder = { boolean: (args) => { const { id, isChecked = false, label, name = id } = args; return ( } valueType="boolean" /> ); }, select: (args) => { const { id, isRequired, label, name = id, selectOptions = [], value = '', } = args; return ( } required={isRequired} /> ); }, string: (args) => { const { id, isRequired, isSensitive = false, label = '', name = id, value, } = args; return ( } required={isRequired} /> ); }, }; const combineIds = (...pieces: string[]) => pieces.join(ID_SEPARATOR); const FenceInputWrapper = styled(FlexBox)({ margin: '.4em 0', }); const CommonFenceInputGroup: FC = ({ fenceId, fenceParameterTooltipProps, fenceTemplate, previousFenceName, previousFenceParameters, }) => { const fenceParameterElements = useMemo(() => { let result: ReactNode; if (fenceTemplate && fenceId) { const { parameters: fenceParameters } = fenceTemplate[fenceId]; let mapToPreviousFenceParameterValues: FenceParameters = {}; if (previousFenceParameters) { mapToPreviousFenceParameterValues = Object.entries( previousFenceParameters, ).reduce((previous, [parameterId, parameterValue]) => { const newKey = combineIds(fenceId, parameterId); previous[newKey] = parameterValue; return previous; }, {}); } const { optional: optionalInputs, required: requiredInputs } = Object.entries(fenceParameters) .sort(([a], [b]) => (a > b ? 1 : -1)) .reduce<{ optional: ReactElement[]; required: ReactElement[]; }>( ( previous, [ parameterId, { content_type: parameterType, default: parameterDefault, deprecated: rawParameterDeprecated, description: parameterDescription, options: parameterSelectOptions, required: rawParameterRequired, }, ], ) => { const isParameterDeprecated = String(rawParameterDeprecated) === '1'; if (!isParameterDeprecated) { const { optional, required } = previous; const buildInput = MAP_TO_INPUT_BUILDER[parameterType] ?? MAP_TO_INPUT_BUILDER.string; const fenceJoinParameterId = combineIds(fenceId, parameterId); const initialValue = mapToPreviousFenceParameterValues[fenceJoinParameterId] ?? parameterDefault; const isParameterRequired = String(rawParameterRequired) === '1'; const isParameterSensitive = /passw/i.test(parameterId); const parameterInput = buildInput({ id: fenceJoinParameterId, isChecked: CHECKED_STATES.includes(initialValue), isRequired: isParameterRequired, isSensitive: isParameterSensitive, label: parameterId, selectOptions: parameterSelectOptions, value: initialValue, }); const parameterInputWithTooltip = ( {parameterDescription}} {...fenceParameterTooltipProps} > {parameterInput} ); if (isParameterRequired) { required.push(parameterInputWithTooltip); } else { optional.push(parameterInputWithTooltip); } } return previous; }, { optional: [], required: [ MAP_TO_INPUT_BUILDER.string({ id: combineIds(fenceId, 'name'), isRequired: true, label: 'Fence device name', value: previousFenceName, }), ], }, ); result = ( div:first-child': { marginTop: 0 }, '& > div': { marginBottom: 0 }, }} > {requiredInputs} {optionalInputs} ); } return result; }, [ fenceId, fenceParameterTooltipProps, fenceTemplate, previousFenceName, previousFenceParameters, ]); return <>{fenceParameterElements}; }; export { ID_SEPARATOR }; export default CommonFenceInputGroup;