Files
AdGuardHome/client/src/components/Logs/Cells/DomainCell.js
Artem Baskal 10f67bd383 + client, querylog: Add blocked service filter support
Close #2124

Squashed commit of the following:

commit 574726e88e4fe7df745dfc964706e1e26f8da59f
Merge: 3bc770fb dc61744d
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 23 19:32:38 2020 +0300

    Merge branch 'master' into feature/2124

commit 3bc770fba6d06bbd965ee181aed7b0a050175f58
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 23 11:22:07 2020 +0300

    minor

commit 90c0d739d1bd09dbcf5f27ff9e6c3f761bf81686
Merge: 5d1f2642 1d36abd1
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 23 11:17:24 2020 +0300

    Merge branch 'master' into feature/2124

commit 5d1f264212686ac7ecab30401b4f0e3c020dbee9
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 17:23:08 2020 +0300

    Display elapsed if there is no service_name in blocked service

commit af86cedc31d566238764e02c5c8e465fa41292c6
Merge: b61976a7 756f97ed
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 16:55:40 2020 +0300

    Merge branch 'master' into feature/2124

commit b61976a7f811e1d01327cad8b0925bd110c6e135
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 16:52:48 2020 +0300

    Rename params to blocked_services, update service name display on client

commit d5b8e5f7b2c4a3d6701cf8845d31b28f55c6a808
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 15:59:46 2020 +0300

    Update docs, return global blocked status

commit adc9a294f76070dea2d845155814c21c52fc6c7f
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 15:24:34 2020 +0300

    + querylog: Extract filteringStatusBlockedService

commit ee8c1dce0d7520be0d0fcfe6f798dd11f13c9262
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 13:54:16 2020 +0300

    + client: Add blocked service filter support
2020-09-23 19:47:02 +03:00

119 lines
4.3 KiB
JavaScript

import React from 'react';
import { useSelector } from 'react-redux';
import classNames from 'classnames';
import propTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import {
DEFAULT_SHORT_DATE_FORMAT_OPTIONS,
LONG_TIME_FORMAT,
SCHEME_TO_PROTOCOL_MAP,
} from '../../../helpers/constants';
import { captitalizeWords, formatDateTime, formatTime } from '../../../helpers/helpers';
import { getSourceData } from '../../../helpers/trackers/trackers';
import IconTooltip from './IconTooltip';
const DomainCell = ({
answer_dnssec,
client_proto,
domain,
time,
tracker,
type,
}) => {
const { t } = useTranslation();
const dnssec_enabled = useSelector((state) => state.dnsConfig.dnssec_enabled);
const isDetailed = useSelector((state) => state.queryLogs.isDetailed);
const hasTracker = !!tracker;
const lockIconClass = classNames('icons icon--24 d-none d-sm-block', {
'icon--green': answer_dnssec,
'icon--disabled': !answer_dnssec,
'my-3': isDetailed,
});
const privacyIconClass = classNames('icons mx-2 icon--24 d-none d-sm-block', {
'icon--green': hasTracker,
'icon--disabled': !hasTracker,
'my-3': isDetailed,
});
const protocol = t(SCHEME_TO_PROTOCOL_MAP[client_proto]) || '';
const ip = type ? `${t('type_table_header')}: ${type}` : '';
const requestDetailsObj = {
time_table_header: formatTime(time, LONG_TIME_FORMAT),
date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS),
domain,
type_table_header: type,
protocol,
};
const sourceData = getSourceData(tracker);
const knownTrackerDataObj = {
name_table_header: tracker?.name,
category_label: hasTracker && captitalizeWords(tracker.category),
source_label: sourceData
&& <a href={sourceData.url} target="_blank" rel="noopener noreferrer"
className="link--green">{sourceData.name}</a>,
};
const renderGrid = (content, idx) => {
const preparedContent = typeof content === 'string' ? t(content) : content;
const className = classNames('text-truncate o-hidden', {
'overflow-break': preparedContent.length > 100,
});
return <div key={idx} className={className}>{preparedContent}</div>;
};
const getGrid = (contentObj, title, className) => [
<div key={title} className={classNames('pb-2 grid--title', className)}>{t(title)}</div>,
<div key={`${title}-1`}
className="grid grid--limited">{React.Children.map(Object.entries(contentObj), renderGrid)}</div>,
];
const requestDetails = getGrid(requestDetailsObj, 'request_details');
const renderContent = hasTracker ? requestDetails.concat(getGrid(knownTrackerDataObj, 'known_tracker', 'pt-4')) : requestDetails;
const valueClass = classNames('w-100 text-truncate', {
'px-2 d-flex justify-content-center flex-column': isDetailed,
});
const details = [ip, protocol].filter(Boolean)
.join(', ');
return <div className="d-flex o-hidden logs__cell logs__cell logs__cell--domain" role="gridcell">
{dnssec_enabled && <IconTooltip
className={lockIconClass}
tooltipClass='py-4 px-5 pb-45'
canShowTooltip={!!answer_dnssec}
xlinkHref='lock'
columnClass='w-100'
content='validated_with_dnssec'
placement='bottom'
/>}
<IconTooltip className={privacyIconClass} tooltipClass='pt-4 pb-5 px-5 mw-75'
xlinkHref='privacy' contentItemClass='key-colon' renderContent={renderContent}
place='bottom' />
<div className={valueClass}>
<div className="text-truncate" title={domain}>{domain}</div>
{details && isDetailed
&& <div className="detailed-info d-none d-sm-block text-truncate"
title={details}>{details}</div>}
</div>
</div>;
};
DomainCell.propTypes = {
answer_dnssec: propTypes.bool.isRequired,
client_proto: propTypes.string.isRequired,
domain: propTypes.string.isRequired,
time: propTypes.string.isRequired,
type: propTypes.string.isRequired,
tracker: propTypes.object,
};
export default DomainCell;