From 128229ad736fce424166dc38dcaf17486fd8f1b5 Mon Sep 17 00:00:00 2001 From: Artem Baskal Date: Fri, 2 Oct 2020 11:33:12 +0300 Subject: [PATCH] + client: Add block and unblock buttons to 'check the filtering' result Close #1734 Squashed commit of the following: commit b7e274318aea773b6b7effba0fcf13859a23d45c Merge: 77c823a4 2f6f65a8 Author: ArtemBaskal Date: Thu Oct 1 23:36:49 2020 +0300 Merge branch 'master' into feature/1734 commit 77c823a46ad6e094d332b40375a32511c8f6ff11 Author: ArtemBaskal Date: Thu Sep 24 22:36:56 2020 +0300 Add blocking button commit bb77029d46ce18e582db04ccf31f7ed7c57de572 Author: ArtemBaskal Date: Wed Sep 23 22:02:45 2020 +0300 Refactor check info commit bd8cf052a0458c767aa65d0d8749648f8e10fdba Author: ArtemBaskal Date: Wed Sep 23 21:15:24 2020 +0300 Fix prop processingCheck commit 5a1d696f7e15f2e1367ff3f9a1767ee3c2344b1b Author: ArtemBaskal Date: Wed Sep 23 20:35:21 2020 +0300 Refactor Check component --- client/src/components/Filters/Check/Info.js | 221 ++++++++----------- client/src/components/Filters/Check/index.js | 117 ++++------ client/src/components/Filters/CustomRules.js | 12 +- client/src/components/Logs/Logs.css | 4 + 4 files changed, 142 insertions(+), 212 deletions(-) diff --git a/client/src/components/Filters/Check/Info.js b/client/src/components/Filters/Check/Info.js index 0c73c55a..1d4c22c5 100644 --- a/client/src/components/Filters/Check/Info.js +++ b/client/src/components/Filters/Check/Info.js @@ -1,155 +1,124 @@ -import React, { Fragment } from 'react'; -import PropTypes from 'prop-types'; -import { withTranslation } from 'react-i18next'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import classNames from 'classnames'; +import i18next from 'i18next'; +import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import { checkFiltered, checkRewrite, checkRewriteHosts, - checkBlackList, - checkNotFilteredNotFound, checkWhiteList, checkSafeSearch, checkSafeBrowsing, - checkParental, getFilterName, + checkParental, + getFilterName, } from '../../../helpers/helpers'; -import { FILTERED } from '../../../helpers/constants'; +import { BLOCK_ACTIONS, FILTERED, FILTERED_STATUS } from '../../../helpers/constants'; +import { toggleBlocking } from '../../../actions'; -const getTitle = (reason, filterName, t, onlyFiltered) => { - if (checkNotFilteredNotFound(reason)) { - return t('check_not_found'); - } +const renderBlockingButton = (isFiltered, domain) => { + const processingRules = useSelector((state) => state.filtering.processingRules); + const dispatch = useDispatch(); + const { t } = useTranslation(); - if (checkRewrite(reason)) { - return t('rewrite_applied'); - } + const buttonType = isFiltered ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK; - if (checkRewriteHosts(reason)) { - return t('rewrite_hosts_applied'); - } + const onClick = async () => { + await dispatch(toggleBlocking(buttonType, domain)); + }; - if (checkBlackList(reason)) { - return filterName; - } + const buttonClass = classNames('mt-3 button-action button-action--main button-action--active button-action--small', { + 'button-action--unblock': isFiltered, + }); - if (checkWhiteList(reason)) { - return ( -
- {filterName} -
- ); - } - - if (onlyFiltered) { - const filterKey = reason.replace(FILTERED, ''); - - return ( -
- {t('query_log_filtered', { filter: filterKey })} -
- ); - } - - return ( - -
- {t('check_reason', { reason })} -
-
- {filterName} -
-
- ); + return ; }; -const getColor = (reason) => { - if (checkFiltered(reason)) { - return 'red'; - } if (checkRewrite(reason) || checkRewriteHosts(reason)) { - return 'blue'; - } if (checkWhiteList(reason)) { - return 'green'; - } +const getTitle = (reason) => { + const { t } = useTranslation(); - return ''; -}; + const filters = useSelector((state) => state.filtering.filters, shallowEqual); + const whitelistFilters = useSelector((state) => state.filtering.whitelistFilters, shallowEqual); + const filter_id = useSelector((state) => state.filtering.check.filter_id); -const Info = ({ - filters, - whitelistFilters, - hostname, - reason, - filter_id, - rule, - service_name, - cname, - ip_addrs, - t, -}) => { - const filterName = getFilterName(filters, + const filterName = getFilterName( + filters, whitelistFilters, filter_id, 'filtered_custom_rules', - (filter) => (filter?.name ? t('query_log_filtered', { filter: filter.name }) : '')); + (filter) => (filter?.name ? t('query_log_filtered', { filter: filter.name }) : ''), + ); + + const getReasonFiltered = (reason) => { + const filterKey = reason.replace(FILTERED, ''); + return i18next.t('query_log_filtered', { filter: filterKey }); + }; + + const REASON_TO_TITLE_MAP = { + [FILTERED_STATUS.NOT_FILTERED_NOT_FOUND]: t('check_not_found'), + [FILTERED_STATUS.REWRITE]: t('rewrite_applied'), + [FILTERED_STATUS.REWRITE_HOSTS]: t('rewrite_hosts_applied'), + [FILTERED_STATUS.FILTERED_BLACK_LIST]: filterName, + [FILTERED_STATUS.NOT_FILTERED_WHITE_LIST]: filterName, + [FILTERED_STATUS.FILTERED_SAFE_SEARCH]: getReasonFiltered(reason), + [FILTERED_STATUS.FILTERED_SAFE_BROWSING]: getReasonFiltered(reason), + [FILTERED_STATUS.FILTERED_PARENTAL]: getReasonFiltered(reason), + }; + + if (Object.prototype.hasOwnProperty.call(REASON_TO_TITLE_MAP, reason)) { + return REASON_TO_TITLE_MAP[reason]; + } + + return <> +
{t('check_reason', { reason })}
+
{filterName}
+ ; +}; + +const Info = () => { + const { + hostname, + reason, + rule, + service_name, + cname, + ip_addrs, + } = useSelector((state) => state.filtering.check, shallowEqual); + const { t } = useTranslation(); + + const title = getTitle(reason); + + const className = classNames('card mb-0 p-3', { + 'logs__row--red': checkFiltered(reason), + 'logs__row--blue': checkRewrite(reason) || checkRewriteHosts(reason), + 'logs__row--green': checkWhiteList(reason), + }); const onlyFiltered = checkSafeSearch(reason) || checkSafeBrowsing(reason) || checkParental(reason); - const title = getTitle(reason, filterName, t, onlyFiltered); - const color = getColor(reason); - if (onlyFiltered) { - return ( -
-
- {hostname} -
+ const isFiltered = checkFiltered(reason); -
{title}
-
- ); - } - - return ( -
-
- {hostname} -
- -
{title}
- - {rule && ( -
{t('check_rule', { rule })}
- )} - - {service_name && ( -
{t('check_service', { service: service_name })}
- )} - - {cname && ( -
{t('check_cname', { cname })}
- )} - - {ip_addrs && ( -
- {t('check_ip', { ip: ip_addrs.join(', ') })} -
- )} -
- ); + return
+
{hostname}
+
{title}
+ {!onlyFiltered + && <> + {rule &&
{t('check_rule', { rule })}
} + {service_name &&
{t('check_service', { service: service_name })}
} + {cname &&
{t('check_cname', { cname })}
} + {ip_addrs &&
{t('check_ip', { ip: ip_addrs.join(', ') })}
} + {renderBlockingButton(isFiltered, hostname)} + } +
; }; -Info.propTypes = { - filters: PropTypes.array.isRequired, - whitelistFilters: PropTypes.array.isRequired, - hostname: PropTypes.string.isRequired, - reason: PropTypes.string.isRequired, - filter_id: PropTypes.number, - rule: PropTypes.string, - service_name: PropTypes.string, - cname: PropTypes.string, - ip_addrs: PropTypes.array, - t: PropTypes.func.isRequired, -}; - -export default withTranslation()(Info); +export default Info; diff --git a/client/src/components/Filters/Check/index.js b/client/src/components/Filters/Check/index.js index a15b62aa..6723c216 100644 --- a/client/src/components/Filters/Check/index.js +++ b/client/src/components/Filters/Check/index.js @@ -1,99 +1,66 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import { Trans, withTranslation } from 'react-i18next'; +import { useTranslation } from 'react-i18next'; import { Field, reduxForm } from 'redux-form'; -import flow from 'lodash/flow'; +import { useSelector } from 'react-redux'; import Card from '../../ui/Card'; - import { renderInputField } from '../../../helpers/form'; import Info from './Info'; import { FORM_NAME } from '../../../helpers/constants'; const Check = (props) => { const { - t, - handleSubmit, pristine, invalid, - processing, - check, - filters, - whitelistFilters, + handleSubmit, } = props; - const { - hostname, - reason, - filter_id, - rule, - service_name, - cname, - ip_addrs, - } = check; + const { t } = useTranslation(); - return ( - -
-
-
-
- - - - -
- {check.hostname && ( - -
- -
- )} + const processingCheck = useSelector((state) => state.filtering.processingCheck); + const hostname = useSelector((state) => state.filtering.check.hostname); + + return + +
+
+
+ + + +
+ {hostname && <> +
+ + }
- - - ); +
+ +
; }; Check.propTypes = { - t: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired, pristine: PropTypes.bool.isRequired, invalid: PropTypes.bool.isRequired, - processing: PropTypes.bool.isRequired, - check: PropTypes.object.isRequired, - filters: PropTypes.array.isRequired, - whitelistFilters: PropTypes.array.isRequired, }; -export default flow([ - withTranslation(), - reduxForm({ form: FORM_NAME.DOMAIN_CHECK }), -])(Check); +export default reduxForm({ form: FORM_NAME.DOMAIN_CHECK })(Check); diff --git a/client/src/components/Filters/CustomRules.js b/client/src/components/Filters/CustomRules.js index 723add5c..05640734 100644 --- a/client/src/components/Filters/CustomRules.js +++ b/client/src/components/Filters/CustomRules.js @@ -45,11 +45,7 @@ class CustomRules extends Component { const { t, filtering: { - filters, - whitelistFilters, userRules, - processingCheck, - check, }, } = this.props; @@ -92,13 +88,7 @@ class CustomRules extends Component {
- + ); } diff --git a/client/src/components/Logs/Logs.css b/client/src/components/Logs/Logs.css index 901c3ab0..e256aeca 100644 --- a/client/src/components/Logs/Logs.css +++ b/client/src/components/Logs/Logs.css @@ -238,6 +238,10 @@ border: 0; } +.button-action--small { + width: fit-content; +} + .button-action--unblock { background: var(--btn-unblock); }