diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index f1e8bd62..2795c843 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -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", diff --git a/client/src/components/Dashboard/Dashboard.css b/client/src/components/Dashboard/Dashboard.css index 04522ef6..6d3aef7f 100644 --- a/client/src/components/Dashboard/Dashboard.css +++ b/client/src/components/Dashboard/Dashboard.css @@ -26,3 +26,10 @@ left: -20px; width: calc(100% + 20px); } + +@media (max-width: 1279.98px) { + .table__action { + position: absolute; + right: 0; + } +} diff --git a/client/src/components/Settings/Dhcp/FormDHCPv4.js b/client/src/components/Settings/Dhcp/FormDHCPv4.js index b938b6f0..873e7696 100644 --- a/client/src/components/Settings/Dhcp/FormDHCPv4.js +++ b/client/src/components/Settings/Dhcp/FormDHCPv4.js @@ -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} /> diff --git a/client/src/components/Settings/Dhcp/FormDHCPv6.js b/client/src/components/Settings/Dhcp/FormDHCPv6.js index 80219fd6..e37a6213 100644 --- a/client/src/components/Settings/Dhcp/FormDHCPv6.js +++ b/client/src/components/Settings/Dhcp/FormDHCPv6.js @@ -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} /> diff --git a/client/src/components/Settings/Dns/Cache/Form.js b/client/src/components/Settings/Dns/Cache/Form.js index c7b2d6ed..f17310c9 100644 --- a/client/src/components/Settings/Dns/Cache/Form.js +++ b/client/src/components/Settings/Dns/Cache/Form.js @@ -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', - title: 'cache_size', - description: 'cache_size_desc', - placeholder: 'enter_cache_size', - validate: validateRequiredValue, -}, -{ - name: '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', - title: 'cache_ttl_max_override', - description: 'cache_ttl_max_override_desc', - placeholder: 'enter_cache_ttl_max_override', -}]; +const getInputFields = (validateRequiredValue) => [ + { + name: CACHE_CONFIG_FIELDS.cache_size, + title: 'cache_size', + description: 'cache_size_desc', + placeholder: 'enter_cache_size', + validate: validateRequiredValue, + }, + { + name: CACHE_CONFIG_FIELDS.cache_ttl_min, + title: 'cache_ttl_min_override', + description: 'cache_ttl_min_override_desc', + placeholder: 'enter_cache_ttl_min_override', + }, + { + 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
{INPUTS_FIELDS.map(({ - name, title, description, placeholder, validate, max, + name, title, description, placeholder, validate, min = 0, max = UINT32_RANGE.MAX, }) =>
@@ -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} />
)} {minExceedsMax - && {t('min_exceeds_max_value')}} + && {t('ttl_cache_validation')}}