<commit_before>import {
    useState,
    useEffect,
    ChangeEvent,
    VFC,
    ChangeEventHandler,
    FormEventHandler,
    MouseEventHandler,
} from 'react';
import { TextField, FormControlLabel, Switch, Button } from '@mui/material';
import produce from 'immer';
import { styles as themeStyles } from 'component/common';
import { trim } from 'component/common/util';
import { IAddon, IAddonProvider } from 'interfaces/addons';
import { AddonParameters } from './AddonParameters/AddonParameters';
import { AddonEvents } from './AddonEvents/AddonEvents';
import cloneDeep from 'lodash.clonedeep';
import { PageContent } from 'component/common/PageContent/PageContent';
import { useNavigate } from 'react-router-dom';
import useAddonsApi from 'hooks/api/actions/useAddonsApi/useAddonsApi';
import useToast from 'hooks/useToast';
import { makeStyles } from 'tss-react/mui';
import { formatUnknownError } from 'utils/formatUnknownError';

const useStyles = makeStyles()(theme => ({
    nameInput: {
        marginRight: '1.5rem',
    },
    formSection: { padding: '10px 28px' },
    buttonsSection: {
        padding: '10px 28px',
        '& > *': {
            marginRight: theme.spacing(1),
        },
    },
}));

interface IAddonFormProps {
    provider?: IAddonProvider;
    addon: IAddon;
    fetch: () => void;
    editMode: boolean;
}

