Pull request: 3313 statistics settings UI
Closes #3313
Squashed commit of the following:
commit 6f2ff98a8282789e2dbb16694ca87a1f4cc8c076
Merge: 1221f02f f4dde3f2
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date: Wed Jul 14 15:53:18 2021 +0300
Merge branch 'master' into 3313-statistics
commit 1221f02f40628964febd22967d85d5185f87b08d
Author: Ildar Kamalov <ik@adguard.com>
Date: Wed Jul 14 15:23:09 2021 +0300
client: make client names clickable
commit 99770ec065e14ce2522a59820f9851d79001923c
Author: Ildar Kamalov <ik@adguard.com>
Date: Wed Jul 14 15:06:30 2021 +0300
client: decreasing interval confirm, disabled stats message
This commit is contained in:
parent
f4dde3f2c1
commit
ebade2b6ce
|
@ -112,6 +112,8 @@
|
||||||
"for_last_24_hours": "for the last 24 hours",
|
"for_last_24_hours": "for the last 24 hours",
|
||||||
"for_last_days": "for the last {{count}} day",
|
"for_last_days": "for the last {{count}} day",
|
||||||
"for_last_days_plural": "for the last {{count}} days",
|
"for_last_days_plural": "for the last {{count}} days",
|
||||||
|
"stats_disabled": "The statistics have been disabled. You can turn it on from the <0>settings page</0>.",
|
||||||
|
"stats_disabled_short": "The statistics have been disabled",
|
||||||
"no_domains_found": "No domains found",
|
"no_domains_found": "No domains found",
|
||||||
"requests_count": "Requests count",
|
"requests_count": "Requests count",
|
||||||
"top_blocked_domains": "Top blocked domains",
|
"top_blocked_domains": "Top blocked domains",
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { HashLink as Link } from 'react-router-hash-link';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import Statistics from './Statistics';
|
import Statistics from './Statistics';
|
||||||
import Counters from './Counters';
|
import Counters from './Counters';
|
||||||
import Clients from './Clients';
|
import Clients from './Clients';
|
||||||
import QueriedDomains from './QueriedDomains';
|
import QueriedDomains from './QueriedDomains';
|
||||||
import BlockedDomains from './BlockedDomains';
|
import BlockedDomains from './BlockedDomains';
|
||||||
|
import { SETTINGS_URLS } from '../../helpers/constants';
|
||||||
|
|
||||||
import PageTitle from '../ui/PageTitle';
|
import PageTitle from '../ui/PageTitle';
|
||||||
import Loading from '../ui/Loading';
|
import Loading from '../ui/Loading';
|
||||||
|
@ -34,6 +37,16 @@ const Dashboard = ({
|
||||||
getAllStats();
|
getAllStats();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const getSubtitle = () => {
|
||||||
|
if (stats.interval === 0) {
|
||||||
|
return t('stats_disabled_short');
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats.interval === 1
|
||||||
|
? t('for_last_24_hours')
|
||||||
|
: t('for_last_days', { count: stats.interval });
|
||||||
|
};
|
||||||
|
|
||||||
const buttonText = protectionEnabled ? 'disable_protection' : 'enable_protection';
|
const buttonText = protectionEnabled ? 'disable_protection' : 'enable_protection';
|
||||||
|
|
||||||
const buttonClass = classNames('btn btn-sm dashboard-title__button', {
|
const buttonClass = classNames('btn btn-sm dashboard-title__button', {
|
||||||
|
@ -52,14 +65,12 @@ const Dashboard = ({
|
||||||
</svg>
|
</svg>
|
||||||
</button>;
|
</button>;
|
||||||
|
|
||||||
const subtitle = stats.interval === 1
|
|
||||||
? t('for_last_24_hours')
|
|
||||||
: t('for_last_days', { count: stats.interval });
|
|
||||||
|
|
||||||
const statsProcessing = stats.processingStats
|
const statsProcessing = stats.processingStats
|
||||||
|| stats.processingGetConfig
|
|| stats.processingGetConfig
|
||||||
|| access.processing;
|
|| access.processing;
|
||||||
|
|
||||||
|
const subtitle = getSubtitle();
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<PageTitle title={t('dashboard')} containerClass="page-title--dashboard">
|
<PageTitle title={t('dashboard')} containerClass="page-title--dashboard">
|
||||||
<button
|
<button
|
||||||
|
@ -81,6 +92,20 @@ const Dashboard = ({
|
||||||
{statsProcessing && <Loading />}
|
{statsProcessing && <Loading />}
|
||||||
{!statsProcessing && <div className="row row-cards dashboard">
|
{!statsProcessing && <div className="row row-cards dashboard">
|
||||||
<div className="col-lg-12">
|
<div className="col-lg-12">
|
||||||
|
{stats.interval === 0 && (
|
||||||
|
<div className="alert alert-warning" role="alert">
|
||||||
|
<Trans components={[
|
||||||
|
<Link
|
||||||
|
to={`${SETTINGS_URLS.settings}#stats-config`}
|
||||||
|
key="0"
|
||||||
|
>
|
||||||
|
link
|
||||||
|
</Link>,
|
||||||
|
]}>
|
||||||
|
stats_disabled
|
||||||
|
</Trans>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<Statistics
|
<Statistics
|
||||||
interval={stats.interval}
|
interval={stats.interval}
|
||||||
dnsQueries={stats.dnsQueries}
|
dnsQueries={stats.dnsQueries}
|
||||||
|
|
|
@ -3,7 +3,9 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import propTypes from 'prop-types';
|
import propTypes from 'prop-types';
|
||||||
|
|
||||||
import { checkFiltered, getBlockingClientName } from '../../../helpers/helpers';
|
import { checkFiltered, getBlockingClientName } from '../../../helpers/helpers';
|
||||||
import { BLOCK_ACTIONS } from '../../../helpers/constants';
|
import { BLOCK_ACTIONS } from '../../../helpers/constants';
|
||||||
import { toggleBlocking, toggleBlockingForClient } from '../../../actions';
|
import { toggleBlocking, toggleBlockingForClient } from '../../../actions';
|
||||||
|
@ -192,12 +194,13 @@ const ClientCell = ({
|
||||||
{renderFormattedClientCell(client, clientInfo, isDetailed, true)}
|
{renderFormattedClientCell(client, clientInfo, isDetailed, true)}
|
||||||
</div>
|
</div>
|
||||||
{isDetailed && clientName && !whoisAvailable && (
|
{isDetailed && clientName && !whoisAvailable && (
|
||||||
<div
|
<Link
|
||||||
className="detailed-info d-none d-sm-block logs__text"
|
className="detailed-info d-none d-sm-block logs__text logs__text--link"
|
||||||
|
to={`logs?search=${encodeURIComponent(clientName)}`}
|
||||||
title={clientName}
|
title={clientName}
|
||||||
>
|
>
|
||||||
{clientName}
|
{clientName}
|
||||||
</div>
|
</Link>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{renderBlockingButton(isFiltered, domain)}
|
{renderBlockingButton(isFiltered, domain)}
|
||||||
|
|
|
@ -51,6 +51,15 @@
|
||||||
color: #888888;
|
color: #888888;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logs__text--link {
|
||||||
|
color: #467fcf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs__text--link:hover,
|
||||||
|
.logs__text--link:focus {
|
||||||
|
color: #295a9f;
|
||||||
|
}
|
||||||
|
|
||||||
.icon--selected {
|
.icon--selected {
|
||||||
background-color: var(--gray-f3);
|
background-color: var(--gray-f3);
|
||||||
border: solid 1px var(--gray-d8);
|
border: solid 1px var(--gray-d8);
|
||||||
|
|
|
@ -7,9 +7,13 @@ import Form from './Form';
|
||||||
|
|
||||||
class StatsConfig extends Component {
|
class StatsConfig extends Component {
|
||||||
handleFormSubmit = (values) => {
|
handleFormSubmit = (values) => {
|
||||||
const { t } = this.props;
|
const { t, interval: prevInterval } = this.props;
|
||||||
// eslint-disable-next-line no-alert
|
|
||||||
if (window.confirm(t('statistics_retention_confirm'))) {
|
if (values.interval < prevInterval) {
|
||||||
|
if (window.confirm(t('statistics_retention_confirm'))) {
|
||||||
|
this.props.setStatsConfig(values);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
this.props.setStatsConfig(values);
|
this.props.setStatsConfig(values);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -28,7 +32,11 @@ class StatsConfig extends Component {
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card title={t('statistics_configuration')} bodyType="card-body box-body--settings">
|
<Card
|
||||||
|
title={t('statistics_configuration')}
|
||||||
|
bodyType="card-body box-body--settings"
|
||||||
|
id="stats-config"
|
||||||
|
>
|
||||||
<div className="form">
|
<div className="form">
|
||||||
<Form
|
<Form
|
||||||
initialValues={{ interval }}
|
initialValues={{ interval }}
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const renderFormattedClientCell = (value, info, isDetailed = false, isLog
|
||||||
const whoisAvailable = whois_info && Object.keys(whois_info).length > 0;
|
const whoisAvailable = whois_info && Object.keys(whois_info).length > 0;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
const nameValue = <div className="logs__text logs__text--nowrap" title={`${name} (${value})`}>
|
const nameValue = <div className="logs__text logs__text--link logs__text--nowrap" title={`${name} (${value})`}>
|
||||||
{name} <small>{`(${value})`}</small>
|
{name} <small>{`(${value})`}</small>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue