import DeleteIcon from '@mui/icons-material/Delete'; import { type FormikValues, useFormikContext } from 'formik'; import { inc, is, not, path, remove, split } from 'ramda'; import { Children } from 'react'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { IconButton } from '../../..'; import { getInput } from '..'; import type { InputPropsWithoutGroup } from '../models'; interface StylesProps { actionsCount?: number; columns?: number; } const useStyles = makeStyles()( (theme, { columns, actionsCount }) => ({ actions: { alignItems: 'center', display: 'flex', flexGrow: 1 }, icon: { marginTop: theme.spacing(0.5) }, inputsRow: { columnGap: theme.spacing(2), display: 'grid', gridTemplateColumns: `repeat(${columns}, 1fr) ${theme.spacing( actionsCount ? 4 * actionsCount : 6 )}`, gridTemplateRows: 'min-content' } }) ); interface Props { additionalActions?: React.ReactNode; columns?: Array; defaultRowValue?: object | string; deleteLabel?: string; getRequired: () => boolean; hasSingleValue?: boolean; index: number; isLastElement: boolean; label: string; onDeleteRow?: (rowIndex: number) => void; tableFieldName: string; } const Row = ({ label, index, columns, tableFieldName, defaultRowValue, getRequired, isLastElement, deleteLabel, onDeleteRow, hasSingleValue, additionalActions }: Props): JSX.Element => { const { classes } = useStyles({ actionsCount: additionalActions ? inc(Children.count(additionalActions)) : 1, columns: columns?.length }); const { t } = useTranslation(); const { setFieldValue, values } = useFormikContext(); const tableFieldNamePath = split('.', tableFieldName); const tableValues = path(tableFieldNamePath, values) as Array; const rowValues = tableValues[index]; const deleteRow = (): void => { if (is(Function, onDeleteRow)) { onDeleteRow(index); return; } setFieldValue(tableFieldName, remove(index, 1, tableValues)); }; const changeRow = ({ property, value }: { property: string; value: unknown; }): void => { const currentRowValue = rowValues || defaultRowValue; setFieldValue( `${tableFieldName}.${index}`, hasSingleValue ? value : { ...currentRowValue, [property]: value } ); }; return (
{columns?.map((field): JSX.Element => { const Input = getInput(field.type); const inputFieldName = hasSingleValue ? `${tableFieldName}.${index}` : `${tableFieldName}.${index}.${field.fieldName}`; return ( changeRow({ property: field.fieldName, value }) } fieldName={inputFieldName} getRequired={getRequired} key={`${label}_${index}_${field.label}`} /> ); })} {not(isLastElement) && (
{additionalActions}
)}
); }; export default Row;