diff --git a/client/src/components/Dashboard/BlockedDomains.js b/client/src/components/Dashboard/BlockedDomains.js index 684bb611..423757a2 100644 --- a/client/src/components/Dashboard/BlockedDomains.js +++ b/client/src/components/Dashboard/BlockedDomains.js @@ -5,7 +5,9 @@ import map from 'lodash/map'; import Card from '../ui/Card'; import Cell from '../ui/Cell'; +import Popover from '../ui/Popover'; +import { getTrackerData } from '../../helpers/whotracksme'; import { getPercent } from '../../helpers/helpers'; import { STATUS_COLORS } from '../../helpers/constants'; @@ -13,7 +15,19 @@ class BlockedDomains extends Component { columns = [{ Header: 'IP', accessor: 'ip', - Cell: ({ value }) => (
{value}
), + Cell: (row) => { + const { value } = row; + const trackerData = getTrackerData(value); + + return ( +
+
+ {value} +
+ {trackerData && } +
+ ); + }, }, { Header: 'Requests count', accessor: 'domain', @@ -43,7 +57,7 @@ class BlockedDomains extends Component { showPagination={false} noDataText="No domains found" minRows={6} - className="-striped -highlight card-table-overflow" + className="-striped -highlight card-table-overflow stats__table" /> ); diff --git a/client/src/components/Dashboard/Dashboard.css b/client/src/components/Dashboard/Dashboard.css new file mode 100644 index 00000000..0f1e60f5 --- /dev/null +++ b/client/src/components/Dashboard/Dashboard.css @@ -0,0 +1,22 @@ +.stats__table .popover__body { + left: 0; + transform: none; +} + +.stats__table .popover__body:after { + left: 13px; +} + +.stats__table .rt-tr-group:first-child .popover__body, +.stats__table .rt-tr-group:nth-child(2) .popover__body { + top: calc(100% + 5px); + bottom: initial; + z-index: 1; +} + +.stats__table .rt-tr-group:first-child .popover__body:after, +.stats__table .rt-tr-group:nth-child(2) .popover__body:after { + top: -11px; + border-top: 6px solid transparent; + border-bottom: 6px solid #585965; +} diff --git a/client/src/components/Dashboard/QueriedDomains.js b/client/src/components/Dashboard/QueriedDomains.js index c1b630a4..0486e46f 100644 --- a/client/src/components/Dashboard/QueriedDomains.js +++ b/client/src/components/Dashboard/QueriedDomains.js @@ -5,7 +5,9 @@ import map from 'lodash/map'; import Card from '../ui/Card'; import Cell from '../ui/Cell'; +import Popover from '../ui/Popover'; +import { getTrackerData } from '../../helpers/whotracksme'; import { getPercent } from '../../helpers/helpers'; import { STATUS_COLORS } from '../../helpers/constants'; @@ -22,7 +24,19 @@ class QueriedDomains extends Component { columns = [{ Header: 'IP', accessor: 'ip', - Cell: ({ value }) => (
{value}
), + Cell: (row) => { + const { value } = row; + const trackerData = getTrackerData(value); + + return ( +
+
+ {value} +
+ {trackerData && } +
+ ); + }, }, { Header: 'Requests count', accessor: 'count', @@ -47,7 +61,7 @@ class QueriedDomains extends Component { showPagination={false} noDataText="No domains found" minRows={6} - className="-striped -highlight card-table-overflow" + className="-striped -highlight card-table-overflow stats__table" /> ); diff --git a/client/src/components/Dashboard/index.js b/client/src/components/Dashboard/index.js index 99fe8e5e..bf49b2a4 100644 --- a/client/src/components/Dashboard/index.js +++ b/client/src/components/Dashboard/index.js @@ -10,6 +10,7 @@ import BlockedDomains from './BlockedDomains'; import PageTitle from '../ui/PageTitle'; import Loading from '../ui/Loading'; +import './Dashboard.css'; class Dashboard extends Component { componentDidMount() { diff --git a/client/src/components/Logs/Logs.css b/client/src/components/Logs/Logs.css index a5f91760..d7df63bb 100644 --- a/client/src/components/Logs/Logs.css +++ b/client/src/components/Logs/Logs.css @@ -60,6 +60,18 @@ border-bottom: 6px solid #585965; } +.logs__table .rt-tr-group:first-child .popover__body { + top: calc(100% + 5px); + bottom: initial; + z-index: 1; +} + +.logs__table .rt-tr-group:first-child .popover__body:after { + top: -11px; + border-top: 6px solid transparent; + border-bottom: 6px solid #585965; +} + .logs__table .rt-thead.-filters input, .logs__table .rt-thead.-filters select { padding: 6px 7px; diff --git a/client/src/components/Logs/index.js b/client/src/components/Logs/index.js index dcc87f66..843ef2c9 100644 --- a/client/src/components/Logs/index.js +++ b/client/src/components/Logs/index.js @@ -6,10 +6,12 @@ import escapeRegExp from 'lodash/escapeRegExp'; import endsWith from 'lodash/endsWith'; import { formatTime } from '../../helpers/helpers'; +import { getTrackerData } from '../../helpers/whotracksme'; import PageTitle from '../ui/PageTitle'; import Card from '../ui/Card'; import Loading from '../ui/Loading'; import Tooltip from '../ui/Tooltip'; +import Popover from '../ui/Popover'; import './Logs.css'; const DOWNLOAD_LOG_FILENAME = 'dns-logs.txt'; @@ -91,12 +93,14 @@ class Logs extends Component { accessor: 'domain', Cell: (row) => { const response = row.value; + const trackerData = getTrackerData(response); return ( -
+
{response}
+ {trackerData && }
); }, diff --git a/client/src/components/ui/Popover.css b/client/src/components/ui/Popover.css new file mode 100644 index 00000000..fa52ba64 --- /dev/null +++ b/client/src/components/ui/Popover.css @@ -0,0 +1,86 @@ +.popover-wrap { + position: relative; + display: inline-block; + vertical-align: middle; +} + +.popover__trigger { + position: relative; + top: 3px; + margin: 0 8px; + cursor: pointer; +} + +.popover__trigger:after { + content: ""; + position: absolute; + top: -6px; + left: -3px; + width: 26px; + height: 24px; +} + +.popover__body { + content: ""; + display: flex; + position: absolute; + min-width: 275px; + bottom: calc(100% + 3px); + left: 50%; + padding: 10px 15px; + font-size: 0.8rem; + white-space: normal; + color: #fff; + background-color: #585965; + border-radius: 3px; + transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out; + transform: translateX(-50%); + visibility: hidden; + opacity: 0; +} + +.popover__body:after { + content: ""; + position: absolute; + bottom: -5px; + left: calc(50% - 6px); + width: 0; + height: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid #585965; +} + +.popover__trigger:hover + .popover__body, +.popover__body:hover { + visibility: visible; + opacity: 1; +} + +.popover__icon { + width: 20px; + height: 20px; + stroke: #9aa0ac; +} + +.popover__list-title { + margin-bottom: 3px; +} + +.popover__list-item { + margin-bottom: 2px; +} + +.popover__list-item:last-child { + margin-bottom: 0; +} + +.popover__link { + font-size: 0.7rem; + color: #66b586; +} + +.popover__link:hover, +.popover__link:focus { + color: #66b586; +} diff --git a/client/src/components/ui/Popover.js b/client/src/components/ui/Popover.js new file mode 100644 index 00000000..005775c8 --- /dev/null +++ b/client/src/components/ui/Popover.js @@ -0,0 +1,40 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import './Popover.css'; + +class Popover extends Component { + render() { + const { data } = this.props; + + return ( +
+
+ +
+
+
+
+ This domain belongs to a known tracker. +
+
+ Name: {data.name} +
+
+ Category: {data.category} +
+
+ More information on Whotracksme +
+
+
+
+ ); + } +} + +Popover.propTypes = { + data: PropTypes.object.isRequired, +}; + +export default Popover; diff --git a/client/src/components/ui/ReactTable.css b/client/src/components/ui/ReactTable.css index 79fa6421..bdcf3576 100644 --- a/client/src/components/ui/ReactTable.css +++ b/client/src/components/ui/ReactTable.css @@ -4,6 +4,10 @@ overflow: visible; } +.ReactTable .rt-tbody { + overflow: visible; +} + .rt-tr-group .red { background-color: #fff4f2; } diff --git a/client/src/components/ui/Tooltip.css b/client/src/components/ui/Tooltip.css index 0cff0e70..fd9df796 100644 --- a/client/src/components/ui/Tooltip.css +++ b/client/src/components/ui/Tooltip.css @@ -16,7 +16,7 @@ content: attr(data-tooltip); display: block; position: absolute; - bottom: calc(100% + 12px); + bottom: calc(100% + 10px); left: 50%; padding: 10px 15px; font-size: 0.85rem; @@ -32,7 +32,7 @@ .tooltip-custom:after { content: ""; position: relative; - top: -9px; + top: -7px; left: calc(50% - 6px); visibility: hidden; opacity: 0; diff --git a/client/src/components/ui/Tooltip.js b/client/src/components/ui/Tooltip.js index 3496a0d2..3f70fcef 100644 --- a/client/src/components/ui/Tooltip.js +++ b/client/src/components/ui/Tooltip.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import './Tooltip.css'; const Tooltip = props => ( -
+
); Tooltip.propTypes = { diff --git a/client/src/helpers/whotracksme.js b/client/src/helpers/whotracksme.js index 2df8a221..8d86a9c6 100644 --- a/client/src/helpers/whotracksme.js +++ b/client/src/helpers/whotracksme.js @@ -5,7 +5,7 @@ import trackersDb from './whotracksmedb.json'; @type {object} @property {string} id - tracker ID. @property {string} name - tracker name. - @property {number} age - tracker category. + @property {number} category - tracker category. */ /** @@ -22,9 +22,9 @@ export const getTrackerData = (domainName) => { const parts = domainName.split(/\./g).reverse(); let hostToCheck = ''; - // Check every subdomain except the TLD - for (let i = 1; i < parts.length; i += 1) { - hostToCheck = hostToCheck + (i > 0 ? '.' : '') + parts[i]; + // Check every subdomain + for (let i = 0; i < parts.length; i += 1) { + hostToCheck = parts[i] + (i > 0 ? '.' : '') + hostToCheck; const trackerId = trackersDb.trackerDomains[hostToCheck]; if (trackerId) {