Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home

This commit is contained in:
Andrey Meshkov 2020-09-16 12:38:46 +03:00
commit ad6c43c4a3
10 changed files with 77 additions and 81 deletions

View File

@ -253,7 +253,7 @@
"rate_limit": "Rate limit",
"edns_enable": "Enable EDNS Client Subnet",
"edns_cs_desc": "If enabled, AdGuard Home will be sending clients' subnets to the DNS servers.",
"rate_limit_desc": "The number of requests per second that a single client is allowed to make (0: unlimited)",
"rate_limit_desc": "The number of requests per second that a single client is allowed to make (setting it to 0 means unlimited)",
"blocking_ipv4_desc": "IP address to be returned for a blocked A request",
"blocking_ipv6_desc": "IP address to be returned for a blocked AAAA request",
"blocking_mode_default": "Default: Respond with REFUSED when blocked by Adblock-style rule; respond with the IP address specified in the rule when blocked by /etc/hosts-style rule",
@ -564,10 +564,9 @@
"enter_cache_size": "Enter cache size",
"enter_cache_ttl_min_override": "Enter minimum TTL",
"enter_cache_ttl_max_override": "Enter maximum TTL",
"cache_ttl_min_override_desc": "Override TTL value (minimum) received from upstream server. This value can't larger than 3600 (1 hour)",
"cache_ttl_min_override_desc": "Override TTL value (minimum) received from upstream server",
"cache_ttl_max_override_desc": "Override TTL value (maximum) received from upstream server",
"min_exceeds_max_value": "Minimum value exceeds maximum value",
"value_not_larger_than": "Value can't be larger than {{maximum}}",
"ttl_cache_validation": "Minimum cache TTL value must be less than or equal to the maximum value",
"filter_category_general": "General",
"filter_category_security": "Security",
"filter_category_regional": "Regional",

View File

