Complete translate client to Vietnamese

This commit is contained in:
Hoàng Rio
2018-10-26 09:44:23 +07:00
parent bfb7a252ad
commit 4590564fea
6 changed files with 132 additions and 54 deletions

View File

@@ -1,8 +1,9 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Trans, withNamespaces } from 'react-i18next';
import Card from '../ui/Card';
export default class UserRules extends Component {
class UserRules extends Component {
handleChange = (e) => {
const { value } = e.currentTarget;
this.props.handleRulesChange(value);
@@ -14,10 +15,11 @@ export default class UserRules extends Component {
};
render() {
const { t } = this.props;
return (
<Card
title="Custom filtering rules"
subtitle="Enter one rule on a line. You can use either adblock rules or hosts files syntax."
title={ t('Custom filtering rules') }
subtitle={ t('Enter one rule on a line. You can use either adblock rules or hosts files syntax.') }
>
<form onSubmit={this.handleSubmit}>
<textarea className="form-control form-control--textarea-large" value={this.props.userRules} onChange={this.handleChange} />
@@ -27,31 +29,28 @@ export default class UserRules extends Component {
type="submit"
onClick={this.handleSubmit}
>
Apply
<Trans>Apply</Trans>
</button>
</div>
</form>
<hr/>
<div className="list leading-loose">
Examples:
<Trans>Examples</Trans>:
<ol className="leading-loose">
<li>
<code>||example.org^</code> - block access to the example.org domain
and all its subdomains
<code>||example.org^</code> - { t('block access to the example.org domain and all its subdomains') }
</li>
<li>
<code> @@||example.org^</code> - unblock access to the example.org
domain and all its subdomains
<code> @@||example.org^</code> - { t('unblock access to the example.org domain and all its subdomains') }
</li>
<li>
<code>127.0.0.1 example.org</code> - AdGuard Home will now return
127.0.0.1 address for the example.org domain (but not its subdomains).
<code>127.0.0.1 example.org</code> - { t('AdGuard Home will now return 127.0.0.1 address for the example.org domain (but not its subdomains).') }
</li>
<li>
<code>! Here goes a comment</code> - just a comment
<code>{ t('! Here goes a comment') }</code> - { t('just a comment') }
</li>
<li>
<code># Also a comment</code> - just a comment
<code>{ t('# Also a comment') }</code> - { t('just a comment') }
</li>
</ol>
</div>
@@ -64,4 +63,7 @@ UserRules.propTypes = {
userRules: PropTypes.string,
handleRulesChange: PropTypes.func,
handleRulesSubmit: PropTypes.func,
t: PropTypes.func,
};
export default withNamespaces()(UserRules);

View File

@@ -1,6 +1,7 @@
import React, { Component } from 'react';
import ReactTable from 'react-table';
import PropTypes from 'prop-types';
import { Trans, withNamespaces } from 'react-i18next';
import Modal from '../ui/Modal';
import PageTitle from '../ui/PageTitle';
import Card from '../ui/Card';
@@ -33,32 +34,32 @@ class Filters extends Component {
};
columns = [{
Header: 'Enabled',
Header: this.props.t('Enabled'),
accessor: 'enabled',
Cell: this.renderCheckbox,
width: 90,
className: 'text-center',
}, {
Header: 'Name',
Header: this.props.t('Name'),
accessor: 'name',
Cell: ({ value }) => (<div className="logs__row logs__row--overflow"><span className="logs__text" title={value}>{value}</span></div>),
}, {
Header: 'Filter URL',
Header: this.props.t('Filter URL'),
accessor: 'url',
Cell: ({ value }) => (<div className="logs__row logs__row--overflow"><a href={value} target='_blank' rel='noopener noreferrer' className="link logs__text">{value}</a></div>),
}, {
Header: 'Rules count',
Header: this.props.t('Rules count'),
accessor: 'rulesCount',
className: 'text-center',
Cell: props => props.value.toLocaleString(),
}, {
Header: 'Last time updated',
Header: this.props.t('Last time updated'),
accessor: 'lastUpdated',
className: 'text-center',
}, {
Header: 'Actions',
Header: this.props.t('Actions'),
accessor: 'url',
Cell: ({ value }) => (<span className='remove-icon fe fe-trash-2' onClick={() => this.props.removeFilter(value)}/>),
Cell: ({ value }) => (<span title={ this.props.t('Delete') } className='remove-icon fe fe-trash-2' onClick={() => this.props.removeFilter(value)}/>),
className: 'text-center',
width: 75,
sortable: false,
@@ -66,27 +67,28 @@ class Filters extends Component {
];
render() {
const { t } = this.props;
const { filters, userRules } = this.props.filtering;
return (
<div>
<PageTitle title="Filters" />
<PageTitle title={ t('Filters') } />
<div className="content">
<div className="row">
<div className="col-md-12">
<Card
title="Filters and hosts blocklists"
subtitle="AdGuard Home understands basic adblock rules and hosts files syntax."
title={ t('Filters and hosts blocklists') }
subtitle={ t('AdGuard Home understands basic adblock rules and hosts files syntax.') }
>
<ReactTable
data={filters}
columns={this.columns}
showPagination={false}
noDataText="No filters added"
noDataText={ t('No filters added') }
minRows={4} // TODO find out what to show if rules.length is 0
/>
<div className="card-actions">
<button className="btn btn-success btn-standart mr-2" type="submit" onClick={this.props.toggleFilteringModal}>Add filter</button>
<button className="btn btn-primary btn-standart" type="submit" onClick={this.props.refreshFilters}>Check updates</button>
<button className="btn btn-success btn-standart mr-2" type="submit" onClick={this.props.toggleFilteringModal}><Trans>Add filter</Trans></button>
<button className="btn btn-primary btn-standart" type="submit" onClick={this.props.refreshFilters}><Trans>Check updates</Trans></button>
</div>
</Card>
</div>
@@ -104,8 +106,8 @@ class Filters extends Component {
toggleModal={this.props.toggleFilteringModal}
addFilter={this.props.addFilter}
isFilterAdded={this.props.filtering.isFilterAdded}
title="New filter subscription"
inputDescription="Enter a valid URL to a filter subscription or a hosts file."
title={ t('New filter subscription') }
inputDescription={ t('Enter a valid URL to a filter subscription or a hosts file.') }
/>
</div>
);
@@ -127,7 +129,8 @@ Filters.propTypes = {
toggleFilteringModal: PropTypes.func.isRequired,
handleRulesChange: PropTypes.func.isRequired,
refreshFilters: PropTypes.func.isRequired,
t: PropTypes.func,
};
export default Filters;
export default withNamespaces()(Filters);

View File

@@ -4,6 +4,7 @@ import ReactTable from 'react-table';
import { saveAs } from 'file-saver/FileSaver';
import escapeRegExp from 'lodash/escapeRegExp';
import endsWith from 'lodash/endsWith';
import { Trans, withNamespaces } from 'react-i18next';
import { formatTime } from '../../helpers/helpers';
import { getTrackerData } from '../../helpers/trackers/trackers';
@@ -75,21 +76,22 @@ class Logs extends Component {
className={`btn btn-sm ${buttonClass}`}
onClick={() => this.toggleBlocking(buttonText.toLowerCase(), domain)}
>
{buttonText}
<Trans>{buttonText}</Trans>
</button>
</div>
);
}
renderLogs(logs) {
const { t } = this.props;
const columns = [{
Header: 'Time',
Header: t('Time'),
accessor: 'time',
maxWidth: 110,
filterable: false,
Cell: ({ value }) => (<div className="logs__row"><span className="logs__text" title={value}>{formatTime(value)}</span></div>),
}, {
Header: 'Domain name',
Header: t('Domain name'),
accessor: 'domain',
Cell: (row) => {
const response = row.value;
@@ -105,11 +107,11 @@ class Logs extends Component {
);
},
}, {
Header: 'Type',
Header: t('Type'),
accessor: 'type',
maxWidth: 60,
}, {
Header: 'Response',
Header: t('Response'),
accessor: 'response',
Cell: (row) => {
const responses = row.value;
@@ -142,7 +144,7 @@ class Logs extends Component {
return (
<div className="logs__row">
{this.renderTooltip(isFiltered, rule)}
<span>Empty</span>
<span><Trans>Empty</Trans></span>
</div>
);
},
@@ -159,11 +161,11 @@ class Logs extends Component {
className="form-control"
value={filter ? filter.value : 'all'}
>
<option value="all">Show all</option>
<option value="filtered">Show filtered</option>
<option value="all">{ t('Show all') }</option>
<option value="filtered">{ t('Show filtered') }</option>
</select>,
}, {
Header: 'Client',
Header: t('Client'),
accessor: 'client',
maxWidth: 250,
Cell: (row) => {
@@ -191,7 +193,14 @@ class Logs extends Component {
showPagination={true}
defaultPageSize={50}
minRows={7}
noDataText="No logs found"
// Text
previousText={ t('Previous') }
nextText={ t('Next') }
loadingText={ t('Loading...') }
pageText={ t('Page') }
ofText={ t('of') }
rowsText={ t('rows') }
noDataText={ t('No logs found') }
defaultFilterMethod={(filter, row) => {
const id = filter.pivotId || filter.id;
return row[id] !== undefined ?
@@ -233,17 +242,17 @@ class Logs extends Component {
className="btn btn-gray btn-sm mr-2"
type="submit"
onClick={() => this.props.toggleLogStatus(queryLogEnabled)}
>Disable log</button>
><Trans>Disable log</Trans></button>
<button
className="btn btn-primary btn-sm mr-2"
type="submit"
onClick={this.handleDownloadButton}
>Download log file</button>
><Trans>Download log file</Trans></button>
<button
className="btn btn-outline-primary btn-sm"
type="submit"
onClick={this.getLogs}
>Refresh</button>
><Trans>Refresh</Trans></button>
</Fragment>
);
}
@@ -253,16 +262,16 @@ class Logs extends Component {
className="btn btn-success btn-sm mr-2"
type="submit"
onClick={() => this.props.toggleLogStatus(queryLogEnabled)}
>Enable log</button>
><Trans>Enable log</Trans></button>
);
}
render() {
const { queryLogs, dashboard } = this.props;
const { queryLogs, dashboard, t } = this.props;
const { queryLogEnabled } = dashboard;
return (
<Fragment>
<PageTitle title="Query Log" subtitle="Last 5000 DNS queries">
<PageTitle title={ t('Query Log') } subtitle={ t('Last 5000 DNS queries') }>
<div className="page-title__actions">
{this.renderButtons(queryLogEnabled)}
</div>
@@ -288,6 +297,7 @@ Logs.propTypes = {
userRules: PropTypes.string,
setRules: PropTypes.func,
addSuccessToast: PropTypes.func,
t: PropTypes.func,
};
export default Logs;
export default withNamespaces()(Logs);

View File

@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Trans } from 'react-i18next';
class Toast extends Component {
componentDidMount() {
@@ -18,7 +19,7 @@ class Toast extends Component {
return (
<div className={`toast toast--${this.props.type}`}>
<p className="toast__content">
{this.props.message}
<Trans>{this.props.message}</Trans>
</p>
<button className="toast__dismiss" onClick={() => this.props.removeToast(this.props.id)}>
<svg stroke="#fff" fill="none" width="20" height="20" strokeWidth="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m18 6-12 12"/><path d="m6 6 12 12"/></svg>

View File

@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactModal from 'react-modal';
import classnames from 'classnames';
import { Trans, withNamespaces } from 'react-i18next';
import { R_URL_REQUIRES_PROTOCOL } from '../../helpers/constants';
import './Modal.css';
@@ -13,7 +14,7 @@ const initialState = {
isUrlValid: false,
};
export default class Modal extends Component {
class Modal extends Component {
state = initialState;
// eslint-disable-next-line
@@ -70,8 +71,8 @@ export default class Modal extends Component {
if (!this.props.isFilterAdded) {
return (
<React.Fragment>
<input type="text" className={inputNameClass} placeholder="Enter name" onChange={this.handleNameChange} />
<input type="text" className={inputUrlClass} placeholder="Enter URL" onChange={this.handleUrlChange} />
<input type="text" className={inputNameClass} placeholder={ this.props.t('Enter name') } onChange={this.handleNameChange} />
<input type="text" className={inputUrlClass} placeholder={ this.props.t('Enter URL') } onChange={this.handleUrlChange} />
{inputDescription &&
<div className="description">
{inputDescription}
@@ -81,7 +82,7 @@ export default class Modal extends Component {
}
return (
<div className="description">
Url added successfully
<Trans>Url added successfully</Trans>
</div>
);
};
@@ -110,8 +111,8 @@ export default class Modal extends Component {
{
!this.props.isFilterAdded &&
<div className="modal-footer">
<button type="button" className="btn btn-secondary" onClick={this.closeModal}>Cancel</button>
<button type="button" className="btn btn-success" onClick={this.handleNext} disabled={isValidForSubmit}>Add filter</button>
<button type="button" className="btn btn-secondary" onClick={this.closeModal}><Trans>Cancel</Trans></button>
<button type="button" className="btn btn-success" onClick={this.handleNext} disabled={isValidForSubmit}><Trans>Add filter</Trans></button>
</div>
}
</div>
@@ -127,4 +128,7 @@ Modal.propTypes = {
inputDescription: PropTypes.string,
addFilter: PropTypes.func.isRequired,
isFilterAdded: PropTypes.bool,
t: PropTypes.func,
};
export default withNamespaces()(Modal);