From e46db985e83b5637131d6aded0594a7b30cddf69 Mon Sep 17 00:00:00 2001 From: Artem Baskal Date: Wed, 15 Jul 2020 20:55:13 +0300 Subject: [PATCH] - client: Fix query logs UI issues Close #1828 Squashed commit of the following: commit bf96b9f2cc99a94a1289c47b04cde136cf0c9f37 Author: ArtemBaskal Date: Wed Jul 15 20:44:22 2020 +0300 Remove field domain from response tooltip commit bba35fdbed6d1e2e532c8effaf2da69de3f2c078 Author: ArtemBaskal Date: Wed Jul 15 20:29:24 2020 +0300 Unify mobile modal commit 5ee2da41594497fd64eadf0fd64c24afdad94e44 Author: ArtemBaskal Date: Wed Jul 15 19:02:47 2020 +0300 Delete unnecessary comment commit ac3a3f13009ad508ddd7eb31aadf7e590a5c2829 Author: ArtemBaskal Date: Wed Jul 15 18:59:44 2020 +0300 minor commit 4b1969a53ce2fcfc859c228b27816459bd8bd1d0 Author: ArtemBaskal Date: Wed Jul 15 18:56:51 2020 +0300 Fix safari mediaQuery change listener issue commit d85de5c4e90d2460632e593cffe3ceea3137e92c Author: ArtemBaskal Date: Wed Jul 15 18:10:30 2020 +0300 Fix logs input search markup (for different locales) commit 6d704399c5379dfda663503b3a5b1d12a92732b2 Author: ArtemBaskal Date: Wed Jul 15 16:05:35 2020 +0300 Fix whois_info markup, fix domain name overflow commit 4c900f60a9c6b71b427d968177252eb168c424c0 Merge: a3955c98 38366ba8 Author: ArtemBaskal Date: Wed Jul 15 13:42:43 2020 +0300 Merge branch 'master' into fix/1828 commit a3955c989a939866c6772b147547344b3f8769c4 Merge: c91c41cb 2759d81a Author: ArtemBaskal Date: Mon Jul 13 15:14:47 2020 +0300 Merge branch 'master' into fix/1828 commit c91c41cbc5f616e0af1092424e42b909d2f43f7c Author: ArtemBaskal Date: Mon Jul 13 13:48:54 2020 +0300 Fix cell overflow commit 19e1d31a40f2e1bb1189a85b72507bcc364d4e0c Merge: af31f48c a33164bf Author: ArtemBaskal Date: Mon Jul 13 12:36:44 2020 +0300 Merge branch 'master' into fix/1828 commit af31f48c4d2699ebfbd2034711c51499b42e40f5 Author: ArtemBaskal Date: Mon Jul 13 10:45:57 2020 +0300 minor commit d9507c5f3f5758e587766ae0fa45f1b9ad703ccf Author: ArtemBaskal Date: Fri Jul 10 18:34:22 2020 +0300 - client: Fix query logs UI issues --- client/src/components/Dashboard/Clients.js | 2 +- client/src/components/Dashboard/DomainCell.js | 2 +- .../components/Logs/Cells/getClientCell.js | 6 +- .../components/Logs/Cells/getResponseCell.js | 14 ++-- client/src/components/Logs/Filters/Form.js | 26 ++++---- client/src/components/Logs/Logs.css | 64 ++++++------------- client/src/components/Logs/Table.js | 58 ++++++----------- client/src/components/Logs/index.js | 29 +++++++-- client/src/helpers/formatClientCell.js | 12 ++-- client/src/helpers/helpers.js | 4 +- 10 files changed, 98 insertions(+), 119 deletions(-) diff --git a/client/src/components/Dashboard/Clients.js b/client/src/components/Dashboard/Clients.js index fc129b93..ac8771e5 100644 --- a/client/src/components/Dashboard/Clients.js +++ b/client/src/components/Dashboard/Clients.js @@ -62,7 +62,7 @@ const clientCell = (t, toggleClientStatus, processing, disallowedClients) => fun return ( <>
- {formatClientCell(row, t)} + {formatClientCell(row, true)}
{ipMatchListStatus !== IP_MATCH_LIST_STATUS.CIDR && renderBlockingButton(ipMatchListStatus, value, toggleClientStatus, processing)} diff --git a/client/src/components/Dashboard/DomainCell.js b/client/src/components/Dashboard/DomainCell.js index 76bb0877..c613c268 100644 --- a/client/src/components/Dashboard/DomainCell.js +++ b/client/src/components/Dashboard/DomainCell.js @@ -9,7 +9,7 @@ const DomainCell = ({ value }) => { return (
-
+
{value}
{trackerData && } diff --git a/client/src/components/Logs/Cells/getClientCell.js b/client/src/components/Logs/Cells/getClientCell.js index 2ebca672..00d5536c 100644 --- a/client/src/components/Logs/Cells/getClientCell.js +++ b/client/src/components/Logs/Cells/getClientCell.js @@ -33,7 +33,7 @@ const getClientCell = ({ const isFiltered = checkFiltered(reason); const nameClass = classNames('w-90 o-hidden d-flex flex-column', { - 'mt-2': isDetailed && !name, + 'mt-2': isDetailed && !name && !whois_info, 'white-space--nowrap': isDetailed, }); @@ -80,9 +80,9 @@ const getClientCell = ({ })}
-
{formatClientCell(row, t, isDetailed)}
+
{formatClientCell(row, isDetailed)}
{isDetailed && name - &&
{name}
}
{renderBlockingButton(isFiltered, domain)} diff --git a/client/src/components/Logs/Cells/getResponseCell.js b/client/src/components/Logs/Cells/getResponseCell.js index fcc2e5a0..6690c0f6 100644 --- a/client/src/components/Logs/Cells/getResponseCell.js +++ b/client/src/components/Logs/Cells/getResponseCell.js @@ -9,8 +9,7 @@ import getHintElement from './getHintElement'; const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => { const { - reason, filterId, rule, status, upstream, elapsedMs, - domain, response, originalResponse, + reason, filterId, rule, status, upstream, elapsedMs, response, originalResponse, } = row.original; const { filters, whitelistFilters } = filtering; @@ -41,7 +40,6 @@ const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => { const FILTERED_STATUS_TO_FIELDS_MAP = { [FILTERED_STATUS.NOT_FILTERED_NOT_FOUND]: { - domain, encryption_status: boldStatusLabel, install_settings_dns: upstream, elapsed: formattedElapsedMs, @@ -49,7 +47,6 @@ const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => { response_table_header: renderResponses(response), }, [FILTERED_STATUS.FILTERED_BLOCKED_SERVICE]: { - domain, encryption_status: boldStatusLabel, install_settings_dns: upstream, elapsed: formattedElapsedMs, @@ -59,7 +56,6 @@ const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => { original_response: renderResponses(originalResponse), }, [FILTERED_STATUS.NOT_FILTERED_WHITE_LIST]: { - domain, encryption_status: boldStatusLabel, install_settings_dns: upstream, elapsed: formattedElapsedMs, @@ -68,21 +64,19 @@ const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => { response_code: status, }, [FILTERED_STATUS.NOT_FILTERED_WHITE_LIST]: { - domain, encryption_status: boldStatusLabel, filter, rule_label: rule, response_code: status, }, [FILTERED_STATUS.FILTERED_SAFE_SEARCH]: { - domain, encryption_status: boldStatusLabel, install_settings_dns: upstream, elapsed: formattedElapsedMs, response_code: status, + response_table_header: renderResponses(response), }, [FILTERED_STATUS.FILTERED_BLACK_LIST]: { - domain, encryption_status: boldStatusLabel, filter, rule_label: rule, @@ -93,7 +87,7 @@ const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => { }, }; - const fields = FILTERED_STATUS_TO_FIELDS_MAP[reason] + const content = FILTERED_STATUS_TO_FIELDS_MAP[reason] ? Object.entries(FILTERED_STATUS_TO_FIELDS_MAP[reason]) : Object.entries(FILTERED_STATUS_TO_FIELDS_MAP.NotFilteredNotFound); @@ -108,7 +102,7 @@ const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => { contentItemClass: 'text-truncate key-colon o-hidden', xlinkHref: 'question', title: 'response_details', - content: fields, + content, placement: 'bottom', })}
diff --git a/client/src/components/Logs/Filters/Form.js b/client/src/components/Logs/Filters/Form.js index 42145c64..d70153c1 100644 --- a/client/src/components/Logs/Filters/Form.js +++ b/client/src/components/Logs/Filters/Form.js @@ -144,18 +144,20 @@ const Form = (props) => { e.preventDefault(); }} > - +
+ +
.-loading-inner { top: 10rem !important; bottom: initial !important; diff --git a/client/src/components/Logs/Table.js b/client/src/components/Logs/Table.js index 131db854..fcf8daa4 100644 --- a/client/src/components/Logs/Table.js +++ b/client/src/components/Logs/Table.js @@ -25,7 +25,7 @@ import { formatDateTime, formatElapsedMs, formatTime, - + processContent, } from '../../helpers/helpers'; import Loading from '../ui/Loading'; import { getSourceData } from '../../helpers/trackers/trackers'; @@ -302,6 +302,7 @@ const Table = (props) => { filterId, rule, originalResponse, + status, } = rowInfo.original; const hasTracker = !!tracker; @@ -328,17 +329,20 @@ const Table = (props) => { }; const isBlockedByResponse = originalResponse.length > 0 && isBlocked; - const status = t(isBlockedByResponse ? 'blocked_by_cname_or_ip' : FILTERED_STATUS_TO_META_MAP[reason]?.label || reason); - const statusBlocked =
{status}
; + const requestStatus = t(isBlockedByResponse ? 'blocked_by_cname_or_ip' : FILTERED_STATUS_TO_META_MAP[reason]?.label || reason); const protocol = t(SCHEME_TO_PROTOCOL_MAP[client_proto]) || ''; const sourceData = getSourceData(tracker); + const { filters, whitelistFilters } = filtering; + const filter = getFilterName(filters, whitelistFilters, filterId, t); + const detailedData = { time_table_header: formatTime(time, LONG_TIME_FORMAT), date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS), - encryption_status: status, + encryption_status: isBlocked + ?
{requestStatus}
: requestStatus, domain, type_table_header: type, protocol, @@ -346,12 +350,19 @@ const Table = (props) => { table_name: tracker?.name, category_label: hasTracker && captitalizeWords(tracker.category), tracker_source: hasTracker && sourceData - && {sourceData.name}, + && {sourceData.name} + , response_details: 'title', install_settings_dns: upstream, elapsed: formattedElapsedMs, + filter: isBlocked ? filter : null, + rule_label: rule, response_table_header: response?.join('\n'), + response_code: status, client_details: 'title', ip_address: client, name: info?.name, @@ -360,41 +371,14 @@ const Table = (props) => { network, source_label: source, validated_with_dnssec: dnssec_enabled ? Boolean(answer_dnssec) : false, - [buttonType]:
{t(buttonType)}
, - }; - - const { filters, whitelistFilters } = filtering; - - const filter = getFilterName(filters, whitelistFilters, filterId, t); - - const detailedDataBlocked = { - time_table_header: formatTime(time, LONG_TIME_FORMAT), - date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS), - encryption_status: statusBlocked, - domain, - type_table_header: type, - protocol, - known_tracker: 'title', - table_name: tracker?.name, - category_label: hasTracker && captitalizeWords(tracker.category), - source_label: hasTracker && sourceData - && {sourceData.name}, - response_details: 'title', - install_settings_dns: upstream, - elapsed: formattedElapsedMs, - filter, - rule_label: rule, - response_table_header: response?.join('\n'), original_response: originalResponse?.join('\n'), [buttonType]:
{t(buttonType)}
, + className={classNames('title--border text-center', { + 'bg--danger': isBlocked, + })}>{t(buttonType)}
, }; - const detailedDataCurrent = isBlocked ? detailedDataBlocked : detailedData; - - setDetailedDataCurrent(detailedDataCurrent); + setDetailedDataCurrent(processContent(detailedData)); setButtonType(buttonType); setModalOpened(true); } diff --git a/client/src/components/Logs/index.js b/client/src/components/Logs/index.js index b328e34e..f889fead 100644 --- a/client/src/components/Logs/index.js +++ b/client/src/components/Logs/index.js @@ -5,6 +5,7 @@ import Modal from 'react-modal'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import queryString from 'query-string'; +import classNames from 'classnames'; import { BLOCK_ACTIONS, TABLE_DEFAULT_PAGE_SIZE, @@ -27,7 +28,7 @@ import { import { addSuccessToast } from '../../actions/toasts'; import './Logs.css'; -export const processContent = (data, buttonType) => Object.entries(data) +const processContent = (data, buttonType) => Object.entries(data) .map(([key, value]) => { if (!value) { return null; @@ -49,7 +50,9 @@ export const processContent = (data, buttonType) => Object.entries(data) return isHidden ? null :
+ className={classNames(`key__${key}`, keyClass, { + 'font-weight-bold': isBoolean && value === true, + })}> {isButton ? value : key}
@@ -133,7 +136,16 @@ const Logs = (props) => { }; useEffect(() => { - mediaQuery.addEventListener('change', mediaQueryHandler); + try { + mediaQuery.addEventListener('change', mediaQueryHandler); + } catch (e1) { + try { + // Safari 13.1 do not support mediaQuery.addEventListener('change', handler) + mediaQuery.addListener(mediaQueryHandler); + } catch (e2) { + console.error(e2); + } + } (async () => { setIsLoading(true); @@ -153,7 +165,16 @@ const Logs = (props) => { })(); return () => { - mediaQuery.removeEventListener('change', mediaQueryHandler); + try { + mediaQuery.removeEventListener('change', mediaQueryHandler); + } catch (e1) { + try { + mediaQuery.removeListener(mediaQueryHandler); + } catch (e2) { + console.error(e2); + } + } + dispatch(resetFilteredLogs()); }; }, []); diff --git a/client/src/helpers/formatClientCell.js b/client/src/helpers/formatClientCell.js index 05baff38..3fc8e55d 100644 --- a/client/src/helpers/formatClientCell.js +++ b/client/src/helpers/formatClientCell.js @@ -2,14 +2,14 @@ import React from 'react'; import { normalizeWhois } from './helpers'; import { WHOIS_ICONS } from './constants'; -const getFormattedWhois = (whois, t) => { +const getFormattedWhois = (whois) => { const whoisInfo = normalizeWhois(whois); return ( Object.keys(whoisInfo) .map((key) => { const icon = WHOIS_ICONS[key]; return ( - + {icon && ( <> @@ -24,7 +24,7 @@ const getFormattedWhois = (whois, t) => { ); }; -export const formatClientCell = (row, t, isDetailed = false) => { +export const formatClientCell = (row, isDetailed = false) => { const { value, original: { info } } = row; let whoisContainer = ''; let nameContainer = value; @@ -33,7 +33,7 @@ export const formatClientCell = (row, t, isDetailed = false) => { const { name, whois_info } = info; if (name) { - nameContainer = isDetailed + nameContainer = !whois_info && isDetailed ? {value} :
{name} @@ -42,10 +42,10 @@ export const formatClientCell = (row, t, isDetailed = false) => {
; } - if (whois_info) { + if (whois_info && isDetailed) { whoisContainer = (
- {getFormattedWhois(whois_info, t)} + {getFormattedWhois(whois_info)}
); } diff --git a/client/src/helpers/helpers.js b/client/src/helpers/helpers.js index a6426ba5..bd246609 100644 --- a/client/src/helpers/helpers.js +++ b/client/src/helpers/helpers.js @@ -318,7 +318,8 @@ export const splitByNewLine = (text) => text.split('\n') * @returns {string} */ export const trimMultilineString = (text) => splitByNewLine(text) - .map((line) => line.trim()).join('\n'); + .map((line) => line.trim()) + .join('\n'); /** * @param {string} text @@ -636,7 +637,6 @@ export const getLogsUrlParams = (search, response_status) => `?${queryString.str response_status, })}`; - export const processContent = (content) => (Array.isArray(content) ? content.filter(([, value]) => value) .flat() : content);