import { FormGroup } from '@mui/material'; import { cloneDeep, debounce } from 'lodash'; import { FC, useCallback, useMemo } from 'react'; import { UPLOAD_FILE_TYPES_ARRAY } from '../../lib/consts/UPLOAD_FILE_TYPES'; import FlexBox from '../FlexBox'; import List from '../List'; import OutlinedInputWithLabel from '../OutlinedInputWithLabel'; import { ExpandablePanel } from '../Panels'; import SelectWithLabel from '../SelectWithLabel'; import { BodyText } from '../Text'; import UncontrolledInput from '../UncontrolledInput'; const FileInputGroup: FC = (props) => { const { anvils, drHosts, fileUuid: fuuid, formik, showSyncInputGroup, showTypeInput, } = props; const { handleBlur, handleChange } = formik; const debounceChangeEventHandler = useMemo( () => debounce(handleChange, 500), [handleChange], ); const { nameChain, locationsChain, typeChain } = useMemo( () => ({ nameChain: `${fuuid}.name`, locationsChain: `${fuuid}.locations`, typeChain: `${fuuid}.type`, }), [fuuid], ); const handleCheckAllLocations = useCallback( (type: keyof FileFormikLocations, checked: boolean) => { formik.setValues((previous: FileFormikValues) => { const current = cloneDeep(previous); const locations = current[fuuid].locations?.[type]; if (!locations) return previous; Object.keys(locations).forEach((key) => { locations[key].active = checked; }); return current; }); }, [formik, fuuid], ); const getAllLocationsCheckboxProps = useCallback( (type: keyof FileFormikLocations): CheckboxProps => { const locations = formik.values[fuuid].locations?.[type] as { [uuid: string]: { active: boolean }; }; if (!locations) return {}; return { checked: Object.values(locations).every(({ active }) => active), onChange: (event, checked) => { handleCheckAllLocations(type, checked); }, }; }, [formik.values, fuuid, handleCheckAllLocations], ); const getLocationCheckboxProps = useCallback( (type: keyof FileFormikLocations, uuid: string): CheckboxProps => { const gridChain = `${locationsChain}.${type}.${uuid}`; const activeChain = `${gridChain}.active`; return { id: activeChain, name: activeChain, checked: formik.values[fuuid].locations?.[type]?.[uuid]?.active, onBlur: handleBlur, onChange: handleChange, }; }, [formik.values, fuuid, handleBlur, handleChange, locationsChain], ); const enableCheckAllLocations = useCallback( (type: keyof FileFormikLocations) => { const locations = formik.values[fuuid].locations?.[type]; return locations && Object.keys(locations).length > 1; }, [formik.values, fuuid], ); const nameInput = useMemo( () => ( } /> ), [debounceChangeEventHandler, formik.values, fuuid, handleBlur, nameChain], ); const syncNodeInputGroup = useMemo( () => showSyncInputGroup && ( getAllLocationsCheckboxProps('anvils')} getListItemCheckboxProps={(uuid) => getLocationCheckboxProps('anvils', uuid) } renderListItem={(anvilUuid, { description, name }) => ( {name}: {description} )} /> ), [ anvils, enableCheckAllLocations, getAllLocationsCheckboxProps, getLocationCheckboxProps, showSyncInputGroup, ], ); const syncDrHostInputGroup = useMemo( () => showSyncInputGroup && ( getAllLocationsCheckboxProps('drHosts')} getListItemCheckboxProps={(uuid) => getLocationCheckboxProps('drHosts', uuid) } renderListItem={(anvilUuid, { hostName }) => ( {hostName} )} /> ), [ drHosts, enableCheckAllLocations, getAllLocationsCheckboxProps, getLocationCheckboxProps, showSyncInputGroup, ], ); const typeInput = useMemo( () => showTypeInput && ( ({ displayValue, value, }), )} value={formik.values[fuuid].type} /> ), [formik.values, fuuid, handleBlur, handleChange, showTypeInput, typeChain], ); return ( :not(:first-child)': { marginTop: '1em' } }}> {nameInput} {typeInput} {syncNodeInputGroup} {syncDrHostInputGroup} ); }; export default FileInputGroup;