0

I have a working solution but it seems a bit slow and buggy, specifically getting in the way of CSS animations when a line is dropped. I'm wondering if the RA team or experienced users have a more elegant, optimal solution. In the future, I hope the ArrayInput/SimpleFormIterator components can provide the line index and maybe even a disableEdit prop to make this an easy process.

I realize FormDataConsumer helps with its ScopedData prop but it caused a lot of breaking bugs when wrapped around all the inputs, and wrapping one around every input seems like a bad solution.

Here's my truncated solution. Any advice is welcome. Thank you!

const WorkOrderLinesForm = ({ type, label = 'Items', ...props }) => {
  //...some setup with useEffects here

    return useMemo(
        () => (
            <ArrayInput
                source={type}
                label={label}
                validate={
                    ['work_order_lines_other', 'work_order_lines_suction', 'work_order_lines_discharge'].includes(type)
                        ? validateWOLines
                        : null
                }
                {...props}
            >
                <SimpleFormIterator>
                    <ConditionalLineInputs
                        type={type}
                        types={types}
                        laborItemDefault={laborItemDefault}
                        updateField={updateField}
                    />
                </SimpleFormIterator>
            </ArrayInput>
        ),
        // eslint-disable-next-line react-hooks/exhaustive-deps
        [type, label, types, laborItemDefault, props.style]
    );
};

const getIsDisabled = ({ lines = [], id }) => {
    const currentIndex = parseInt(id.match(/[\d]/g));

    const renderDisabledInput =
        lines &&
        'undefined' !== typeof lines[currentIndex] &&
        ('undefined' !== typeof lines[currentIndex].id || 'undefined' !== typeof lines[currentIndex].original_ids);

    return renderDisabledInput;
};

const ConditionalLineInputs = ({ label, type, types, laborItemDefault, source, updateField, ...props }) => {
    const formState = useFormState();
    const { values, initialValues } = formState;
    const renderDisabledInput = useMemo(() => getIsDisabled({ lines: values[type], id: props.id }), [
        props.id,
        type,
        values,
    ]);

    const getSource = useCallback((scopedSource: string) => `${source}.${scopedSource}`, [source]);

    return useMemo(
        () => (
            <Fragment>
                <SelectInput
                    disabled={
                        renderDisabledInput
                    }
                    source={getSource('classification')}
                    label="Classification"
                    choices={classificationChoices}
                    initialValue={'work_order_lines_labor' === type ? 'Labor' : 'Part'}
                    optionValue="name"
                    validate={[required()]}
                    {...props}
                />
                <DateTimeInput
                    source={getSource('transacted_at')}
                    label="Transacted At"
                    options={{
                        format: 'MM/dd/yyyy, HH:mm',
                        clearable: true,
                    }}
                    validate={[required()]}
                    disabled={renderDisabledInput}
                    initialValue={today}
                    {...props}
                />
         // Other inputs...
                )}
            </Fragment>
        ),
        [
            getSource,
            initialValues.assigned_to_id,
            label,
            laborItemDefault,
            props,
            renderDisabledInput,
            source,
            type,
            types,
            updateField,
            values,
        ]
    );
};

1 Answers1

0

For any curious, dropping the values prop in array in this code fixed my animation/rendering issue:

    // eslint-disable-next-line react-hooks/exhaustive-deps
    const renderDisabledInput = useMemo(() => getIsDisabled({ lines: values[type], id: props.id }), [props.id, type]);

Still would love to hear how others disabled edits on their lines forms, so please comment if you've done this!