client: 2451 Support multiple matched rules in the UI
Close #2451
Squashed commit of the following:
commit f6d0a8fe4fa575dff67b2d2f4c9f6aaf6a6414d3
Merge: 3b13e529d 955b735c8
Author: Artem Baskal <a.baskal@adguard.com>
Date: Fri Dec 25 14:53:16 2020 +0300
Merge branch 'master' into feature/2451
commit 3b13e529da01823cbc674d81be065b68cd08bbd3
Author: Artem Baskal <a.baskal@adguard.com>
Date: Thu Dec 24 12:53:13 2020 +0300
Update JSXElement in jsdocs
commit f0749cd0466ef69d964b1c2575dffacb33f71b31
Author: Artem Baskal <a.baskal@adguard.com>
Date: Mon Dec 21 13:23:48 2020 +0300
minor
commit bd014b00e762a1895c132bc962c06f107c50fe17
Author: Artem Baskal <a.baskal@adguard.com>
Date: Mon Dec 21 12:49:29 2020 +0300
Minor helper update
commit 260a66b7b78eb80596b88fec14f409838727e4bb
Author: Artem Baskal <a.baskal@adguard.com>
Date: Mon Dec 21 12:31:08 2020 +0300
Rule locale update
commit c960cf9f658e52cb587676dceb97506880a9db94
Author: Artem Baskal <a.baskal@adguard.com>
Date: Mon Dec 21 12:27:50 2020 +0300
Add styles for filters list
commit 6f3b2176fd52598cddb147ad7828adb95abf08f0
Author: Artem Baskal <a.baskal@adguard.com>
Date: Fri Dec 18 18:34:17 2020 +0300
client: 2451 Support multiple matched rules in the UI
This commit is contained in:
parent
955b735c8b
commit
644a9b5565
@ -1846,7 +1846,7 @@ Response:
|
|||||||
}
|
}
|
||||||
|
|
||||||
There are also deprecated properties `filter_id` and `rule` on the top level of
|
There are also deprecated properties `filter_id` and `rule` on the top level of
|
||||||
the response object. Their usaga should be replaced with
|
the response object. Their usage should be replaced with
|
||||||
`rules[*].filter_list_id` and `rules[*].text` correspondingly. See the
|
`rules[*].filter_list_id` and `rules[*].text` correspondingly. See the
|
||||||
_OpenAPI_ documentation and the `./openapi/CHANGELOG.md` file.
|
_OpenAPI_ documentation and the `./openapi/CHANGELOG.md` file.
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@
|
|||||||
"source_label": "Source",
|
"source_label": "Source",
|
||||||
"found_in_known_domain_db": "Found in the known domains database.",
|
"found_in_known_domain_db": "Found in the known domains database.",
|
||||||
"category_label": "Category",
|
"category_label": "Category",
|
||||||
"rule_label": "Rule",
|
"rule_label": "Rule(s)",
|
||||||
"list_label": "List",
|
"list_label": "List",
|
||||||
"unknown_filter": "Unknown filter {{filterId}}",
|
"unknown_filter": "Unknown filter {{filterId}}",
|
||||||
"known_tracker": "Known tracker",
|
"known_tracker": "Known tracker",
|
||||||
@ -530,7 +530,6 @@
|
|||||||
"check_ip": "IP addresses: {{ip}}",
|
"check_ip": "IP addresses: {{ip}}",
|
||||||
"check_cname": "CNAME: {{cname}}",
|
"check_cname": "CNAME: {{cname}}",
|
||||||
"check_reason": "Reason: {{reason}}",
|
"check_reason": "Reason: {{reason}}",
|
||||||
"check_rule": "Rule: {{rule}}",
|
|
||||||
"check_service": "Service name: {{service}}",
|
"check_service": "Service name: {{service}}",
|
||||||
"service_name": "Service name",
|
"service_name": "Service name",
|
||||||
"check_not_found": "Not found in your filter lists",
|
"check_not_found": "Not found in your filter lists",
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
checkSafeSearch,
|
checkSafeSearch,
|
||||||
checkSafeBrowsing,
|
checkSafeBrowsing,
|
||||||
checkParental,
|
checkParental,
|
||||||
getFilterName,
|
getRulesToFilterList,
|
||||||
} from '../../../helpers/helpers';
|
} from '../../../helpers/helpers';
|
||||||
import { BLOCK_ACTIONS, FILTERED, FILTERED_STATUS } from '../../../helpers/constants';
|
import { BLOCK_ACTIONS, FILTERED, FILTERED_STATUS } from '../../../helpers/constants';
|
||||||
import { toggleBlocking } from '../../../actions';
|
import { toggleBlocking } from '../../../actions';
|
||||||
@ -41,32 +41,27 @@ const renderBlockingButton = (isFiltered, domain) => {
|
|||||||
</button>;
|
</button>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTitle = (reason) => {
|
const getTitle = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const filters = useSelector((state) => state.filtering.filters, shallowEqual);
|
const filters = useSelector((state) => state.filtering.filters, shallowEqual);
|
||||||
const whitelistFilters = useSelector((state) => state.filtering.whitelistFilters, shallowEqual);
|
const whitelistFilters = useSelector((state) => state.filtering.whitelistFilters, shallowEqual);
|
||||||
const filter_id = useSelector((state) => state.filtering.check.filter_id);
|
const rules = useSelector((state) => state.filtering.check.rules, shallowEqual);
|
||||||
|
const reason = useSelector((state) => state.filtering.check.reason);
|
||||||
const filterName = getFilterName(
|
|
||||||
filters,
|
|
||||||
whitelistFilters,
|
|
||||||
filter_id,
|
|
||||||
'filtered_custom_rules',
|
|
||||||
(filter) => (filter?.name ? t('query_log_filtered', { filter: filter.name }) : ''),
|
|
||||||
);
|
|
||||||
|
|
||||||
const getReasonFiltered = (reason) => {
|
const getReasonFiltered = (reason) => {
|
||||||
const filterKey = reason.replace(FILTERED, '');
|
const filterKey = reason.replace(FILTERED, '');
|
||||||
return i18next.t('query_log_filtered', { filter: filterKey });
|
return i18next.t('query_log_filtered', { filter: filterKey });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ruleAndFilterNames = getRulesToFilterList(rules, filters, whitelistFilters);
|
||||||
|
|
||||||
const REASON_TO_TITLE_MAP = {
|
const REASON_TO_TITLE_MAP = {
|
||||||
[FILTERED_STATUS.NOT_FILTERED_NOT_FOUND]: t('check_not_found'),
|
[FILTERED_STATUS.NOT_FILTERED_NOT_FOUND]: t('check_not_found'),
|
||||||
[FILTERED_STATUS.REWRITE]: t('rewrite_applied'),
|
[FILTERED_STATUS.REWRITE]: t('rewrite_applied'),
|
||||||
[FILTERED_STATUS.REWRITE_HOSTS]: t('rewrite_hosts_applied'),
|
[FILTERED_STATUS.REWRITE_HOSTS]: t('rewrite_hosts_applied'),
|
||||||
[FILTERED_STATUS.FILTERED_BLACK_LIST]: filterName,
|
[FILTERED_STATUS.FILTERED_BLACK_LIST]: ruleAndFilterNames,
|
||||||
[FILTERED_STATUS.NOT_FILTERED_WHITE_LIST]: filterName,
|
[FILTERED_STATUS.NOT_FILTERED_WHITE_LIST]: ruleAndFilterNames,
|
||||||
[FILTERED_STATUS.FILTERED_SAFE_SEARCH]: getReasonFiltered(reason),
|
[FILTERED_STATUS.FILTERED_SAFE_SEARCH]: getReasonFiltered(reason),
|
||||||
[FILTERED_STATUS.FILTERED_SAFE_BROWSING]: getReasonFiltered(reason),
|
[FILTERED_STATUS.FILTERED_SAFE_BROWSING]: getReasonFiltered(reason),
|
||||||
[FILTERED_STATUS.FILTERED_PARENTAL]: getReasonFiltered(reason),
|
[FILTERED_STATUS.FILTERED_PARENTAL]: getReasonFiltered(reason),
|
||||||
@ -78,7 +73,11 @@ const getTitle = (reason) => {
|
|||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div>{t('check_reason', { reason })}</div>
|
<div>{t('check_reason', { reason })}</div>
|
||||||
<div>{filterName}</div>
|
<div>
|
||||||
|
{t('rule_label')}:
|
||||||
|
|
||||||
|
{ruleAndFilterNames}
|
||||||
|
</div>
|
||||||
</>;
|
</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,14 +85,13 @@ const Info = () => {
|
|||||||
const {
|
const {
|
||||||
hostname,
|
hostname,
|
||||||
reason,
|
reason,
|
||||||
rule,
|
|
||||||
service_name,
|
service_name,
|
||||||
cname,
|
cname,
|
||||||
ip_addrs,
|
ip_addrs,
|
||||||
} = useSelector((state) => state.filtering.check, shallowEqual);
|
} = useSelector((state) => state.filtering.check, shallowEqual);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const title = getTitle(reason);
|
const title = getTitle();
|
||||||
|
|
||||||
const className = classNames('card mb-0 p-3', {
|
const className = classNames('card mb-0 p-3', {
|
||||||
'logs__row--red': checkFiltered(reason),
|
'logs__row--red': checkFiltered(reason),
|
||||||
@ -112,7 +110,6 @@ const Info = () => {
|
|||||||
<div>{title}</div>
|
<div>{title}</div>
|
||||||
{!onlyFiltered
|
{!onlyFiltered
|
||||||
&& <>
|
&& <>
|
||||||
{rule && <div>{t('check_rule', { rule })}</div>}
|
|
||||||
{service_name && <div>{t('check_service', { service: service_name })}</div>}
|
{service_name && <div>{t('check_service', { service: service_name })}</div>}
|
||||||
{cname && <div>{t('check_cname', { cname })}</div>}
|
{cname && <div>{t('check_cname', { cname })}</div>}
|
||||||
{ip_addrs && <div>{t('check_ip', { ip: ip_addrs.join(', ') })}</div>}
|
{ip_addrs && <div>{t('check_ip', { ip: ip_addrs.join(', ') })}</div>}
|
||||||
|
@ -4,8 +4,9 @@ import classNames from 'classnames';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import propTypes from 'prop-types';
|
import propTypes from 'prop-types';
|
||||||
import {
|
import {
|
||||||
|
getRulesToFilterList,
|
||||||
formatElapsedMs,
|
formatElapsedMs,
|
||||||
getFilterName,
|
getFilterNames,
|
||||||
getServiceName,
|
getServiceName,
|
||||||
} from '../../../helpers/helpers';
|
} from '../../../helpers/helpers';
|
||||||
import { FILTERED_STATUS, FILTERED_STATUS_TO_META_MAP } from '../../../helpers/constants';
|
import { FILTERED_STATUS, FILTERED_STATUS_TO_META_MAP } from '../../../helpers/constants';
|
||||||
@ -18,8 +19,7 @@ const ResponseCell = ({
|
|||||||
response,
|
response,
|
||||||
status,
|
status,
|
||||||
upstream,
|
upstream,
|
||||||
rule,
|
rules,
|
||||||
filterId,
|
|
||||||
service_name,
|
service_name,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -36,7 +36,6 @@ const ResponseCell = ({
|
|||||||
|
|
||||||
const statusLabel = t(isBlockedByResponse ? 'blocked_by_cname_or_ip' : FILTERED_STATUS_TO_META_MAP[reason]?.LABEL || reason);
|
const statusLabel = t(isBlockedByResponse ? 'blocked_by_cname_or_ip' : FILTERED_STATUS_TO_META_MAP[reason]?.LABEL || reason);
|
||||||
const boldStatusLabel = <span className="font-weight-bold">{statusLabel}</span>;
|
const boldStatusLabel = <span className="font-weight-bold">{statusLabel}</span>;
|
||||||
const filter = getFilterName(filters, whitelistFilters, filterId);
|
|
||||||
|
|
||||||
const renderResponses = (responseArr) => {
|
const renderResponses = (responseArr) => {
|
||||||
if (!responseArr || responseArr.length === 0) {
|
if (!responseArr || responseArr.length === 0) {
|
||||||
@ -52,18 +51,23 @@ const ResponseCell = ({
|
|||||||
})}</div>;
|
})}</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rulesList = getRulesToFilterList(rules, filters, whitelistFilters);
|
||||||
|
|
||||||
const COMMON_CONTENT = {
|
const COMMON_CONTENT = {
|
||||||
encryption_status: boldStatusLabel,
|
encryption_status: boldStatusLabel,
|
||||||
install_settings_dns: upstream,
|
install_settings_dns: upstream,
|
||||||
elapsed: formattedElapsedMs,
|
elapsed: formattedElapsedMs,
|
||||||
response_code: status,
|
response_code: status,
|
||||||
...(service_name ? { service_name: getServiceName(service_name) } : { filter }),
|
...(service_name
|
||||||
rule_label: rule,
|
? { service_name: getServiceName(service_name) }
|
||||||
|
: { }
|
||||||
|
),
|
||||||
|
rule_label: rulesList,
|
||||||
response_table_header: renderResponses(response),
|
response_table_header: renderResponses(response),
|
||||||
original_response: renderResponses(originalResponse),
|
original_response: renderResponses(originalResponse),
|
||||||
};
|
};
|
||||||
|
|
||||||
const content = rule
|
const content = rules.length > 0
|
||||||
? Object.entries(COMMON_CONTENT)
|
? Object.entries(COMMON_CONTENT)
|
||||||
: Object.entries({
|
: Object.entries({
|
||||||
...COMMON_CONTENT,
|
...COMMON_CONTENT,
|
||||||
@ -78,7 +82,8 @@ const ResponseCell = ({
|
|||||||
}
|
}
|
||||||
return getServiceName(service_name);
|
return getServiceName(service_name);
|
||||||
case FILTERED_STATUS.FILTERED_BLACK_LIST:
|
case FILTERED_STATUS.FILTERED_BLACK_LIST:
|
||||||
return filter;
|
case FILTERED_STATUS.NOT_FILTERED_WHITE_LIST:
|
||||||
|
return getFilterNames(rules, filters, whitelistFilters).join(', ');
|
||||||
default:
|
default:
|
||||||
return formattedElapsedMs;
|
return formattedElapsedMs;
|
||||||
}
|
}
|
||||||
@ -113,8 +118,10 @@ ResponseCell.propTypes = {
|
|||||||
response: propTypes.array.isRequired,
|
response: propTypes.array.isRequired,
|
||||||
status: propTypes.string.isRequired,
|
status: propTypes.string.isRequired,
|
||||||
upstream: propTypes.string.isRequired,
|
upstream: propTypes.string.isRequired,
|
||||||
rule: propTypes.string,
|
rules: propTypes.arrayOf(propTypes.shape({
|
||||||
filterId: propTypes.number,
|
text: propTypes.string.isRequired,
|
||||||
|
filter_list_id: propTypes.number.isRequired,
|
||||||
|
})),
|
||||||
service_name: propTypes.string,
|
service_name: propTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,11 +6,11 @@ import propTypes from 'prop-types';
|
|||||||
import {
|
import {
|
||||||
captitalizeWords,
|
captitalizeWords,
|
||||||
checkFiltered,
|
checkFiltered,
|
||||||
|
getRulesToFilterList,
|
||||||
formatDateTime,
|
formatDateTime,
|
||||||
formatElapsedMs,
|
formatElapsedMs,
|
||||||
formatTime,
|
formatTime,
|
||||||
getBlockingClientName,
|
getBlockingClientName,
|
||||||
getFilterName,
|
|
||||||
getServiceName,
|
getServiceName,
|
||||||
processContent,
|
processContent,
|
||||||
} from '../../../helpers/helpers';
|
} from '../../../helpers/helpers';
|
||||||
@ -70,8 +70,7 @@ const Row = memo(({
|
|||||||
upstream,
|
upstream,
|
||||||
type,
|
type,
|
||||||
client_proto,
|
client_proto,
|
||||||
filterId,
|
rules,
|
||||||
rule,
|
|
||||||
originalResponse,
|
originalResponse,
|
||||||
status,
|
status,
|
||||||
service_name,
|
service_name,
|
||||||
@ -107,8 +106,6 @@ const Row = memo(({
|
|||||||
|
|
||||||
const sourceData = getSourceData(tracker);
|
const sourceData = getSourceData(tracker);
|
||||||
|
|
||||||
const filter = getFilterName(filters, whitelistFilters, filterId);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
confirmMessage,
|
confirmMessage,
|
||||||
buttonKey: blockingClientKey,
|
buttonKey: blockingClientKey,
|
||||||
@ -172,8 +169,8 @@ const Row = memo(({
|
|||||||
response_details: 'title',
|
response_details: 'title',
|
||||||
install_settings_dns: upstream,
|
install_settings_dns: upstream,
|
||||||
elapsed: formattedElapsedMs,
|
elapsed: formattedElapsedMs,
|
||||||
filter: rule ? filter : null,
|
rule_label: rules.length > 0
|
||||||
rule_label: rule,
|
&& getRulesToFilterList(rules, filters, whitelistFilters),
|
||||||
response_table_header: response?.join('\n'),
|
response_table_header: response?.join('\n'),
|
||||||
response_code: status,
|
response_code: status,
|
||||||
client_details: 'title',
|
client_details: 'title',
|
||||||
@ -235,8 +232,10 @@ Row.propTypes = {
|
|||||||
upstream: propTypes.string.isRequired,
|
upstream: propTypes.string.isRequired,
|
||||||
type: propTypes.string.isRequired,
|
type: propTypes.string.isRequired,
|
||||||
client_proto: propTypes.string.isRequired,
|
client_proto: propTypes.string.isRequired,
|
||||||
filterId: propTypes.number,
|
rules: propTypes.arrayOf(propTypes.shape({
|
||||||
rule: propTypes.string,
|
text: propTypes.string.isRequired,
|
||||||
|
filter_list_id: propTypes.number.isRequired,
|
||||||
|
})),
|
||||||
originalResponse: propTypes.array,
|
originalResponse: propTypes.array,
|
||||||
status: propTypes.string.isRequired,
|
status: propTypes.string.isRequired,
|
||||||
service_name: propTypes.string,
|
service_name: propTypes.string,
|
||||||
|
@ -428,3 +428,13 @@
|
|||||||
margin-right: 1px;
|
margin-right: 1px;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filteringRules__rule {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filteringRules__filter {
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: normal;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ import i18n from 'i18next';
|
|||||||
import uniqBy from 'lodash/uniqBy';
|
import uniqBy from 'lodash/uniqBy';
|
||||||
import ipaddr from 'ipaddr.js';
|
import ipaddr from 'ipaddr.js';
|
||||||
import queryString from 'query-string';
|
import queryString from 'query-string';
|
||||||
|
import React from 'react';
|
||||||
import { getTrackerData } from './trackers/trackers';
|
import { getTrackerData } from './trackers/trackers';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -68,6 +69,7 @@ export const normalizeLogs = (logs) => logs.map((log) => {
|
|||||||
time,
|
time,
|
||||||
filterId,
|
filterId,
|
||||||
rule,
|
rule,
|
||||||
|
rules,
|
||||||
service_name,
|
service_name,
|
||||||
original_answer,
|
original_answer,
|
||||||
upstream,
|
upstream,
|
||||||
@ -80,6 +82,15 @@ export const normalizeLogs = (logs) => logs.map((log) => {
|
|||||||
return `${type}: ${value} (ttl=${ttl})`;
|
return `${type}: ${value} (ttl=${ttl})`;
|
||||||
}) : []);
|
}) : []);
|
||||||
|
|
||||||
|
let newRules = rules;
|
||||||
|
/* TODO 'filterId' and 'rule' are deprecated, will be removed in 0.106 */
|
||||||
|
if (rule !== undefined && filterId !== undefined && rules !== undefined && rules.length === 0) {
|
||||||
|
newRules = {
|
||||||
|
filter_list_id: filterId,
|
||||||
|
text: rule,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
time,
|
time,
|
||||||
domain,
|
domain,
|
||||||
@ -88,8 +99,10 @@ export const normalizeLogs = (logs) => logs.map((log) => {
|
|||||||
reason,
|
reason,
|
||||||
client,
|
client,
|
||||||
client_proto,
|
client_proto,
|
||||||
|
/* TODO 'filterId' and 'rule' are deprecated, will be removed in 0.106 */
|
||||||
filterId,
|
filterId,
|
||||||
rule,
|
rule,
|
||||||
|
rules: newRules,
|
||||||
status,
|
status,
|
||||||
service_name,
|
service_name,
|
||||||
originalAnswer: original_answer,
|
originalAnswer: original_answer,
|
||||||
@ -726,6 +739,75 @@ export const getFilterName = (
|
|||||||
return resolveFilterName(filter);
|
return resolveFilterName(filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {array} rules
|
||||||
|
* @param {array} filters
|
||||||
|
* @param {array} whitelistFilters
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
export const getFilterNames = (rules, filters, whitelistFilters) => rules.map(
|
||||||
|
({ filter_list_id }) => getFilterName(filters, whitelistFilters, filter_list_id),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {array} rules
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
export const getRuleNames = (rules) => rules.map(({ text }) => text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {array} rules
|
||||||
|
* @param {array} filters
|
||||||
|
* @param {array} whitelistFilters
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
export const getFilterNameToRulesMap = (rules, filters, whitelistFilters) => rules.reduce(
|
||||||
|
(acc, { text, filter_list_id }) => {
|
||||||
|
const filterName = getFilterName(filters, whitelistFilters, filter_list_id);
|
||||||
|
|
||||||
|
acc[filterName] = (acc[filterName] || []).concat(text);
|
||||||
|
return acc;
|
||||||
|
}, {},
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {array} rules
|
||||||
|
* @param {array} filters
|
||||||
|
* @param {array} whitelistFilters
|
||||||
|
* @param {object} classes
|
||||||
|
* @returns {JSXElement}
|
||||||
|
*/
|
||||||
|
export const getRulesToFilterList = (rules, filters, whitelistFilters, classes = {
|
||||||
|
list: 'filteringRules',
|
||||||
|
rule: 'filteringRules__rule font-monospace',
|
||||||
|
filter: 'filteringRules__filter',
|
||||||
|
}) => {
|
||||||
|
const filterNameToRulesMap = getFilterNameToRulesMap(rules, filters, whitelistFilters);
|
||||||
|
|
||||||
|
return <dl className={classes.list}>
|
||||||
|
{Object.entries(filterNameToRulesMap).reduce(
|
||||||
|
(acc, [filterName, rulesArr]) => acc
|
||||||
|
.concat(rulesArr.map((rule, i) => <dd key={i} className={classes.rule}>{rule}</dd>))
|
||||||
|
.concat(<dt className={classes.filter} key={classes.filter}>{filterName}</dt>),
|
||||||
|
[],
|
||||||
|
)}
|
||||||
|
</dl>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {array} rules
|
||||||
|
* @param {array} filters
|
||||||
|
* @param {array} whitelistFilters
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const getRulesAndFilterNames = (rules, filters, whitelistFilters) => {
|
||||||
|
const filterNameToRulesMap = getFilterNameToRulesMap(rules, filters, whitelistFilters);
|
||||||
|
|
||||||
|
return Object.entries(filterNameToRulesMap).map(
|
||||||
|
([filterName, filterRules]) => filterRules.concat(filterName).join('\n'),
|
||||||
|
).join('\n\n');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ip {string}
|
* @param ip {string}
|
||||||
* @param gateway_ip {string}
|
* @param gateway_ip {string}
|
||||||
|
@ -31,7 +31,7 @@ const getFormattedWhois = (whois) => {
|
|||||||
* @param {object} info.whois_info
|
* @param {object} info.whois_info
|
||||||
* @param {boolean} [isDetailed]
|
* @param {boolean} [isDetailed]
|
||||||
* @param {boolean} [isLogs]
|
* @param {boolean} [isLogs]
|
||||||
* @returns {JSX.Element}
|
* @returns {JSXElement}
|
||||||
*/
|
*/
|
||||||
export const renderFormattedClientCell = (value, info, isDetailed = false, isLogs = false) => {
|
export const renderFormattedClientCell = (value, info, isDetailed = false, isLogs = false) => {
|
||||||
let whoisContainer = null;
|
let whoisContainer = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user