Translate dashboard to Vietnamese with i18n
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import ReactTable from 'react-table';
|
||||
import PropTypes from 'prop-types';
|
||||
import map from 'lodash/map';
|
||||
import { withNamespaces, Trans } from 'react-i18next';
|
||||
|
||||
import Card from '../ui/Card';
|
||||
import Cell from '../ui/Cell';
|
||||
@@ -29,7 +30,7 @@ class BlockedDomains extends Component {
|
||||
);
|
||||
},
|
||||
}, {
|
||||
Header: 'Requests count',
|
||||
Header: <Trans>Requests count</Trans>,
|
||||
accessor: 'domain',
|
||||
maxWidth: 190,
|
||||
Cell: ({ value }) => {
|
||||
@@ -48,15 +49,16 @@ class BlockedDomains extends Component {
|
||||
}];
|
||||
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
return (
|
||||
<Card title="Top blocked domains" subtitle="for the last 24 hours" bodyType="card-table" refresh={this.props.refreshButton}>
|
||||
<Card title={ t('Top blocked domains') } subtitle={ t('for the last 24 hours') } bodyType="card-table" refresh={this.props.refreshButton}>
|
||||
<ReactTable
|
||||
data={map(this.props.topBlockedDomains, (value, prop) => (
|
||||
{ ip: prop, domain: value }
|
||||
))}
|
||||
columns={this.columns}
|
||||
showPagination={false}
|
||||
noDataText="No domains found"
|
||||
noDataText={ t('No domains found') }
|
||||
minRows={6}
|
||||
className="-striped -highlight card-table-overflow stats__table"
|
||||
/>
|
||||
@@ -71,6 +73,7 @@ BlockedDomains.propTypes = {
|
||||
replacedSafebrowsing: PropTypes.number.isRequired,
|
||||
replacedParental: PropTypes.number.isRequired,
|
||||
refreshButton: PropTypes.node.isRequired,
|
||||
t: PropTypes.func,
|
||||
};
|
||||
|
||||
export default BlockedDomains;
|
||||
export default withNamespaces()(BlockedDomains);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import ReactTable from 'react-table';
|
||||
import PropTypes from 'prop-types';
|
||||
import map from 'lodash/map';
|
||||
import { Trans, withNamespaces } from 'react-i18next';
|
||||
|
||||
import Card from '../ui/Card';
|
||||
import Cell from '../ui/Cell';
|
||||
@@ -24,7 +25,7 @@ class Clients extends Component {
|
||||
accessor: 'ip',
|
||||
Cell: ({ value }) => (<div className="logs__row logs__row--overflow"><span className="logs__text" title={value}>{value}</span></div>),
|
||||
}, {
|
||||
Header: 'Requests count',
|
||||
Header: <Trans>Requests count</Trans>,
|
||||
accessor: 'count',
|
||||
Cell: ({ value }) => {
|
||||
const percent = getPercent(this.props.dnsQueries, value);
|
||||
@@ -37,15 +38,16 @@ class Clients extends Component {
|
||||
}];
|
||||
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
return (
|
||||
<Card title="Top clients" subtitle="for the last 24 hours" bodyType="card-table" refresh={this.props.refreshButton}>
|
||||
<Card title={ t('Top clients') } subtitle={ t('for the last 24 hours') } bodyType="card-table" refresh={this.props.refreshButton}>
|
||||
<ReactTable
|
||||
data={map(this.props.topClients, (value, prop) => (
|
||||
{ ip: prop, count: value }
|
||||
))}
|
||||
columns={this.columns}
|
||||
showPagination={false}
|
||||
noDataText="No clients found"
|
||||
noDataText={ t('No clients found') }
|
||||
minRows={6}
|
||||
className="-striped -highlight card-table-overflow"
|
||||
/>
|
||||
@@ -58,6 +60,7 @@ Clients.propTypes = {
|
||||
topClients: PropTypes.object.isRequired,
|
||||
dnsQueries: PropTypes.number.isRequired,
|
||||
refreshButton: PropTypes.node.isRequired,
|
||||
t: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Clients;
|
||||
export default withNamespaces()(Clients);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans, withNamespaces } from 'react-i18next';
|
||||
|
||||
import Card from '../ui/Card';
|
||||
import Tooltip from '../ui/Tooltip';
|
||||
@@ -7,13 +8,13 @@ import Tooltip from '../ui/Tooltip';
|
||||
const tooltipType = 'tooltip-custom--narrow';
|
||||
|
||||
const Counters = props => (
|
||||
<Card title="General statistics" subtitle="for the last 24 hours" bodyType="card-table" refresh={props.refreshButton}>
|
||||
<Card title={ props.t('General statistics') } subtitle={ props.t('for the last 24 hours') } bodyType="card-table" refresh={props.refreshButton}>
|
||||
<table className="table card-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
DNS Queries
|
||||
<Tooltip text="A number of DNS quieries processed for the last 24 hours" type={tooltipType} />
|
||||
<Trans>DNS Queries</Trans>
|
||||
<Tooltip text={ props.t('A number of DNS quieries processed for the last 24 hours') } type={tooltipType} />
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<span className="text-muted">
|
||||
@@ -23,8 +24,8 @@ const Counters = props => (
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Blocked by <a href="#filters">Filters</a>
|
||||
<Tooltip text="A number of DNS requests blocked by adblock filters and hosts blocklists" type={tooltipType} />
|
||||
<Trans>Blocked by</Trans> <a href="#filters"><Trans>Filters</Trans></a>
|
||||
<Tooltip text={ props.t('A number of DNS requests blocked by adblock filters and hosts blocklists') } type={tooltipType} />
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<span className="text-muted">
|
||||
@@ -34,8 +35,8 @@ const Counters = props => (
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Blocked malware/phishing
|
||||
<Tooltip text="A number of DNS requests blocked by the AdGuard browsing security module" type={tooltipType} />
|
||||
<Trans>Blocked malware/phishing</Trans>
|
||||
<Tooltip text={ props.t('A number of DNS requests blocked by the AdGuard browsing security module') } type={tooltipType} />
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<span className="text-muted">
|
||||
@@ -45,8 +46,8 @@ const Counters = props => (
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Blocked adult websites
|
||||
<Tooltip text="A number of adult websites blocked" type={tooltipType} />
|
||||
<Trans>Blocked adult websites</Trans>
|
||||
<Tooltip text={ props.t('A number of adult websites blocked') } type={tooltipType} />
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<span className="text-muted">
|
||||
@@ -56,8 +57,8 @@ const Counters = props => (
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Enforced safe search
|
||||
<Tooltip text="A number of DNS requests to search engines for which Safe Search was enforced" type={tooltipType} />
|
||||
<Trans>Enforced safe search</Trans>
|
||||
<Tooltip text={ props.t('A number of DNS requests to search engines for which Safe Search was enforced') } type={tooltipType} />
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<span className="text-muted">
|
||||
@@ -67,8 +68,8 @@ const Counters = props => (
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Average processing time
|
||||
<Tooltip text="Average time in milliseconds on processing a DNS request" type={tooltipType} />
|
||||
<Trans>Average processing time</Trans>
|
||||
<Tooltip text={ props.t('Average time in milliseconds on processing a DNS request') } type={tooltipType} />
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<span className="text-muted">
|
||||
@@ -89,6 +90,7 @@ Counters.propTypes = {
|
||||
replacedSafesearch: PropTypes.number.isRequired,
|
||||
avgProcessingTime: PropTypes.number.isRequired,
|
||||
refreshButton: PropTypes.node.isRequired,
|
||||
t: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Counters;
|
||||
export default withNamespaces()(Counters);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import ReactTable from 'react-table';
|
||||
import PropTypes from 'prop-types';
|
||||
import map from 'lodash/map';
|
||||
import { withNamespaces, Trans } from 'react-i18next';
|
||||
|
||||
import Card from '../ui/Card';
|
||||
import Cell from '../ui/Cell';
|
||||
@@ -38,7 +39,7 @@ class QueriedDomains extends Component {
|
||||
);
|
||||
},
|
||||
}, {
|
||||
Header: 'Requests count',
|
||||
Header: <Trans>Requests count</Trans>,
|
||||
accessor: 'count',
|
||||
maxWidth: 190,
|
||||
Cell: ({ value }) => {
|
||||
@@ -52,15 +53,16 @@ class QueriedDomains extends Component {
|
||||
}];
|
||||
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
return (
|
||||
<Card title="Top queried domains" subtitle="for the last 24 hours" bodyType="card-table" refresh={this.props.refreshButton}>
|
||||
<Card title={ t('Top queried domains') } subtitle={ t('for the last 24 hours') } bodyType="card-table" refresh={this.props.refreshButton}>
|
||||
<ReactTable
|
||||
data={map(this.props.topQueriedDomains, (value, prop) => (
|
||||
{ ip: prop, count: value }
|
||||
))}
|
||||
columns={this.columns}
|
||||
showPagination={false}
|
||||
noDataText="No domains found"
|
||||
noDataText={ t('No domains found') }
|
||||
minRows={6}
|
||||
className="-striped -highlight card-table-overflow stats__table"
|
||||
/>
|
||||
@@ -73,6 +75,7 @@ QueriedDomains.propTypes = {
|
||||
topQueriedDomains: PropTypes.object.isRequired,
|
||||
dnsQueries: PropTypes.number.isRequired,
|
||||
refreshButton: PropTypes.node.isRequired,
|
||||
t: PropTypes.func,
|
||||
};
|
||||
|
||||
export default QueriedDomains;
|
||||
export default withNamespaces()(QueriedDomains);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import Card from '../ui/Card';
|
||||
import Line from '../ui/Line';
|
||||
@@ -30,7 +31,7 @@ class Statistics extends Component {
|
||||
{dnsQueries}
|
||||
</div>
|
||||
<div className="card-title-stats">
|
||||
DNS Queries
|
||||
<Trans>DNS Queries</Trans>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-chart-bg">
|
||||
@@ -48,7 +49,7 @@ class Statistics extends Component {
|
||||
{getPercent(dnsQueries, blockedFiltering)}
|
||||
</div>
|
||||
<div className="card-title-stats">
|
||||
Blocked by <a href="#filters">Filters</a>
|
||||
<Trans>Blocked by</Trans> <a href="#filters"><Trans>Filters</Trans></a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-chart-bg">
|
||||
@@ -66,7 +67,7 @@ class Statistics extends Component {
|
||||
{getPercent(dnsQueries, replacedSafebrowsing)}
|
||||
</div>
|
||||
<div className="card-title-stats">
|
||||
Blocked malware/phishing
|
||||
<Trans>Blocked malware/phishing</Trans>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-chart-bg">
|
||||
@@ -84,7 +85,7 @@ class Statistics extends Component {
|
||||
{getPercent(dnsQueries, replacedParental)}
|
||||
</div>
|
||||
<div className="card-title-stats">
|
||||
Blocked adult websites
|
||||
<Trans>Blocked adult websites</Trans>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-chart-bg">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import 'whatwg-fetch';
|
||||
import { Trans, withNamespaces } from 'react-i18next';
|
||||
|
||||
import Statistics from './Statistics';
|
||||
import Counters from './Counters';
|
||||
@@ -30,25 +31,25 @@ class Dashboard extends Component {
|
||||
|
||||
return (
|
||||
<button type="button" className={`btn btn-sm mr-2 ${buttonClass}`} onClick={() => this.props.toggleProtection(protectionEnabled)}>
|
||||
{buttonText} protection
|
||||
<Trans>{buttonText} protection</Trans>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dashboard } = this.props;
|
||||
const { dashboard, t } = this.props;
|
||||
const dashboardProcessing =
|
||||
dashboard.processing ||
|
||||
dashboard.processingStats ||
|
||||
dashboard.processingStatsHistory ||
|
||||
dashboard.processingTopStats;
|
||||
|
||||
const refreshFullButton = <button type="button" className="btn btn-outline-primary btn-sm" onClick={() => this.getAllStats()}>Refresh statistics</button>;
|
||||
const refreshFullButton = <button type="button" className="btn btn-outline-primary btn-sm" onClick={() => this.getAllStats()}><Trans>Refresh statistics</Trans></button>;
|
||||
const refreshButton = <button type="button" className="btn btn-outline-primary btn-sm card-refresh" onClick={() => this.getAllStats()} />;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageTitle title="Dashboard">
|
||||
<PageTitle title={ t('Dashboard') }>
|
||||
<div className="page-title__actions">
|
||||
{this.getToggleFilteringButton()}
|
||||
{refreshFullButton}
|
||||
@@ -124,6 +125,7 @@ Dashboard.propTypes = {
|
||||
isCoreRunning: PropTypes.bool,
|
||||
getFiltering: PropTypes.func,
|
||||
toggleProtection: PropTypes.func,
|
||||
t: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Dashboard;
|
||||
export default withNamespaces()(Dashboard);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { NavLink } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import enhanceWithClickOutside from 'react-click-outside';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import { Trans } from 'react-i18next';
|
||||
import { REPOSITORY } from '../../helpers/constants';
|
||||
|
||||
class Menu extends Component {
|
||||
@@ -28,37 +28,37 @@ class Menu extends Component {
|
||||
<li className="nav-item border-bottom d-lg-none" onClick={this.toggleMenu}>
|
||||
<div className="nav-link nav-link--back">
|
||||
<svg className="nav-icon" fill="none" height="24" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m19 12h-14"/><path d="m12 19-7-7 7-7"/></svg>
|
||||
Back
|
||||
<Trans>Back</Trans>
|
||||
</div>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<NavLink to="/" exact={true} className="nav-link">
|
||||
<svg className="nav-icon" fill="none" height="24" stroke="#9aa0ac" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m3 9 9-7 9 7v11a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2-2z"/><path d="m9 22v-10h6v10"/></svg>
|
||||
Dashboard
|
||||
<Trans>Dashboard</Trans>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<NavLink to="/settings" className="nav-link">
|
||||
<svg className="nav-icon" fill="none" height="24" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="3"/><path d="m19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1 -2.83 0l-.06-.06a1.65 1.65 0 0 0 -1.82-.33 1.65 1.65 0 0 0 -1 1.51v.17a2 2 0 0 1 -2 2 2 2 0 0 1 -2-2v-.09a1.65 1.65 0 0 0 -1.08-1.51 1.65 1.65 0 0 0 -1.82.33l-.06.06a2 2 0 0 1 -2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0 -1.51-1h-.17a2 2 0 0 1 -2-2 2 2 0 0 1 2-2h.09a1.65 1.65 0 0 0 1.51-1.08 1.65 1.65 0 0 0 -.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33h.08a1.65 1.65 0 0 0 1-1.51v-.17a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0 -.33 1.82v.08a1.65 1.65 0 0 0 1.51 1h.17a2 2 0 0 1 2 2 2 2 0 0 1 -2 2h-.09a1.65 1.65 0 0 0 -1.51 1z"/></svg>
|
||||
Settings
|
||||
<Trans>Settings</Trans>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<NavLink to="/filters" className="nav-link">
|
||||
<svg className="nav-icon" fill="none" height="24" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m22 3h-20l8 9.46v6.54l4 2v-8.54z"/></svg>
|
||||
Filters
|
||||
<Trans>Filters</Trans>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<NavLink to="/logs" className="nav-link">
|
||||
<svg className="nav-icon" fill="none" height="24" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m14 2h-8a2 2 0 0 0 -2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-12z"/><path d="m14 2v6h6"/><path d="m16 13h-8"/><path d="m16 17h-8"/><path d="m10 9h-1-1"/></svg>
|
||||
Query Log
|
||||
<Trans>Query Log</Trans>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a href={`${REPOSITORY.URL}/wiki`} className="nav-link" target="_blank" rel="noopener noreferrer">
|
||||
<svg className="nav-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#66b574" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12" y2="17"></line></svg>
|
||||
FAQ
|
||||
<Trans>FAQ</Trans>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
export default function Version(props) {
|
||||
const { dnsVersion, dnsAddress, dnsPort } = props;
|
||||
return (
|
||||
<div className="nav-version">
|
||||
<div className="nav-version__text">
|
||||
version: <span className="nav-version__value">{dnsVersion}</span>
|
||||
<Trans>version</Trans>: <span className="nav-version__value">{dnsVersion}</span>
|
||||
</div>
|
||||
<div className="nav-version__text">
|
||||
address: <span className="nav-version__value">{dnsAddress}:{dnsPort}</span>
|
||||
<Trans>address</Trans>: <span className="nav-version__value">{dnsAddress}:{dnsPort}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import Menu from './Menu';
|
||||
import Version from './Version';
|
||||
@@ -44,7 +45,7 @@ class Header extends Component {
|
||||
</Link>
|
||||
{!dashboard.proccessing && dashboard.isCoreRunning &&
|
||||
<span className={badgeClass}>
|
||||
{dashboard.protectionEnabled ? 'ON' : 'OFF'}
|
||||
<Trans>{dashboard.protectionEnabled ? 'ON' : 'OFF'}</Trans>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Trans } from 'react-i18next';
|
||||
import { REPOSITORY } from '../../helpers/constants';
|
||||
|
||||
class Footer extends Component {
|
||||
@@ -20,13 +21,13 @@ class Footer extends Component {
|
||||
<div className="col-auto">
|
||||
<ul className="list-inline text-center mb-0">
|
||||
<li className="list-inline-item">
|
||||
<a href={REPOSITORY.URL} target="_blank" rel="noopener noreferrer">Homepage</a>
|
||||
<a href={REPOSITORY.URL} target="_blank" rel="noopener noreferrer"><Trans>Homepage</Trans></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="col-auto">
|
||||
<a href={`${REPOSITORY.URL}/issues/new`} className="btn btn-outline-primary btn-sm" target="_blank" rel="noopener noreferrer">
|
||||
Report an issue
|
||||
<Trans>Report an issue</Trans>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user