fix dhcp form
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { UINT32_RANGE } from '../../../helpers/constants';
|
import { UINT32_RANGE } from '../../../helpers/constants';
|
||||||
@@ -12,6 +12,8 @@ import {
|
|||||||
validateRequiredValue,
|
validateRequiredValue,
|
||||||
} from '../../../helpers/validators';
|
} from '../../../helpers/validators';
|
||||||
import { DhcpFormValues } from '.';
|
import { DhcpFormValues } from '.';
|
||||||
|
import { Input } from '../../ui/Controls/Input';
|
||||||
|
import { toNumber } from '../../../helpers/form';
|
||||||
|
|
||||||
type FormDHCPv4Props = {
|
type FormDHCPv4Props = {
|
||||||
processingConfig?: boolean;
|
processingConfig?: boolean;
|
||||||
@@ -30,9 +32,9 @@ const FormDHCPv4 = ({ processingConfig, ipv4placeholders, interfaces, onSubmit }
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors, isSubmitting },
|
formState: { errors, isSubmitting },
|
||||||
|
control,
|
||||||
watch,
|
watch,
|
||||||
} = useFormContext<DhcpFormValues>();
|
} = useFormContext<DhcpFormValues>();
|
||||||
|
|
||||||
@@ -52,121 +54,138 @@ const FormDHCPv4 = ({ processingConfig, ipv4placeholders, interfaces, onSubmit }
|
|||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-6">
|
<div className="col-lg-6">
|
||||||
<div className="form__group form__group--settings">
|
<div className="form__group form__group--settings">
|
||||||
<label>{t('dhcp_form_gateway_input')}</label>
|
<Controller
|
||||||
<input
|
name="v4.gateway_ip"
|
||||||
data-testid="v4_gateway_ip"
|
control={control}
|
||||||
type="text"
|
rules={{
|
||||||
className="form-control"
|
|
||||||
placeholder={t(ipv4placeholders?.gateway_ip || '')}
|
|
||||||
disabled={!isInterfaceIncludesIpv4}
|
|
||||||
{...register('v4.gateway_ip', {
|
|
||||||
validate: {
|
validate: {
|
||||||
ipv4: validateIpv4,
|
ipv4: validateIpv4,
|
||||||
required: (value) => (isEmptyConfig ? undefined : validateRequiredValue(value)),
|
required: (value) => (isEmptyConfig ? undefined : validateRequiredValue(value)),
|
||||||
notInRange: validateNotInRange,
|
notInRange: validateNotInRange,
|
||||||
},
|
},
|
||||||
})}
|
}}
|
||||||
|
render={({ field, fieldState }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="text"
|
||||||
|
data-testid="v4_gateway_ip"
|
||||||
|
label={t('dhcp_form_gateway_input')}
|
||||||
|
placeholder={t(ipv4placeholders.gateway_ip)}
|
||||||
|
error={fieldState.error?.message}
|
||||||
|
disabled={!isInterfaceIncludesIpv4}
|
||||||
/>
|
/>
|
||||||
{errors.v4?.gateway_ip && (
|
|
||||||
<div className="form__message form__message--error">{t(errors.v4.gateway_ip.message)}</div>
|
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form__group form__group--settings">
|
<div className="form__group form__group--settings">
|
||||||
<label>{t('dhcp_form_subnet_input')}</label>
|
<Controller
|
||||||
<input
|
name="v4.subnet_mask"
|
||||||
data-testid="v4_subnet_mask"
|
control={control}
|
||||||
type="text"
|
rules={{
|
||||||
className="form-control"
|
|
||||||
placeholder={t(ipv4placeholders?.subnet_mask || '')}
|
|
||||||
disabled={!isInterfaceIncludesIpv4}
|
|
||||||
{...register('v4.subnet_mask', {
|
|
||||||
validate: {
|
validate: {
|
||||||
required: (value) => (isEmptyConfig ? undefined : validateRequiredValue(value)),
|
required: (value) => (isEmptyConfig ? undefined : validateRequiredValue(value)),
|
||||||
subnet: validateGatewaySubnetMask,
|
subnet: validateGatewaySubnetMask,
|
||||||
},
|
},
|
||||||
})}
|
}}
|
||||||
|
render={({ field, fieldState }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="text"
|
||||||
|
data-testid="v4_subnet_mask"
|
||||||
|
label={t('dhcp_form_subnet_input')}
|
||||||
|
placeholder={t(ipv4placeholders.subnet_mask)}
|
||||||
|
error={fieldState.error?.message}
|
||||||
|
disabled={!isInterfaceIncludesIpv4}
|
||||||
/>
|
/>
|
||||||
{errors.v4?.subnet_mask && (
|
|
||||||
<div className="form__message form__message--error">{t(errors.v4.subnet_mask.message)}</div>
|
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-lg-6">
|
<div className="col-lg-6">
|
||||||
<div className="form__group form__group--settings">
|
<div className="form__group mb-0">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<label>{t('dhcp_form_range_title')}</label>
|
<label>{t('dhcp_form_range_title')}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<input
|
<Controller
|
||||||
data-testid="v4_range_start"
|
name="v4.range_start"
|
||||||
type="text"
|
control={control}
|
||||||
className="form-control"
|
rules={{
|
||||||
placeholder={t(ipv4placeholders?.range_start || '')}
|
|
||||||
disabled={!isInterfaceIncludesIpv4}
|
|
||||||
{...register('v4.range_start', {
|
|
||||||
validate: {
|
validate: {
|
||||||
ipv4: validateIpv4,
|
ipv4: validateIpv4,
|
||||||
gateway: validateIpForGatewaySubnetMask,
|
gateway: validateIpForGatewaySubnetMask,
|
||||||
},
|
},
|
||||||
})}
|
}}
|
||||||
|
render={({ field, fieldState }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="text"
|
||||||
|
data-testid="v4_range_start"
|
||||||
|
placeholder={t(ipv4placeholders.range_start)}
|
||||||
|
error={fieldState.error?.message}
|
||||||
|
disabled={!isInterfaceIncludesIpv4}
|
||||||
/>
|
/>
|
||||||
{errors.v4?.range_start && (
|
|
||||||
<div className="form__message form__message--error">
|
|
||||||
{t(errors.v4.range_start.message)}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<input
|
<Controller
|
||||||
data-testid="v4_range_end"
|
name="v4.range_end"
|
||||||
type="text"
|
control={control}
|
||||||
className="form-control"
|
rules={{
|
||||||
placeholder={t(ipv4placeholders?.range_end || '')}
|
|
||||||
disabled={!isInterfaceIncludesIpv4}
|
|
||||||
{...register('v4.range_end', {
|
|
||||||
validate: {
|
validate: {
|
||||||
ipv4: validateIpv4,
|
ipv4: validateIpv4,
|
||||||
rangeEnd: validateIpv4RangeEnd,
|
rangeEnd: validateIpv4RangeEnd,
|
||||||
gateway: validateIpForGatewaySubnetMask,
|
gateway: validateIpForGatewaySubnetMask,
|
||||||
},
|
},
|
||||||
})}
|
}}
|
||||||
|
render={({ field, fieldState }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="text"
|
||||||
|
data-testid="v4_range_end"
|
||||||
|
placeholder={t(ipv4placeholders.range_end)}
|
||||||
|
error={fieldState.error?.message}
|
||||||
|
disabled={!isInterfaceIncludesIpv4}
|
||||||
/>
|
/>
|
||||||
{errors.v4?.range_end && (
|
|
||||||
<div className="form__message form__message--error">
|
|
||||||
{errors.v4.range_end.message}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form__group form__group--settings">
|
<div className="form__group form__group--settings">
|
||||||
<label>{t('dhcp_form_lease_title')}</label>
|
<Controller
|
||||||
<input
|
name="v4.lease_duration"
|
||||||
data-testid="v4_lease_duration"
|
control={control}
|
||||||
type="number"
|
rules={{
|
||||||
className="form-control"
|
|
||||||
placeholder={t(ipv4placeholders?.lease_duration || '')}
|
|
||||||
disabled={!isInterfaceIncludesIpv4}
|
|
||||||
min={1}
|
|
||||||
max={UINT32_RANGE.MAX}
|
|
||||||
{...register('v4.lease_duration', {
|
|
||||||
valueAsNumber: true,
|
|
||||||
validate: {
|
validate: {
|
||||||
required: (value) => (isEmptyConfig ? undefined : validateRequiredValue(value)),
|
required: (value) => (isEmptyConfig ? undefined : validateRequiredValue(value)),
|
||||||
},
|
},
|
||||||
})}
|
}}
|
||||||
|
render={({ field, fieldState }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="number"
|
||||||
|
data-testid="v4_lease_duration"
|
||||||
|
label={t('dhcp_form_lease_title')}
|
||||||
|
placeholder={t(ipv4placeholders.lease_duration)}
|
||||||
|
error={fieldState.error?.message}
|
||||||
|
disabled={!isInterfaceIncludesIpv4}
|
||||||
|
min={1}
|
||||||
|
max={UINT32_RANGE.MAX}
|
||||||
|
onChange={(e) => {
|
||||||
|
const { value } = e.target;
|
||||||
|
field.onChange(toNumber(value));
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
{errors.v4?.lease_duration && (
|
|
||||||
<div className="form__message form__message--error">
|
|
||||||
{t(errors.v4.lease_duration.message)}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { UINT32_RANGE } from '../../../helpers/constants';
|
import { UINT32_RANGE } from '../../../helpers/constants';
|
||||||
import { validateIpv6, validateRequiredValue } from '../../../helpers/validators';
|
import { validateIpv6, validateRequiredValue } from '../../../helpers/validators';
|
||||||
import { DhcpFormValues } from '.';
|
import { DhcpFormValues } from '.';
|
||||||
|
import { Input } from '../../ui/Controls/Input';
|
||||||
|
import { toNumber } from '../../../helpers/form';
|
||||||
|
|
||||||
type FormDHCPv6Props = {
|
type FormDHCPv6Props = {
|
||||||
processingConfig?: boolean;
|
processingConfig?: boolean;
|
||||||
@@ -20,9 +22,9 @@ type FormDHCPv6Props = {
|
|||||||
const FormDHCPv6 = ({ processingConfig, ipv6placeholders, interfaces, onSubmit }: FormDHCPv6Props) => {
|
const FormDHCPv6 = ({ processingConfig, ipv6placeholders, interfaces, onSubmit }: FormDHCPv6Props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const {
|
const {
|
||||||
register,
|
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors, isSubmitting, isValid },
|
formState: { isSubmitting, isValid },
|
||||||
|
control,
|
||||||
watch,
|
watch,
|
||||||
} = useFormContext<DhcpFormValues>();
|
} = useFormContext<DhcpFormValues>();
|
||||||
|
|
||||||
@@ -40,54 +42,60 @@ const FormDHCPv6 = ({ processingConfig, ipv6placeholders, interfaces, onSubmit }
|
|||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-6">
|
<div className="col-lg-6">
|
||||||
<div className="form__group form__group--settings">
|
<div className="form__group mb-0">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<label>{t('dhcp_form_range_title')}</label>
|
<label>{t('dhcp_form_range_title')}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<input
|
<Controller
|
||||||
data-testid="v6_range_start"
|
name="v6.range_start"
|
||||||
type="text"
|
control={control}
|
||||||
className="form-control"
|
rules={{
|
||||||
placeholder={t(ipv6placeholders?.range_start || '')}
|
validate: isInterfaceIncludesIpv6
|
||||||
disabled={!isInterfaceIncludesIpv6}
|
? {
|
||||||
{...register('v6.range_start', {
|
|
||||||
validate: {
|
|
||||||
ipv6: validateIpv6,
|
ipv6: validateIpv6,
|
||||||
required: (value) =>
|
required: validateRequiredValue,
|
||||||
isInterfaceIncludesIpv6 ? undefined : validateRequiredValue(value),
|
}
|
||||||
},
|
: undefined,
|
||||||
})}
|
}}
|
||||||
|
render={({ field, fieldState }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="text"
|
||||||
|
data-testid="v6_range_start"
|
||||||
|
placeholder={t(ipv6placeholders.range_start)}
|
||||||
|
error={fieldState.error?.message}
|
||||||
|
disabled={!isInterfaceIncludesIpv6}
|
||||||
/>
|
/>
|
||||||
{errors.v6?.range_start && (
|
|
||||||
<div className="form__message form__message--error">
|
|
||||||
{t(errors.v6.range_start.message)}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<input
|
<Controller
|
||||||
data-testid="v6_range_end"
|
name="v6.range_end"
|
||||||
type="text"
|
control={control}
|
||||||
className="form-control"
|
rules={{
|
||||||
placeholder={t(ipv6placeholders?.range_end || '')}
|
validate: isInterfaceIncludesIpv6
|
||||||
disabled={!isInterfaceIncludesIpv6}
|
? {
|
||||||
{...register('v6.range_end', {
|
|
||||||
validate: {
|
|
||||||
ipv6: validateIpv6,
|
ipv6: validateIpv6,
|
||||||
required: (value) =>
|
required: validateRequiredValue,
|
||||||
isInterfaceIncludesIpv6 ? undefined : validateRequiredValue(value),
|
}
|
||||||
},
|
: undefined,
|
||||||
})}
|
}}
|
||||||
|
render={({ field, fieldState }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="text"
|
||||||
|
data-testid="v6_range_end"
|
||||||
|
placeholder={t(ipv6placeholders.range_end)}
|
||||||
|
error={fieldState.error?.message}
|
||||||
|
disabled={!isInterfaceIncludesIpv6}
|
||||||
/>
|
/>
|
||||||
{errors.v6?.range_end && (
|
|
||||||
<div className="form__message form__message--error">
|
|
||||||
{t(errors.v6.range_end.message)}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -96,26 +104,34 @@ const FormDHCPv6 = ({ processingConfig, ipv6placeholders, interfaces, onSubmit }
|
|||||||
|
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-6 form__group form__group--settings">
|
<div className="col-lg-6 form__group form__group--settings">
|
||||||
<label>{t('dhcp_form_lease_title')}</label>
|
<Controller
|
||||||
<input
|
name="v6.lease_duration"
|
||||||
data-testid="v6_lease_duration"
|
control={control}
|
||||||
|
rules={{
|
||||||
|
validate: isInterfaceIncludesIpv6
|
||||||
|
? {
|
||||||
|
required: validateRequiredValue,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
}}
|
||||||
|
render={({ field, fieldState }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
type="number"
|
type="number"
|
||||||
className="form-control"
|
data-testid="v6_lease_duration"
|
||||||
placeholder={t(ipv6placeholders?.lease_duration || '')}
|
label={t('dhcp_form_lease_title')}
|
||||||
|
placeholder={t(ipv6placeholders.lease_duration)}
|
||||||
|
error={fieldState.error?.message}
|
||||||
disabled={!isInterfaceIncludesIpv6}
|
disabled={!isInterfaceIncludesIpv6}
|
||||||
min={1}
|
min={1}
|
||||||
max={UINT32_RANGE.MAX}
|
max={UINT32_RANGE.MAX}
|
||||||
{...register('v6.lease_duration', {
|
onChange={(e) => {
|
||||||
valueAsNumber: true,
|
const { value } = e.target;
|
||||||
validate: {
|
field.onChange(toNumber(value));
|
||||||
required: (value) =>
|
}}
|
||||||
isInterfaceIncludesIpv6 ? undefined : validateRequiredValue(value),
|
|
||||||
},
|
|
||||||
})}
|
|
||||||
/>
|
/>
|
||||||
{errors.v6?.lease_duration && (
|
|
||||||
<div className="form__message form__message--error">{t(errors.v6.lease_duration.message)}</div>
|
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ const Dhcp = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
const handleSubmit = (values: DhcpFormValues) => {
|
||||||
dispatch(
|
dispatch(
|
||||||
setDhcpConfig({
|
setDhcpConfig({
|
||||||
interface_name,
|
interface_name,
|
||||||
@@ -293,7 +293,6 @@ const Dhcp = () => {
|
|||||||
|
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
<Interfaces />
|
<Interfaces />
|
||||||
|
|
||||||
<Card title={t('dhcp_ipv4_settings')} bodyType="card-body box-body--settings">
|
<Card title={t('dhcp_ipv4_settings')} bodyType="card-body box-body--settings">
|
||||||
<div>
|
<div>
|
||||||
<FormDHCPv4
|
<FormDHCPv4
|
||||||
@@ -304,7 +303,6 @@ const Dhcp = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card title={t('dhcp_ipv6_settings')} bodyType="card-body box-body--settings">
|
<Card title={t('dhcp_ipv6_settings')} bodyType="card-body box-body--settings">
|
||||||
<div>
|
<div>
|
||||||
<FormDHCPv6
|
<FormDHCPv6
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ export const Form = ({
|
|||||||
subject,
|
subject,
|
||||||
warning_validation,
|
warning_validation,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
debouncedConfigValidation,
|
|
||||||
setTlsConfig,
|
setTlsConfig,
|
||||||
validateTlsConfig,
|
validateTlsConfig,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
@@ -187,7 +186,6 @@ export const Form = ({
|
|||||||
if (JSON.stringify(previousValues) !== JSON.stringify(watchedValues)) {
|
if (JSON.stringify(previousValues) !== JSON.stringify(watchedValues)) {
|
||||||
// TODO(ik) onChange TLS config validation
|
// TODO(ik) onChange TLS config validation
|
||||||
console.log('debouncedConfigValidation');
|
console.log('debouncedConfigValidation');
|
||||||
debouncedConfigValidation(watchedValues);
|
|
||||||
previousValuesRef.current = watchedValues;
|
previousValuesRef.current = watchedValues;
|
||||||
}
|
}
|
||||||
}, [watchedValues]);
|
}, [watchedValues]);
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ export const Encryption = ({ encryption, setTlsConfig, validateTlsConfig }: Prop
|
|||||||
const submitValues = getSubmitValues(values);
|
const submitValues = getSubmitValues(values);
|
||||||
|
|
||||||
if (submitValues.enabled) {
|
if (submitValues.enabled) {
|
||||||
console.log('validateTlsConfig');
|
|
||||||
validateTlsConfig(submitValues);
|
validateTlsConfig(submitValues);
|
||||||
}
|
}
|
||||||
}, DEBOUNCE_TIMEOUT),
|
}, DEBOUNCE_TIMEOUT),
|
||||||
|
|||||||
Reference in New Issue
Block a user