export const AddonForm: VFC<IAddonFormProps> = ({
    editMode,
    provider,
    addon: initialValues,
    fetch,
}) => {
    const { createAddon, updateAddon } = useAddonsApi();
    const { setToastData, setToastApiError } = useToast();
    const navigate = useNavigate();
    const { classes: styles } = useStyles();

    const [formValues, setFormValues] = useState(initialValues);
    const [errors, setErrors] = useState<{
        containsErrors: boolean;
        parameters: Record<string, string>;
        events?: string;
        general?: string;
        description?: string;
    }>({
        containsErrors: false,
        parameters: {},
    });
    const submitText = editMode ? 'Update' : 'Create';

    useEffect(() => {
        if (!provider) {
            fetch();
        }
    }, [fetch, provider]); // empty array => fetch only first time

    useEffect(() => {
        setFormValues({ ...initialValues });
        /* eslint-disable-next-line */
    }, [initialValues.description, initialValues.provider]);

    useEffect(() => {
        if (provider && !formValues.provider) {
            setFormValues({ ...initialValues, provider: provider.name });
        }
    }, [provider, initialValues, formValues.provider]);

    const setFieldValue =
        (field: string): ChangeEventHandler<HTMLInputElement> =>
        event => {
            event.preventDefault();
            setFormValues({ ...formValues, [field]: event.target.value });
        };

    const onEnabled: MouseEventHandler = event => {
        event.preventDefault();
        setFormValues(({ enabled }) => ({ ...formValues, enabled: !enabled }));
    };

    const setParameterValue =
        (param: string): ChangeEventHandler<HTMLInputElement> =>
        event => {
            event.preventDefault();
            setFormValues(
                produce(draft => {
                    draft.parameters[param] = event.target.value;
                })
            );
        };

    const setEventValue =
        (name: string) => (event: ChangeEvent<HTMLInputElement>) => {
            const newConfig = { ...formValues };
            if (event.target.checked) {
                newConfig.events.push(name);
            } else {
                newConfig.events = newConfig.events.filter(e => e !== name);
            }
            setFormValues(newConfig);
            setErrors({ ...errors, events: undefined });
        };

    const onCancel = () => {
        navigate(-1);
    };

    const onSubmit: FormEventHandler<HTMLFormElement> = async event => {
        event.preventDefault();
        if (!provider) return;

        const updatedErrors = cloneDeep(errors);
        updatedErrors.containsErrors = false;

        // Validations<commit_msg>fix: avoid direct mutation of setState return value (#1034)<commit_after>import {
    useState,
    useEffect,
    ChangeEvent,
    VFC,
    ChangeEventHandler,
    FormEventHandler,
    MouseEventHandler,
} from 'react';
import { TextField, FormControlLabel, Switch, Button } from '@mui/material';
import produce from 'immer';
import { styles as themeStyles } from 'component/common';
import { trim } from 'component/common/util';
import { IAddon, IAddonProvider } from 'interfaces/addons';
import { AddonParameters } from './AddonParameters/AddonParameters';
import { AddonEvents } from './AddonEvents/AddonEvents';
import cloneDeep from 'lodash.clonedeep';
import { PageContent } from 'component/common/PageContent/PageContent';
import { useNavigate } from 'react-router-dom';
import useAddonsApi from 'hooks/api/actions/useAddonsApi/useAddonsApi';
import useToast from 'hooks/useToast';
import { makeStyles } from 'tss-react/mui';
import { formatUnknownError } from 'utils/formatUnknownError';

const useStyles = makeStyles()(theme => ({
    nameInput: {
        marginRight: '1.5rem',
    },
    formSection: { padding: '10px 28px' },
    buttonsSection: {
        padding: '10px 28px',
        '& > *': {
            marginRight: theme.spacing(1),
        },
    },
}));

interface IAddonFormProps {
    provider?: IAddonProvider;
    addon: IAddon;
    fetch: () => void;
    editMode: boolean;
}

export const AddonForm: VFC<IAddonFormProps> = ({
    editMode,
    provider,
    addon: initialValues,
    fetch,
}) => {
    const { createAddon, updateAddon } = useAddonsApi();
    const { setToastData, setToastApiError } = useToast();
    const navigate = useNavigate();
    const { classes: styles } = useStyles();

    const [formValues, setFormValues] = useState(initialValues);
    const [errors, setErrors] = useState<{
        containsErrors: boolean;
        parameters: Record<string, string>;
        events?: string;
        general?: string;
        description?: string;
    }>({
        containsErrors: false,
        parameters: {},
    });
    const submitText = editMode ? 'Update' : 'Create';

    useEffect(() => {
        if (!provider) {
            fetch();
        }
    }, [fetch, provider]); // empty array => fetch only first time

    useEffect(() => {
        setFormValues({ ...initialValues });
        /* eslint-disable-next-line */
    }, [initialValues.description, initialValues.provider]);

    useEffect(() => {
        if (provider && !formValues.provider) {
            setFormValues({ ...initialValues, provider: provider.name });
        }
    }, [provider, initialValues, formValues.provider]);

    const setFieldValue =
        (field: string): ChangeEventHandler<HTMLInputElement> =>
        event => {
            event.preventDefault();
            setFormValues({ ...formValues, [field]: event.target.value });
        };

    const onEnabled: MouseEventHandler = event => {
        event.preventDefault();
        setFormValues(({ enabled }) => ({ ...formValues, enabled: !enabled }));
    };

    const setParameterValue =
        (param: string): ChangeEventHandler<HTMLInputElement> =>
        event => {
            event.preventDefault();
            setFormValues(
                produce(draft => {
                    draft.parameters[param] = event.target.value;
                })
            );
        };

    const setEventValue =
        (name: string) => (event: ChangeEvent<HTMLInputElement>) => {
            setFormValues(
                produce(draft => {
                    if (event.target.checked) {
                        draft.events.push(name);
                    } else {
                        draft.events = draft.events.filter(e => e !== name);
                    }
                })
            );
            setErrors(prev => ({
                ...prev,
                events: undefined,
            }));
        };

    const onCancel = () => {
        navigate(-1);
    };

    const onSubmit: FormEventHandler<HTMLFormElement> = async event => {
        event.preventDefault();
        if (!provider) return;

        const updatedErrors = cloneDeep(errors);
        updatedErrors.containsErrors = false;

        // Validations
{'fraction_non_alphanumeric': 0.1320028853089685, 'fraction_numerical': 0.003366193796585718, 'mean_word_length': 2.394124847001224, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1681122', 'n_tokens_mistral': 2283, 'n_tokens_neox': 2268, 'n_words': 505}