From 6b134469d477a35d4307f36a3824a59ffc2e7597 Mon Sep 17 00:00:00 2001 From: Artem Baskal Date: Fri, 3 Jul 2020 19:17:58 +0300 Subject: [PATCH] - client: Clear input field when switching from logs page Close #1523 Squashed commit of the following: commit 9ae9b0e480c2ec6bd835faf4caccacd8c1fdfe9f Author: ArtemBaskal Date: Fri Jul 3 17:56:34 2020 +0300 Setup babel and apply everywhere nullish coalescing and optional chaining operators commit 0966063842a79078e1d61a54c271e18c9427b2b1 Merge: 42a54f2b 21dfb5ff Author: ArtemBaskal Date: Fri Jul 3 16:59:34 2020 +0300 Merge branch 'master' into fix/1523 commit 42a54f2ba0d8f5f4e4c04f16abc507b5d9009035 Author: ArtemBaskal Date: Fri Jul 3 13:30:25 2020 +0300 Center mobile tooltip buttons commit 9cdd501a863b596f1d903f8dd3c449ffbe4c1604 Author: ArtemBaskal Date: Fri Jul 3 13:21:37 2020 +0300 Add cross icon to clear input on click commit 1308b93c42ffea2ffb7457c34aef96e5cdaccaf2 Merge: 265fec7c da546790 Author: ArtemBaskal Date: Mon Jun 29 19:42:04 2020 +0300 Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home commit 265fec7c72656b0c4738623cb470f1c14736230a Author: ArtemBaskal Date: Mon Jun 29 19:41:37 2020 +0300 - client: Clear input field when switching from logs page --- client/babel.config.js | 2 + client/package-lock.json | 32 ++++++++--- client/package.json | 2 + client/src/actions/index.js | 4 +- .../src/components/Filters/Services/index.js | 2 +- .../components/Logs/Cells/getClientCell.js | 13 ++--- .../components/Logs/Cells/getDomainCell.js | 4 +- .../components/Logs/Cells/getResponseCell.js | 3 +- client/src/components/Logs/Filters/Form.js | 53 +++++++++++++++---- client/src/components/Logs/Filters/index.js | 3 +- client/src/components/Logs/Logs.css | 27 +++++----- client/src/components/Logs/Table.js | 37 ++++++------- client/src/components/Logs/index.js | 2 +- client/src/components/Settings/Dhcp/index.js | 2 +- client/src/components/Toasts/index.js | 2 +- client/src/components/ui/Guide.js | 6 +-- client/src/components/ui/Icons.css | 5 ++ client/src/helpers/form.js | 4 +- client/src/helpers/formatClientCell.js | 6 +-- client/src/helpers/helpers.js | 10 ++-- client/src/install/Setup/Settings.js | 4 +- client/src/reducers/access.js | 12 ++--- 22 files changed, 144 insertions(+), 91 deletions(-) diff --git a/client/babel.config.js b/client/babel.config.js index 55609d5e..c6fdd790 100644 --- a/client/babel.config.js +++ b/client/babel.config.js @@ -9,6 +9,8 @@ module.exports = (api) => { '@babel/plugin-proposal-class-properties', '@babel/plugin-transform-runtime', '@babel/plugin-proposal-object-rest-spread', + '@babel/plugin-proposal-nullish-coalescing-operator', + '@babel/plugin-proposal-optional-chaining', ], }; }; diff --git a/client/package-lock.json b/client/package-lock.json index 91b1f414..faaa5598 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -472,13 +472,21 @@ } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", + "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } } }, "@babel/plugin-proposal-numeric-separator": { @@ -513,13 +521,21 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", - "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.4.tgz", + "integrity": "sha512-ZIhQIEeavTgouyMSdZRap4VPPHqJJ3NEs2cuHs5p0erH+iz6khB0qfgU8g7UuJkG88+fBMy23ZiU+nuHvekJeQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-optional-chaining": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } } }, "@babel/plugin-proposal-unicode-property-regex": { diff --git a/client/package.json b/client/package.json index 7f154d4d..edf5e424 100644 --- a/client/package.json +++ b/client/package.json @@ -44,7 +44,9 @@ "devDependencies": { "@babel/core": "^7.9.6", "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", "@babel/plugin-proposal-object-rest-spread": "^7.9.6", + "@babel/plugin-proposal-optional-chaining": "^7.10.4", "@babel/plugin-transform-runtime": "^7.9.6", "@babel/preset-env": "^7.9.6", "@babel/preset-react": "^7.9.4", diff --git a/client/src/actions/index.js b/client/src/actions/index.js index 478a3021..2cef57e6 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.js @@ -149,7 +149,7 @@ const checkStatus = async (handleRequestSuccess, handleRequestError, attempts = try { const response = await axios.get('control/status'); rmTimeout(timeout); - if (response && response.status === 200) { + if (response?.status === 200) { handleRequestSuccess(response); if (response.data.running === false) { timeout = setTimeout( @@ -183,7 +183,7 @@ export const getUpdate = () => async (dispatch, getState) => { }; const handleRequestSuccess = (response) => { - const responseVersion = response.data && response.data.version; + const responseVersion = response.data?.version; if (dnsVersion !== responseVersion) { dispatch(getUpdateSuccess()); diff --git a/client/src/components/Filters/Services/index.js b/client/src/components/Filters/Services/index.js index 1830be38..e1c9d840 100644 --- a/client/src/components/Filters/Services/index.js +++ b/client/src/components/Filters/Services/index.js @@ -17,7 +17,7 @@ const getInitialDataForServices = (initial) => (initial ? initial.reduce( const Services = () => { const [t] = useTranslation(); const dispatch = useDispatch(); - const services = useSelector((store) => store && store.services); + const services = useSelector((store) => store?.services); useEffect(() => { dispatch(getBlockedServices()); diff --git a/client/src/components/Logs/Cells/getClientCell.js b/client/src/components/Logs/Cells/getClientCell.js index b842e0e6..147dd3af 100644 --- a/client/src/components/Logs/Cells/getClientCell.js +++ b/client/src/components/Logs/Cells/getClientCell.js @@ -11,23 +11,20 @@ const getClientCell = ({ row, t, isDetailed, toggleBlocking, autoClients, processingRules, }) => { const { - reason, client, domain, info: { name }, + reason, client, domain, info: { name, whois_info }, } = row.original; const autoClient = autoClients.find((autoClient) => autoClient.name === client); - const country = autoClient && autoClient.whois_info && autoClient.whois_info.country; - const city = autoClient && autoClient.whois_info && autoClient.whois_info.city; - const network = autoClient && autoClient.whois_info && autoClient.whois_info.orgname; - const source = autoClient && autoClient.source; + const source = autoClient?.source; const id = nanoid(); const data = { address: client, name, - country, - city, - network, + country: whois_info?.country, + city: whois_info?.city, + network: whois_info?.orgname, source_label: source, }; diff --git a/client/src/components/Logs/Cells/getDomainCell.js b/client/src/components/Logs/Cells/getDomainCell.js index 0d460190..bff36c37 100644 --- a/client/src/components/Logs/Cells/getDomainCell.js +++ b/client/src/components/Logs/Cells/getDomainCell.js @@ -57,8 +57,8 @@ const getDomainCell = (props) => { const sourceData = getSourceData(tracker); const knownTrackerDataObj = { - name_table_header: tracker && tracker.name, - category_label: tracker && captitalizeWords(tracker.category), + name_table_header: tracker?.name, + category_label: hasTracker && captitalizeWords(tracker.category), source_label: sourceData && {sourceData.name}, diff --git a/client/src/components/Logs/Cells/getResponseCell.js b/client/src/components/Logs/Cells/getResponseCell.js index f0b390c3..73cd1d2b 100644 --- a/client/src/components/Logs/Cells/getResponseCell.js +++ b/client/src/components/Logs/Cells/getResponseCell.js @@ -36,8 +36,7 @@ const getResponseCell = (row, filtering, t, isDetailed) => { const { filters, whitelistFilters } = filtering; const formattedElapsedMs = formatElapsedMs(elapsedMs, t); - const statusLabel = t((FILTERED_STATUS_TO_META_MAP[reason] - && FILTERED_STATUS_TO_META_MAP[reason].label) || reason); + const statusLabel = t(FILTERED_STATUS_TO_META_MAP[reason]?.label || reason); const boldStatusLabel = {statusLabel}; const filter = getFilterName(filters, whitelistFilters, filterId, t); diff --git a/client/src/components/Logs/Filters/Form.js b/client/src/components/Logs/Filters/Form.js index df0bc483..21e64322 100644 --- a/client/src/components/Logs/Filters/Form.js +++ b/client/src/components/Logs/Filters/Form.js @@ -1,10 +1,18 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import { Field, reduxForm } from 'redux-form'; import { useTranslation } from 'react-i18next'; import debounce from 'lodash/debounce'; -import { DEBOUNCE_FILTER_TIMEOUT, FORM_NAME, RESPONSE_FILTER } from '../../../helpers/constants'; +import { useDispatch } from 'react-redux'; +import classNames from 'classnames'; +import { + DEBOUNCE_FILTER_TIMEOUT, + DEFAULT_LOGS_FILTER, + FORM_NAME, + RESPONSE_FILTER, +} from '../../../helpers/constants'; import Tooltip from '../../ui/Tooltip'; +import { setLogsFilter } from '../../../actions/queryLogs'; const renderFilterField = ({ input, @@ -16,8 +24,9 @@ const renderFilterField = ({ autoComplete, tooltip, meta: { touched, error }, + onClearInputClick, }) => <> -
+
@@ -31,9 +40,15 @@ const renderFilterField = ({ disabled={disabled} autoComplete={autoComplete} aria-label={placeholder} /> - - - +
+ + + +
+ + + {!disabled && touched && (error && {error})} @@ -42,6 +57,7 @@ const renderFilterField = ({ renderFilterField.propTypes = { input: PropTypes.object.isRequired, id: PropTypes.string.isRequired, + onClearInputClick: PropTypes.func.isRequired, className: PropTypes.string, placeholder: PropTypes.string, type: PropTypes.string, @@ -59,13 +75,29 @@ const Form = (props) => { className = '', responseStatusClass, submit, + reset, + setIsLoading, } = props; - const [t] = useTranslation(); + const { t } = useTranslation(); + const dispatch = useDispatch(); const debouncedSubmit = debounce(submit, DEBOUNCE_FILTER_TIMEOUT); const zeroDelaySubmit = () => setTimeout(submit, 0); + const clearInput = async () => { + await dispatch(setLogsFilter(DEFAULT_LOGS_FILTER)); + await reset(); + }; + + const onInputClear = async () => { + setIsLoading(true); + await clearInput(); + setIsLoading(false); + }; + + useEffect(() => clearInput, []); + return (
{ @@ -79,16 +111,17 @@ const Form = (props) => { name="search" component={renderFilterField} type="text" - className={`form-control--search form-control--transparent ${className}`} + className={classNames('form-control--search form-control--transparent', className)} placeholder={t('domain_or_client')} tooltip={t('query_log_strict_search')} onChange={debouncedSubmit} + onClearInputClick={onInputClear} />
{Object.values(RESPONSE_FILTER) @@ -107,6 +140,8 @@ Form.propTypes = { className: PropTypes.string, responseStatusClass: PropTypes.string, submit: PropTypes.func.isRequired, + reset: PropTypes.func.isRequired, + setIsLoading: PropTypes.func.isRequired, }; export default reduxForm({ diff --git a/client/src/components/Logs/Filters/index.js b/client/src/components/Logs/Filters/index.js index 49744af3..8bb2165c 100644 --- a/client/src/components/Logs/Filters/index.js +++ b/client/src/components/Logs/Filters/index.js @@ -33,7 +33,8 @@ const Filters = ({ filter, refreshLogs, setIsLoading }) => { responseStatusClass="d-sm-block" initialValues={filter} onSubmit={onSubmit} - /> + setIsLoading={setIsLoading} + />
); }; diff --git a/client/src/components/Logs/Logs.css b/client/src/components/Logs/Logs.css index 0a5939c1..2f12c08d 100644 --- a/client/src/components/Logs/Logs.css +++ b/client/src/components/Logs/Logs.css @@ -199,17 +199,6 @@ position: relative; } -.logs__notice { - position: relative; - z-index: 1; - top: 0.5rem; - right: 2rem; - margin-top: 0.1875rem; - font-size: 0.75rem; - text-align: left; - color: var(--gray-a5); -} - .logs__whois { display: inline; font-size: 12px; @@ -485,10 +474,22 @@ .input-group-search { background-color: transparent; position: relative; - left: 2rem; - top: 0.4rem; width: 1.5rem; height: 1.5rem; + top: 0.4rem; +} + +.input-group-search__icon--magnifier { + left: 2rem; +} + +.input-group-search__icon--cross { + left: -4.5rem; + cursor: pointer; +} + +.input-group-search__icon--tooltip { + left: -4rem; } .form-control--container { diff --git a/client/src/components/Logs/Table.js b/client/src/components/Logs/Table.js index ccab98bb..6e0649de 100644 --- a/client/src/components/Logs/Table.js +++ b/client/src/components/Logs/Table.js @@ -180,6 +180,7 @@ const Table = (props) => { minWidth: 123, maxHeight: 60, headerClassName: 'logs__text', + className: 'pb-0', }, ]; @@ -279,20 +280,15 @@ const Table = (props) => { const hasTracker = !!tracker; - const autoClient = autoClients.find( - (autoClient) => autoClient.name === client, - ); + const autoClient = autoClients + .find((autoClient) => autoClient.name === client); - const country = autoClient && autoClient.whois_info - && autoClient.whois_info.country; + const { whois_info } = info; + const country = whois_info?.country; + const city = whois_info?.city; + const network = whois_info?.orgname; - const network = autoClient && autoClient.whois_info - && autoClient.whois_info.orgname; - - const city = autoClient && autoClient.whois_info - && autoClient.whois_info.city; - - const source = autoClient && autoClient.source; + const source = autoClient?.source; const formattedElapsedMs = formatElapsedMs(elapsedMs, t); const isFiltered = checkFiltered(reason); @@ -302,8 +298,7 @@ const Table = (props) => { toggleBlocking(buttonType, domain); }; - const status = t((FILTERED_STATUS_TO_META_MAP[reason] - && FILTERED_STATUS_TO_META_MAP[reason].label) || reason); + const status = t(FILTERED_STATUS_TO_META_MAP[reason]?.label || reason); const statusBlocked =
{status}
; const protocol = t(SCHEME_TO_PROTOCOL_MAP[client_proto]) || ''; @@ -318,7 +313,7 @@ const Table = (props) => { type_table_header: type, protocol, known_tracker: hasTracker && 'title', - table_name: hasTracker && tracker.name, + table_name: tracker?.name, category_label: hasTracker && captitalizeWords(tracker.category), tracker_source: hasTracker && sourceData && { response_details: 'title', install_settings_dns: upstream, elapsed: formattedElapsedMs, - response_table_header: response && response.join('\n'), + response_table_header: response?.join('\n'), client_details: 'title', ip_address: client, - name: info && info.name, + name: info?.name, country, city, network, source_label: source, validated_with_dnssec: dnssec_enabled ? Boolean(answer_dnssec) : false, [buttonType]:
{t(buttonType)}
, + className="title--border bg--danger text-center">{t(buttonType)}
, }; const detailedDataBlocked = { @@ -347,7 +342,7 @@ const Table = (props) => { type_table_header: type, protocol, known_tracker: 'title', - table_name: hasTracker && tracker.name, + table_name: tracker?.name, category_label: hasTracker && captitalizeWords(tracker.category), source_label: hasTracker && sourceData && { response_details: 'title', install_settings_dns: upstream, elapsed: formattedElapsedMs, - response_table_header: response && response.join('\n'), + response_table_header: response?.join('\n'), [buttonType]:
{t(buttonType)}
, + className="title--border text-center">{t(buttonType)}
, }; const detailedDataCurrent = isFiltered ? detailedDataBlocked : detailedData; diff --git a/client/src/components/Logs/index.js b/client/src/components/Logs/index.js index 3ac21857..6bfdcb86 100644 --- a/client/src/components/Logs/index.js +++ b/client/src/components/Logs/index.js @@ -12,12 +12,12 @@ import Loading from '../ui/Loading'; import Filters from './Filters'; import Table from './Table'; import Disabled from './Disabled'; -import './Logs.css'; import { getFilteringStatus } from '../../actions/filtering'; import { getClients } from '../../actions'; import { getDnsConfig } from '../../actions/dnsConfig'; import { getLogsConfig } from '../../actions/queryLogs'; import { addSuccessToast } from '../../actions/toasts'; +import './Logs.css'; const INITIAL_REQUEST = true; const INITIAL_REQUEST_DATA = ['', TABLE_FIRST_PAGE, INITIAL_REQUEST]; diff --git a/client/src/components/Settings/Dhcp/index.js b/client/src/components/Settings/Dhcp/index.js index 8943fb6e..b08b1094 100644 --- a/client/src/components/Settings/Dhcp/index.js +++ b/client/src/components/Settings/Dhcp/index.js @@ -32,7 +32,7 @@ class Dhcp extends Component { const { config, check, processingDhcp, processingConfig, } = this.props.dhcp; - const otherDhcpFound = check && check.otherServer + const otherDhcpFound = check?.otherServer && check.otherServer.found === DHCP_STATUS_RESPONSE.YES; const filledConfig = Object.keys(config).every((key) => { if (key === 'enabled' || key === 'icmp_timeout_msec') { diff --git a/client/src/components/Toasts/index.js b/client/src/components/Toasts/index.js index a0278751..d765b097 100644 --- a/client/src/components/Toasts/index.js +++ b/client/src/components/Toasts/index.js @@ -9,7 +9,7 @@ import './Toast.css'; const Toasts = (props) => ( - {props.toasts.notices && props.toasts.notices.map((toast) => { + {props.toasts.notices?.map((toast) => { const { id } = toast; return (
- {tlsAddress && tlsAddress.length > 0 && ( + {tlsAddress?.length > 0 && (
)} - {httpsAddress && httpsAddress.length > 0 && ( + {httpsAddress?.length > 0 && (
{!disabled && touched - && (error && {error})} + && error && {error}} ; renderSelectField.propTypes = { @@ -232,7 +232,7 @@ renderServiceField.propTypes = { // https://redux-form.com/6.6.3/examples/fieldlevelvalidation/ export const required = (value) => { const formattedValue = typeof value === 'string' ? value.trim() : value; - if (formattedValue || formattedValue === 0 || (formattedValue && formattedValue.length !== 0)) { + if (formattedValue || formattedValue === 0 || formattedValue?.length !== 0) { return undefined; } return form_error_required; diff --git a/client/src/helpers/formatClientCell.js b/client/src/helpers/formatClientCell.js index 37776af1..9e125588 100644 --- a/client/src/helpers/formatClientCell.js +++ b/client/src/helpers/formatClientCell.js @@ -1,4 +1,4 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import { normalizeWhois } from './helpers'; import { WHOIS_ICONS } from './constants'; @@ -11,12 +11,12 @@ const getFormattedWhois = (whois, t) => { return ( {icon && ( - + <>   - + )}{whoisInfo[key]} ); diff --git a/client/src/helpers/helpers.js b/client/src/helpers/helpers.js index 8b3308c3..26954bed 100644 --- a/client/src/helpers/helpers.js +++ b/client/src/helpers/helpers.js @@ -142,7 +142,7 @@ export const addClientInfo = (data, clients, param) => ( const info = clients.find((item) => item[clientIp]) || ''; return { ...row, - info: (info && info[clientIp]) || '', + info: info?.[clientIp] ?? '', }; }) ); @@ -342,7 +342,7 @@ export const normalizeTopClients = (topClients) => topClients.reduce( export const getClientInfo = (clients, ip) => { const client = clients - .find((item) => item.ip_addrs && item.ip_addrs.find((clientIp) => clientIp === ip)); + .find((item) => item.ip_addrs?.find((clientIp) => clientIp === ip)); if (!client) { return ''; @@ -403,7 +403,7 @@ export const secondsToMilliseconds = (seconds) => { return seconds; }; -export const normalizeRulesTextarea = (text) => text && text.replace(/^\n/g, '') +export const normalizeRulesTextarea = (text) => text?.replace(/^\n/g, '') .replace(/\n\s*\n/g, '\n'); export const isVersionGreater = (currentVersion, previousVersion) => ( @@ -415,7 +415,7 @@ export const normalizeWhois = (whois) => { const { city, country, ...values } = whois; - let location = (country && country) || ''; + let location = country || ''; if (city && location) { location = `${location}, ${city}`; @@ -483,7 +483,7 @@ export const checkParental = (reason) => reason === FILTERED_STATUS.FILTERED_PAR export const checkBlockedService = (reason) => reason === FILTERED_STATUS.FILTERED_BLOCKED_SERVICE; export const getCurrentFilter = (url, filters) => { - const filter = filters && filters.find((item) => url === item.url); + const filter = filters?.find((item) => url === item.url); if (filter) { const { enabled, name, url } = filter; diff --git a/client/src/install/Setup/Settings.js b/client/src/install/Setup/Settings.js index afafcf34..f12c3344 100644 --- a/client/src/install/Setup/Settings.js +++ b/client/src/install/Setup/Settings.js @@ -29,9 +29,9 @@ const renderInterfaces = ((interfaces) => ( flags, } = option; - if (option && ip_addresses && ip_addresses.length > 0) { + if (option && ip_addresses?.length > 0) { const ip = getInterfaceIp(option); - const isDown = flags && flags.includes('down'); + const isDown = flags?.includes('down'); if (isDown) { return ( diff --git a/client/src/reducers/access.js b/client/src/reducers/access.js index cf1ad958..e90bb314 100644 --- a/client/src/reducers/access.js +++ b/client/src/reducers/access.js @@ -14,9 +14,9 @@ const access = handleActions( } = payload; const newState = { ...state, - allowed_clients: (allowed_clients && allowed_clients.join('\n')) || '', - disallowed_clients: (disallowed_clients && disallowed_clients.join('\n')) || '', - blocked_hosts: (blocked_hosts && blocked_hosts.join('\n')) || '', + allowed_clients: allowed_clients?.join('\n') || '', + disallowed_clients: disallowed_clients?.join('\n') || '', + blocked_hosts: blocked_hosts?.join('\n') || '', processing: false, }; return newState; @@ -42,9 +42,9 @@ const access = handleActions( } = payload; const newState = { ...state, - allowed_clients: (allowed_clients && allowed_clients.join('\n')) || '', - disallowed_clients: (disallowed_clients && disallowed_clients.join('\n')) || '', - blocked_hosts: (blocked_hosts && blocked_hosts.join('\n')) || '', + allowed_clients: allowed_clients?.join('\n') || '', + disallowed_clients: disallowed_clients?.join('\n') || '', + blocked_hosts: blocked_hosts?.join('\n') || '', processingSet: false, }; return newState;