rewrite form

This commit is contained in:
Ildar Kamalov 2024-12-12 17:01:30 +03:00
parent 77420d8c96
commit 8e2dea267c
7 changed files with 76 additions and 63 deletions

View file

@ -44,7 +44,7 @@ const Check = ({ onSubmit }: Props) => {
type="text"
className="form-control"
placeholder={t('form_enter_host') ?? ''}
{...register('name', { required: true })}
{...register('name', { required: t('form_error_required') })}
/>
<span className="input-group-append">
<button

View file

@ -1,50 +1,71 @@
import React from 'react';
import { useForm } from 'react-hook-form';
import { Trans, useTranslation } from 'react-i18next';
import { Field, reduxForm } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import { validateAnswer, validateDomain } from '../../../helpers/validators';
import { renderInputField } from '../../../helpers/form';
import { validateAnswer, validateDomain, validateRequiredValue } from '../../../helpers/validators';
import { FORM_NAME } from '../../../helpers/constants';
interface FormProps {
pristine: boolean;
handleSubmit: (...args: unknown[]) => string;
reset: (...args: unknown[]) => string;
toggleRewritesModal: (...args: unknown[]) => unknown;
submitting: boolean;
processingAdd: boolean;
t: (...args: unknown[]) => string;
initialValues?: object;
interface FormValues {
domain: string;
answer: string;
}
const Form = (props: FormProps) => {
const { t, handleSubmit, reset, pristine, submitting, toggleRewritesModal, processingAdd } = props;
type Props = {
processingAdd: boolean;
currentRewrite?: { answer: string, domain: string; };
toggleRewritesModal: () => void;
onSubmit?: (data: FormValues) => Promise<void> | void;
}
const Form = ({ processingAdd, currentRewrite, toggleRewritesModal, onSubmit }: Props) => {
const { t } = useTranslation();
const {
register,
handleSubmit,
reset,
formState: { isDirty, isSubmitting, errors },
} = useForm<FormValues>({
mode: 'onChange',
defaultValues: {
domain: currentRewrite?.domain || '',
answer: currentRewrite?.answer || '',
},
});
const handleFormSubmit = async (data: FormValues) => {
if (onSubmit) {
await onSubmit(data);
}
};
return (
<form onSubmit={handleSubmit}>
<form onSubmit={handleSubmit(handleFormSubmit)}>
<div className="modal-body">
<div className="form__desc form__desc--top">
<Trans>domain_desc</Trans>
</div>
<div className="form__group">
<Field
<input
id="domain"
name="domain"
component={renderInputField}
type="text"
className="form-control"
placeholder={t('form_domain')}
validate={[validateRequiredValue, validateDomain]}
{...register('domain', {
validate: validateDomain,
required: t('form_error_required'),
})}
/>
{errors.domain && (
<div className="form__message form__message--error">
{errors.domain.message}
</div>
)}
</div>
<Trans>examples_title</Trans>:
<ol className="leading-loose">
<li>
<code>example.org</code> <Trans>example_rewrite_domain</Trans>
</li>
<li>
<code>*.example.org</code> &nbsp;
<span>
@ -53,15 +74,21 @@ const Form = (props: FormProps) => {
</li>
</ol>
<div className="form__group">
<Field
<input
id="answer"
name="answer"
component={renderInputField}
type="text"
className="form-control"
placeholder={t('form_answer')}
validate={[validateRequiredValue, validateAnswer]}
placeholder={t('form_answer') ?? ''}
{...register('answer', {
validate: validateAnswer,
required: t('form_error_required'),
})}
/>
{errors.answer && (
<div className="form__message form__message--error">
{errors.answer.message}
</div>
)}
</div>
</div>
@ -78,18 +105,20 @@ const Form = (props: FormProps) => {
<button
type="button"
className="btn btn-secondary btn-standard"
disabled={submitting || processingAdd}
disabled={isSubmitting || processingAdd}
onClick={() => {
reset();
toggleRewritesModal();
}}>
}}
>
<Trans>cancel_btn</Trans>
</button>
<button
type="submit"
className="btn btn-success btn-standard"
disabled={submitting || pristine || processingAdd}>
disabled={isSubmitting || !isDirty || processingAdd}
>
<Trans>save_btn</Trans>
</button>
</div>
@ -98,10 +127,4 @@ const Form = (props: FormProps) => {
);
};
export default flow([
withTranslation(),
reduxForm({
form: FORM_NAME.REWRITES,
enableReinitialize: true,
}),
])(Form);
export default Form;

View file

@ -14,7 +14,7 @@ interface ModalProps {
processingAdd: boolean;
processingDelete: boolean;
modalType: string;
currentRewrite?: object;
currentRewrite?: { answer: string, domain: string; };
}
const Modal = (props: ModalProps) => {
@ -23,7 +23,6 @@ const Modal = (props: ModalProps) => {
handleSubmit,
toggleRewritesModal,
processingAdd,
processingDelete,
modalType,
currentRewrite,
} = props;
@ -50,11 +49,10 @@ const Modal = (props: ModalProps) => {
</div>
<Form
initialValues={{ ...currentRewrite }}
onSubmit={handleSubmit}
toggleRewritesModal={toggleRewritesModal}
processingAdd={processingAdd}
processingDelete={processingDelete}
currentRewrite={currentRewrite}
/>
</div>
</ReactModal>

View file

@ -63,6 +63,7 @@
}
.form__message {
margin-top: 4px;
font-size: 11px;
}

View file

@ -292,7 +292,7 @@ export const validateIsSafePort = (value: any) => {
*/
export const validateDomain = (value: any) => {
if (value && !R_HOST.test(value)) {
return 'form_error_domain_format';
return i18next.t('form_error_domain_format');
}
return undefined;
};
@ -303,7 +303,7 @@ export const validateDomain = (value: any) => {
*/
export const validateAnswer = (value: any) => {
if (value && !R_IPV4.test(value) && !R_IPV6.test(value) && !R_HOST.test(value)) {
return 'form_error_answer_format';
return i18next.t('form_error_answer_format');
}
return undefined;
};

View file

@ -55,17 +55,14 @@ const Auth = (props: Props) => {
<Trans>install_auth_username</Trans>
</label>
<input
{...register('username', { required: {
value: true,
message: i18n.t('form_error_required'),
}})}
{...register('username', { required: t('form_error_required') })}
type="text"
className={cn('form-control', { 'is-invalid': errors.username })}
placeholder={t('install_auth_username_enter')}
autoComplete="username"
/>
{errors.username && (
<div className="invalid-feedback">
<div className="form__message form__message--error">
{errors.username.message}
</div>
)}
@ -77,10 +74,7 @@ const Auth = (props: Props) => {
</label>
<input
{...register('password', {
required: {
value: true,
message: i18n.t('form_error_required'),
},
required: t('form_error_required'),
validate: validatePasswordLength,
})}
type="password"
@ -89,8 +83,8 @@ const Auth = (props: Props) => {
autoComplete="new-password"
/>
{errors.password && (
<div className="invalid-feedback">
{errors.password.message || i18n.t('form_error_password_length')}
<div className="form__message form__message--error">
{errors.password.message}
</div>
)}
</div>
@ -101,10 +95,7 @@ const Auth = (props: Props) => {
</label>
<input
{...register('confirm_password', {
required: {
value: true,
message: i18n.t('form_error_required'),
},
required: t('form_error_required'),
validate: validateConfirmPassword,
})}
type="password"

View file

@ -276,7 +276,7 @@ const Settings: React.FC<Props> = ({
)}
/>
{errors.web?.port && (
<div className="text-danger">
<div className="form__message form__message--error">
{errors.web.port.message}
</div>
)}
@ -376,7 +376,7 @@ const Settings: React.FC<Props> = ({
)}
/>
{errors.dns?.port.message && (
<div className="text-danger">
<div className="form__message form__message--error">
{t(errors.dns.port.message)}
</div>
)}