update components to use react-hook-form

This commit is contained in:
dmitrii
2024-12-24 13:55:54 +03:00
parent da808bfcbc
commit 914affe0c0
8 changed files with 830 additions and 615 deletions

View File

@@ -1,13 +1,9 @@
import React from 'react';
import { connect } from 'react-redux';
import { Controller, useForm } from 'react-hook-form';
import { Trans, useTranslation } from 'react-i18next';
import { Field, reduxForm, formValueSelector } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import { renderTextareaField } from '../../../../helpers/form';
import { trimMultilineString, removeEmptyLines } from '../../../../helpers/helpers';
import { CLIENT_ID_LINK, FORM_NAME } from '../../../../helpers/constants';
import { CLIENT_ID_LINK } from '../../../../helpers/constants';
import { removeEmptyLines, trimMultilineString } from '../../../../helpers/helpers';
const fields = [
{
@@ -31,88 +27,108 @@ const fields = [
];
interface FormProps {
handleSubmit: (...args: unknown[]) => string;
submitting: boolean;
invalid: boolean;
initialValues: object;
initialValues?: {
allowed_clients?: string;
disallowed_clients?: string;
blocked_hosts?: string;
};
onSubmit: (data: any) => void;
processingSet: boolean;
t: (...args: unknown[]) => string;
textarea?: boolean;
allowedClients?: string;
}
interface renderFieldProps {
id?: string;
title?: string;
subtitle?: string;
disabled?: boolean;
processingSet?: boolean;
normalizeOnBlur?: (...args: unknown[]) => unknown;
interface FormData {
allowed_clients: string;
disallowed_clients: string;
blocked_hosts: string;
}
let Form = (props: FormProps) => {
const { allowedClients, handleSubmit, submitting, invalid, processingSet } = props;
const Form = ({ initialValues, onSubmit, processingSet }: FormProps) => {
const { t } = useTranslation();
const {
control,
handleSubmit,
watch,
formState: { isSubmitting, isDirty },
} = useForm<FormData>({
mode: 'onChange',
defaultValues: {
allowed_clients: initialValues?.allowed_clients || '',
disallowed_clients: initialValues?.disallowed_clients || '',
blocked_hosts: initialValues?.blocked_hosts || '',
},
});
const allowedClients = watch('allowed_clients');
const renderField = ({
id,
title,
subtitle,
disabled = false,
processingSet,
normalizeOnBlur,
}: renderFieldProps) => (
<div key={id} className="form__group mb-5">
<label className="form__label form__label--with-desc" htmlFor={id}>
<Trans>{title}</Trans>
}: {
id: keyof FormData;
title: string;
subtitle: string;
normalizeOnBlur: (value: string) => string;
}) => {
const disabled = allowedClients && id === 'disallowed_clients';
{disabled && (
<>
<span> </span>(<Trans>disabled</Trans>)
</>
)}
</label>
return (
<div key={id} className="form__group mb-5">
<label className="form__label form__label--with-desc" htmlFor={id}>
{t(title)}
{disabled && (
<>
<span> </span>({t('disabled')})
</>
)}
</label>
<div className="form__desc form__desc--top">
<Trans
components={{
a: (
<a href={CLIENT_ID_LINK} target="_blank" rel="noopener noreferrer">
text
</a>
),
}}>
{subtitle}
</Trans>
<div className="form__desc form__desc--top">
<Trans
components={{
a: (
<a href={CLIENT_ID_LINK} target="_blank" rel="noopener noreferrer">
{t('text')}
</a>
),
}}>
{subtitle}
</Trans>
</div>
<Controller
name={id}
control={control}
render={({ field }) => (
<textarea
{...field}
id={id}
className="form-control form-control--textarea font-monospace"
disabled={disabled || processingSet}
onBlur={(e) => {
const normalized = normalizeOnBlur(e.target.value);
field.onChange(normalized);
}}
/>
)}
/>
</div>
<Field
id={id}
name={id}
component={renderTextareaField}
type="text"
className="form-control form-control--textarea font-monospace"
disabled={disabled || processingSet}
normalizeOnBlur={normalizeOnBlur}
/>
</div>
);
);
};
return (
<form onSubmit={handleSubmit}>
{fields.map((f) => {
return renderField({
...f,
disabled: allowedClients && f.id === 'disallowed_clients' || false
});
})}
<form onSubmit={handleSubmit(onSubmit)}>
{fields.map((f) => renderField(f as { id: keyof FormData; title: string; subtitle: string; normalizeOnBlur: (value: string) => string; }))}
<div className="card-actions">
<div className="btn-list">
<button
type="submit"
className="btn btn-success btn-standard"
disabled={submitting || invalid || processingSet}>
<Trans>save_config</Trans>
disabled={isSubmitting || !isDirty || processingSet}>
{t('save_config')}
</button>
</div>
</div>
@@ -120,18 +136,4 @@ let Form = (props: FormProps) => {
);
};
const selector = formValueSelector(FORM_NAME.ACCESS);
Form = connect((state) => {
const allowedClients = selector(state, 'allowed_clients');
return {
allowedClients,
};
})(Form);
export default flow([
withTranslation(),
reduxForm({
form: FORM_NAME.ACCESS,
}),
])(Form);
export default Form;