@ -82,7 +82,7 @@ const Dashboard = ({
</div>
</PageTitle>
{statsProcessing && <Loading />}
{!statsProcessing && <div className="row row-cards">
{!statsProcessing && <div className="row row-cards dashboard">
<div className="col-lg-12">
<Statistics
interval={stats.interval}
@ -100,7 +100,6 @@ const Dashboard = ({
<div className="col-lg-6">
<Counters
subtitle={subtitle}
refreshButton={refreshButton}
/>
</div>

View File

@ -8,10 +8,9 @@ import {
renderInputField,
toNumber,
} from '../../../helpers/form';
import { FORM_NAME } from '../../../helpers/constants';
import { FORM_NAME, UINT32_RANGE } from '../../../helpers/constants';
import {
validateIpv4,
validateIsPositiveValue,
validateRequiredValue,
validateIpv4RangeEnd,
} from '../../../helpers/validators';
@ -110,9 +109,10 @@ const FormDHCPv4 = ({
type="number"
className="form-control"
placeholder={t(ipv4placeholders.lease_duration)}
validate={[validateIsPositiveValue, validateRequired]}
validate={validateRequired}
normalize={toNumber}
min={0}
min={1}
max={UINT32_RANGE.MAX}
disabled={!isInterfaceIncludesIpv4}
/>
</div>

View File

@ -8,12 +8,8 @@ import {
renderInputField,
toNumber,
} from '../../../helpers/form';
import { FORM_NAME } from '../../../helpers/constants';
import {
validateIpv6,
validateIsPositiveValue,
validateRequiredValue,
} from '../../../helpers/validators';
import { FORM_NAME, UINT32_RANGE } from '../../../helpers/constants';
import { validateIpv6, validateRequiredValue } from '../../../helpers/validators';
const FormDHCPv6 = ({
handleSubmit,
@ -86,9 +82,10 @@ const FormDHCPv6 = ({
type="number"
className="form-control"
placeholder={t(ipv6placeholders.lease_duration)}
validate={[validateIsPositiveValue, validateRequired]}
validate={validateRequired}
normalizeOnBlur={toNumber}
min={0}
min={1}
max={UINT32_RANGE.MAX}
disabled={!isInterfaceIncludesIpv6}
/>
</div>

View File

@ -4,32 +4,30 @@ import { Field, reduxForm } from 'redux-form';
import { Trans, useTranslation } from 'react-i18next';
import { shallowEqual, useSelector } from 'react-redux';
import { renderInputField, toNumber } from '../../../../helpers/form';
import { validateBiggerOrEqualZeroValue, getMaxValueValidator, validateRequiredValue } from '../../../../helpers/validators';
import { FORM_NAME, SECONDS_IN_HOUR } from '../../../../helpers/constants';
import { validateRequiredValue } from '../../../../helpers/validators';
import { CACHE_CONFIG_FIELDS, FORM_NAME, UINT32_RANGE } from '../../../../helpers/constants';
const validateMaxValue3600 = getMaxValueValidator(SECONDS_IN_HOUR);
const getInputFields = ({ validateRequiredValue, validateMaxValue3600 }) => [{
name: 'cache_size',
const getInputFields = (validateRequiredValue) => [
{
name: CACHE_CONFIG_FIELDS.cache_size,
title: 'cache_size',
description: 'cache_size_desc',
placeholder: 'enter_cache_size',
validate: validateRequiredValue,
},
{
name: 'cache_ttl_min',
},
{
name: CACHE_CONFIG_FIELDS.cache_ttl_min,
title: 'cache_ttl_min_override',
description: 'cache_ttl_min_override_desc',
placeholder: 'enter_cache_ttl_min_override',
max: SECONDS_IN_HOUR,
validate: validateMaxValue3600,
},
{
name: 'cache_ttl_max',
},
{
name: CACHE_CONFIG_FIELDS.cache_ttl_max,
title: 'cache_ttl_max_override',
description: 'cache_ttl_max_override_desc',
placeholder: 'enter_cache_ttl_max_override',
}];
},
];
const Form = ({
handleSubmit, submitting, invalid,
@ -41,17 +39,16 @@ const Form = ({
cache_ttl_max, cache_ttl_min,
} = useSelector((state) => state.form[FORM_NAME.CACHE].values, shallowEqual);
const minExceedsMax = cache_ttl_min > cache_ttl_max;
const minExceedsMax = typeof cache_ttl_min === 'number'
&& typeof cache_ttl_max === 'number'
&& cache_ttl_min > cache_ttl_max;
const INPUTS_FIELDS = getInputFields({
validateRequiredValue,
validateMaxValue3600,
});
const INPUTS_FIELDS = getInputFields(validateRequiredValue);
return <form onSubmit={handleSubmit}>
<div className="row">
{INPUTS_FIELDS.map(({
name, title, description, placeholder, validate, max,
name, title, description, placeholder, validate, min = 0, max = UINT32_RANGE.MAX,
}) => <div className="col-12" key={name}>
<div className="col-12 col-md-7 p-0">
<div className="form__group form__group--settings">
@ -66,15 +63,15 @@ const Form = ({
disabled={processingSetConfig}
normalize={toNumber}
className="form-control"
validate={[validateBiggerOrEqualZeroValue].concat(validate || [])}
min={0}
validate={validate}
min={min}
max={max}
/>
</div>
</div>
</div>)}
{minExceedsMax
&& <span className="text-danger pl-3 pb-3">{t('min_exceeds_max_value')}</span>}
&& <span className="text-danger pl-3 pb-3">{t('ttl_cache_validation')}</span>}
</div>
<button
type="submit"

View File

@ -1,10 +1,12 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { change } from 'redux-form';
import Card from '../../../ui/Card';
import Form from './Form';
import { setDnsConfig } from '../../../../actions/dnsConfig';
import { selectCompletedFields } from '../../../../helpers/helpers';
import { CACHE_CONFIG_FIELDS, FORM_NAME } from '../../../../helpers/constants';
const CacheConfig = () => {
const { t } = useTranslation();
@ -15,6 +17,15 @@ const CacheConfig = () => {
const handleFormSubmit = (values) => {
const completedFields = selectCompletedFields(values);
Object.entries(completedFields).forEach(([k, v]) => {
if ((k === CACHE_CONFIG_FIELDS.cache_ttl_min
|| k === CACHE_CONFIG_FIELDS.cache_ttl_max)
&& v === 0) {
dispatch(change(FORM_NAME.CACHE, k, ''));
}
});
dispatch(setDnsConfig(completedFields));
};

View File

@ -10,12 +10,11 @@ import {
toNumber,
} from '../../../../helpers/form';
import {
validateBiggerOrEqualZeroValue,
validateIpv4,
validateIpv6,
validateRequiredValue,
} from '../../../../helpers/validators';
import { BLOCKING_MODES, FORM_NAME } from '../../../../helpers/constants';
import { BLOCKING_MODES, FORM_NAME, UINT32_RANGE } from '../../../../helpers/constants';
const checkboxes = [
{
@ -87,7 +86,9 @@ const Form = ({
className="form-control"
placeholder={t('form_enter_rate_limit')}
normalize={toNumber}
validate={[validateRequiredValue, validateBiggerOrEqualZeroValue]}
validate={validateRequiredValue}
min={UINT32_RANGE.MIN}
max={UINT32_RANGE.MAX}
/>
</div>
</div>

View File

@ -19,7 +19,7 @@
max-height: 17.5rem;
}
.card-table-overflow--limited.clients__table {
.dashboard .card-table-overflow--limited {
max-height: 18rem;
}
@ -122,6 +122,12 @@
}
}
@media (min-width: 992px) {
.dashboard .card:not(.card--full) {
height: 22rem;
}
}
.card .logs__cell--red {
background-color: #fff4f2;
}

View File

@ -506,9 +506,12 @@ export const FORM_NAME = {
export const SMALL_SCREEN_SIZE = 767;
export const MEDIUM_SCREEN_SIZE = 1023;
export const SECONDS_IN_HOUR = 60 * 60;
export const SECONDS_IN_DAY = 60 * 60 * 24;
export const SECONDS_IN_DAY = SECONDS_IN_HOUR * 24;
export const UINT32_RANGE = {
MIN: 0,
MAX: 4294967295,
};
export const DHCP_VALUES_PLACEHOLDERS = {
ipv4: {
@ -559,3 +562,9 @@ export const ADDRESS_TYPES = {
CIDR: 'CIDR',
UNKNOWN: 'UNKNOWN',
};
export const CACHE_CONFIG_FIELDS = {
cache_size: 'cache_size',
cache_ttl_min: 'cache_ttl_min',
cache_ttl_max: 'cache_ttl_max',
};

View File

@ -1,4 +1,3 @@
import i18next from 'i18next';
import {
MAX_PORT,
R_CIDR,
@ -28,17 +27,6 @@ export const validateRequiredValue = (value) => {
return 'form_error_required';
};
/**
* @param maximum {number}
* @returns {(value:number) => undefined|string}
*/
export const getMaxValueValidator = (maximum) => (value) => {
if (value && value > maximum) {
return i18next.t('value_not_larger_than', { maximum });
}
return undefined;
};
/**
* @param value {string}
* @returns {undefined|string}
@ -122,17 +110,6 @@ export const validateMac = (value) => {
return undefined;
};
/**
* @param value {number}
* @returns {undefined|string}
*/
export const validateIsPositiveValue = (value) => {
if ((value || value === 0) && value <= 0) {
return 'form_error_positive';
}
return undefined;
};
/**
* @param value {number}
* @returns {boolean|*}