diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index f3d893f2..a8164e1e 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -66,19 +66,21 @@ "disabled_protection": "Disabled protection", "refresh_statics": "Refresh statistics", "dns_query": "DNS Queries", - "blocked_by": "Blocked by Filters", + "blocked_by": "<0>Blocked by Filters", "stats_malware_phishing": "Blocked malware/phishing", "stats_adult": "Blocked adult websites", "stats_query_domain": "Top queried domains", "for_last_24_hours": "for the last 24 hours", - "for_last_days": "for the last {{value}} days", + "for_last_days": "for the last {{count}} day", + "for_last_days_plural": "for the last {{count}} days", "no_domains_found": "No domains found", "requests_count": "Requests count", "top_blocked_domains": "Top blocked domains", "top_clients": "Top clients", "no_clients_found": "No clients found", "general_statistics": "General statistics", - "number_of_dns_query_days": "A number of DNS queries processed for the last {{value}} days", + "number_of_dns_query_days": "A number of DNS queries processed for the last {{count}} day", + "number_of_dns_query_days_plural": "A number of DNS queries processed for the last {{count}} days", "number_of_dns_query_24_hours": "A number of DNS queries processed for the last 24 hours", "number_of_dns_query_blocked_24_hours": "A number of DNS requests blocked by adblock filters and hosts blocklists", "number_of_dns_query_blocked_24_hours_by_sec": "A number of DNS requests blocked by the AdGuard browsing security module", @@ -365,7 +367,8 @@ "stats_params": "Statistics configuration", "config_successfully_saved": "Configuration successfully saved", "interval_24_hour": "24 hours", - "interval_days": "{{value}} days", + "interval_days": "{{count}} day", + "interval_days_plural": "{{count}} days", "time_period": "Time period", "domain": "Domain", "answer": "Answer", diff --git a/client/src/api/Api.js b/client/src/api/Api.js index afd75ea5..de068563 100644 --- a/client/src/api/Api.js +++ b/client/src/api/Api.js @@ -22,7 +22,6 @@ export default class Api { } // Global methods - GLOBAL_RESTART = { path: 'restart', method: 'POST' }; GLOBAL_START = { path: 'start', method: 'POST' }; GLOBAL_STATUS = { path: 'status', method: 'GET' }; GLOBAL_STOP = { path: 'stop', method: 'POST' }; @@ -36,11 +35,6 @@ export default class Api { GLOBAL_DISABLE_PROTECTION = { path: 'disable_protection', method: 'POST' }; GLOBAL_UPDATE = { path: 'update', method: 'POST' }; - restartGlobalFiltering() { - const { path, method } = this.GLOBAL_RESTART; - return this.makeRequest(path, method); - } - startGlobalFiltering() { const { path, method } = this.GLOBAL_START; return this.makeRequest(path, method); diff --git a/client/src/components/Dashboard/BlockedDomains.js b/client/src/components/Dashboard/BlockedDomains.js index f88ca325..00c9b64e 100644 --- a/client/src/components/Dashboard/BlockedDomains.js +++ b/client/src/components/Dashboard/BlockedDomains.js @@ -1,76 +1,67 @@ -import React, { Component } from 'react'; +import React from 'react'; import ReactTable from 'react-table'; import PropTypes from 'prop-types'; import { withNamespaces, Trans } from 'react-i18next'; import Card from '../ui/Card'; import Cell from '../ui/Cell'; -import Popover from '../ui/Popover'; +import DomainCell from './DomainCell'; -import { getTrackerData } from '../../helpers/trackers/trackers'; import { getPercent } from '../../helpers/helpers'; import { STATUS_COLORS } from '../../helpers/constants'; -class BlockedDomains extends Component { - columns = [ - { - Header: domain, - accessor: 'domain', - Cell: (row) => { - const { value } = row; - const trackerData = getTrackerData(value); +const CountCell = totalBlocked => + function cell(row) { + const { value } = row; + const percent = getPercent(totalBlocked, value); - return ( -
-
- {value} -
- {trackerData && } -
- ); - }, - }, - { - Header: requests_count, - accessor: 'count', - maxWidth: 190, - Cell: ({ value }) => { - const { blockedFiltering, replacedSafebrowsing, replacedParental } = this.props; - const blocked = blockedFiltering + replacedSafebrowsing + replacedParental; - const percent = getPercent(blocked, value); + return ; + }; - return ; - }, - }, - ]; +const BlockedDomains = ({ + t, + refreshButton, + topBlockedDomains, + subtitle, + blockedFiltering, + replacedSafebrowsing, + replacedParental, +}) => { + const totalBlocked = blockedFiltering + replacedSafebrowsing + replacedParental; - render() { - const { - t, refreshButton, topBlockedDomains, subtitle, - } = this.props; - - return ( - - ({ - domain: item.name, - count: item.count, - }))} - columns={this.columns} - showPagination={false} - noDataText={t('no_domains_found')} - minRows={6} - className="-striped -highlight card-table-overflow stats__table" - /> - - ); - } -} + return ( + + ({ + domain, + count, + }))} + columns={[ + { + Header: domain, + accessor: 'domain', + Cell: DomainCell, + }, + { + Header: requests_count, + accessor: 'count', + maxWidth: 190, + Cell: CountCell(totalBlocked), + }, + ]} + showPagination={false} + noDataText={t('no_domains_found')} + minRows={6} + className="-striped -highlight card-table-overflow stats__table" + /> + + ); +}; BlockedDomains.propTypes = { topBlockedDomains: PropTypes.array.isRequired, diff --git a/client/src/components/Dashboard/Clients.js b/client/src/components/Dashboard/Clients.js index 3fcef21c..d2e9d4a9 100644 --- a/client/src/components/Dashboard/Clients.js +++ b/client/src/components/Dashboard/Clients.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React from 'react'; import ReactTable from 'react-table'; import PropTypes from 'prop-types'; import { Trans, withNamespaces } from 'react-i18next'; @@ -9,86 +9,84 @@ import Cell from '../ui/Cell'; import { getPercent, getClientName } from '../../helpers/helpers'; import { STATUS_COLORS } from '../../helpers/constants'; -class Clients extends Component { - getPercentColor = (percent) => { - if (percent > 50) { - return STATUS_COLORS.green; - } else if (percent > 10) { - return STATUS_COLORS.yellow; +const getClientsPercentColor = (percent) => { + if (percent > 50) { + return STATUS_COLORS.green; + } else if (percent > 10) { + return STATUS_COLORS.yellow; + } + return STATUS_COLORS.red; +}; + +const ipCell = (clients, autoClients) => + function cell(row) { + let client; + const { value } = row; + const clientName = getClientName(clients, value) || getClientName(autoClients, value); + + if (clientName) { + client = ( + + {clientName} ({value}) + + ); + } else { + client = value; } - return STATUS_COLORS.red; - }; - - columns = [ - { - Header: 'IP', - accessor: 'ip', - Cell: ({ value }) => { - const clientName = - getClientName(this.props.clients, value) || - getClientName(this.props.autoClients, value); - let client; - - if (clientName) { - client = ( - - {clientName} ({value}) - - ); - } else { - client = value; - } - - return ( -
- - {client} - -
- ); - }, - sortMethod: (a, b) => - parseInt(a.replace(/\./g, ''), 10) - parseInt(b.replace(/\./g, ''), 10), - }, - { - Header: requests_count, - accessor: 'count', - Cell: ({ value }) => { - const percent = getPercent(this.props.dnsQueries, value); - const percentColor = this.getPercentColor(percent); - - return ; - }, - }, - ]; - - render() { - const { - t, refreshButton, topClients, subtitle, - } = this.props; return ( - - ({ - ip: item.name, - count: item.count, - }))} - columns={this.columns} - showPagination={false} - noDataText={t('no_clients_found')} - minRows={6} - className="-striped -highlight card-table-overflow" - /> - +
+ + {client} + +
); - } -} + }; + +const countCell = dnsQueries => + function cell(row) { + const { value } = row; + const percent = getPercent(dnsQueries, value); + const percentColor = getClientsPercentColor(percent); + + return ; + }; + +const Clients = ({ + t, refreshButton, topClients, subtitle, clients, autoClients, dnsQueries, +}) => ( + + ({ + ip, + count, + }))} + columns={[ + { + Header: 'IP', + accessor: 'ip', + sortMethod: (a, b) => + parseInt(a.replace(/\./g, ''), 10) - parseInt(b.replace(/\./g, ''), 10), + Cell: ipCell(clients, autoClients), + }, + { + Header: requests_count, + accessor: 'count', + Cell: countCell(dnsQueries), + }, + ]} + showPagination={false} + noDataText={t('no_clients_found')} + minRows={6} + className="-striped -highlight card-table-overflow" + /> + +); Clients.propTypes = { topClients: PropTypes.array.isRequired, diff --git a/client/src/components/Dashboard/Counters.js b/client/src/components/Dashboard/Counters.js index 393c8d34..36ab78c6 100644 --- a/client/src/components/Dashboard/Counters.js +++ b/client/src/components/Dashboard/Counters.js @@ -25,7 +25,7 @@ const Counters = (props) => { const tooltipTitle = interval === 1 ? t('number_of_dns_query_24_hours') - : t('number_of_dns_query_days', { value: interval }); + : t('number_of_dns_query_days', { count: interval }); return ( { - - blocked_by - + link]}> + blocked_by + { + const trackerData = getTrackerData(value); + + return ( +
+
+ {value} +
+ {trackerData && } +
+ ); +}; + +DomainCell.propTypes = { + value: PropTypes.string.isRequired, +}; + +export default DomainCell; diff --git a/client/src/components/Dashboard/QueriedDomains.js b/client/src/components/Dashboard/QueriedDomains.js index 82fde13e..79f77c11 100644 --- a/client/src/components/Dashboard/QueriedDomains.js +++ b/client/src/components/Dashboard/QueriedDomains.js @@ -1,83 +1,67 @@ -import React, { Component } from 'react'; +import React from 'react'; import ReactTable from 'react-table'; import PropTypes from 'prop-types'; import { withNamespaces, Trans } from 'react-i18next'; import Card from '../ui/Card'; import Cell from '../ui/Cell'; -import Popover from '../ui/Popover'; +import DomainCell from './DomainCell'; -import { getTrackerData } from '../../helpers/trackers/trackers'; -import { getPercent } from '../../helpers/helpers'; import { STATUS_COLORS } from '../../helpers/constants'; +import { getPercent } from '../../helpers/helpers'; -class QueriedDomains extends Component { - getPercentColor = (percent) => { - if (percent > 10) { - return STATUS_COLORS.red; - } else if (percent > 5) { - return STATUS_COLORS.yellow; - } - return STATUS_COLORS.green; +const getQueriedPercentColor = (percent) => { + if (percent > 10) { + return STATUS_COLORS.red; + } else if (percent > 5) { + return STATUS_COLORS.yellow; + } + return STATUS_COLORS.green; +}; + +const countCell = dnsQueries => + function cell(row) { + const { value } = row; + const percent = getPercent(dnsQueries, value); + const percentColor = getQueriedPercentColor(percent); + + return ; }; - columns = [ - { - Header: domain, - accessor: 'domain', - Cell: (row) => { - const { value } = row; - const trackerData = getTrackerData(value); - - return ( -
-
- {value} -
- {trackerData && } -
- ); - }, - }, - { - Header: requests_count, - accessor: 'count', - maxWidth: 190, - Cell: ({ value }) => { - const percent = getPercent(this.props.dnsQueries, value); - const percentColor = this.getPercentColor(percent); - - return ; - }, - }, - ]; - - render() { - const { - t, refreshButton, topQueriedDomains, subtitle, - } = this.props; - return ( - - ({ - domain: item.name, - count: item.count, - }))} - columns={this.columns} - showPagination={false} - noDataText={t('no_domains_found')} - minRows={6} - className="-striped -highlight card-table-overflow stats__table" - /> - - ); - } -} +const QueriedDomains = ({ + t, refreshButton, topQueriedDomains, subtitle, dnsQueries, +}) => ( + + ({ + domain, + count, + }))} + columns={[ + { + Header: domain, + accessor: 'domain', + Cell: DomainCell, + }, + { + Header: requests_count, + accessor: 'count', + maxWidth: 190, + Cell: countCell(dnsQueries), + }, + ]} + showPagination={false} + noDataText={t('no_domains_found')} + minRows={6} + className="-striped -highlight card-table-overflow stats__table" + /> + +); QueriedDomains.propTypes = { topQueriedDomains: PropTypes.array.isRequired, diff --git a/client/src/components/Dashboard/Statistics.js b/client/src/components/Dashboard/Statistics.js index 8331add6..9d8358b7 100644 --- a/client/src/components/Dashboard/Statistics.js +++ b/client/src/components/Dashboard/Statistics.js @@ -1,130 +1,67 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import { Trans, withNamespaces } from 'react-i18next'; - -import Card from '../ui/Card'; -import Line from '../ui/Line'; +import { withNamespaces, Trans } from 'react-i18next'; +import StatsCard from './StatsCard'; import { getPercent, normalizeHistory } from '../../helpers/helpers'; -import { STATUS_COLORS } from '../../helpers/constants'; -class Statistics extends Component { - getNormalizedHistory = (data, interval, id) => [{ data: normalizeHistory(data, interval), id }]; +const getNormalizedHistory = (data, interval, id) => [ + { data: normalizeHistory(data, interval), id }, +]; - render() { - const { - interval, - dnsQueries, - blockedFiltering, - replacedSafebrowsing, - replacedParental, - numDnsQueries, - numBlockedFiltering, - numReplacedSafebrowsing, - numReplacedParental, - } = this.props; - - return ( -
-
- -
-
- {numDnsQueries} -
-
- dns_query -
-
-
- -
-
-
-
- -
-
- {numBlockedFiltering} -
-
- {getPercent(numDnsQueries, numBlockedFiltering)} -
- -
-
- -
-
-
-
- -
-
- {numReplacedSafebrowsing} -
-
- {getPercent(numDnsQueries, numReplacedSafebrowsing)} -
-
- stats_malware_phishing -
-
-
- -
-
-
-
- -
-
- {numReplacedParental} -
-
- {getPercent(numDnsQueries, numReplacedParental)} -
-
- stats_adult -
-
-
- -
-
-
-
- ); - } -} +const Statistics = ({ + interval, + dnsQueries, + blockedFiltering, + replacedSafebrowsing, + replacedParental, + numDnsQueries, + numBlockedFiltering, + numReplacedSafebrowsing, + numReplacedParental, +}) => ( +
+
+ dns_query} + color="blue" + /> +
+
+ link]}>blocked_by} + color="red" + /> +
+
+ stats_malware_phishing} + color="green" + /> +
+
+ stats_adult} + color="yellow" + /> +
+
+); Statistics.propTypes = { interval: PropTypes.number.isRequired, diff --git a/client/src/components/Dashboard/StatsCard.js b/client/src/components/Dashboard/StatsCard.js new file mode 100644 index 00000000..4d99d9b5 --- /dev/null +++ b/client/src/components/Dashboard/StatsCard.js @@ -0,0 +1,31 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { STATUS_COLORS } from '../../helpers/constants'; +import Card from '../ui/Card'; +import Line from '../ui/Line'; + +const StatsCard = ({ + total, lineData, percent, title, color, +}) => ( + +
+
{total}
+
{title}
+
+ {percent >= 0 && (
{percent}
)} +
+ +
+
+); + +StatsCard.propTypes = { + total: PropTypes.number.isRequired, + lineData: PropTypes.array.isRequired, + title: PropTypes.object.isRequired, + color: PropTypes.string.isRequired, + percent: PropTypes.number, +}; + +export default StatsCard; diff --git a/client/src/components/Dashboard/index.js b/client/src/components/Dashboard/index.js index 60fa90ac..1960a793 100644 --- a/client/src/components/Dashboard/index.js +++ b/client/src/components/Dashboard/index.js @@ -51,7 +51,7 @@ class Dashboard extends Component { const subtitle = stats.interval === 1 ? t('for_last_24_hours') - : t('for_last_days', { value: stats.interval }); + : t('for_last_days', { count: stats.interval }); const refreshFullButton = (