Merge branch 'master' into 1920-client-find

This commit is contained in:
Andrey Meshkov 2020-09-08 13:36:10 +03:00
commit 49a5bab267
10 changed files with 61 additions and 17 deletions

6
client/package-lock.json generated vendored
View File

@ -12377,9 +12377,9 @@
} }
}, },
"react-i18next": { "react-i18next": {
"version": "11.4.0", "version": "11.7.2",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.4.0.tgz", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.7.2.tgz",
"integrity": "sha512-lyOZSSQkif4H9HnHN3iEKVkryLI+WkdZSEw3VAZzinZLopfYRMHVY5YxCopdkXPLEHs6S5GjKYPh3+j0j336Fg==", "integrity": "sha512-Djj3K3hh5Tecla2CI9rLO3TZBYGMFrGilm0JY4cLofAQONCi5TK6nVmUPKoB59n1ZffgjfgJt6zlbE9aGF6Q0Q==",
"requires": { "requires": {
"@babel/runtime": "^7.3.1", "@babel/runtime": "^7.3.1",
"html-parse-stringify2": "2.0.1" "html-parse-stringify2": "2.0.1"

2
client/package.json vendored
View File

@ -28,7 +28,7 @@
"react": "^16.13.1", "react": "^16.13.1",
"react-click-outside": "^3.0.1", "react-click-outside": "^3.0.1",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-i18next": "^11.4.0", "react-i18next": "^11.7.2",
"react-modal": "^3.11.2", "react-modal": "^3.11.2",
"react-popper-tooltip": "^2.11.1", "react-popper-tooltip": "^2.11.1",
"react-redux": "^7.2.0", "react-redux": "^7.2.0",

View File

@ -363,7 +363,7 @@
"fix": "Fix", "fix": "Fix",
"dns_providers": "Here is a <0>list of known DNS providers</0> to choose from.", "dns_providers": "Here is a <0>list of known DNS providers</0> to choose from.",
"update_now": "Update now", "update_now": "Update now",
"update_failed": "Auto-update failed. Please <a href='https://github.com/AdguardTeam/AdGuardHome/wiki/Getting-Started#update'>follow the steps</a> to update manually.", "update_failed": "Auto-update failed. Please <a>follow these steps</a> to update manually.",
"processing_update": "Please wait, AdGuard Home is being updated", "processing_update": "Please wait, AdGuard Home is being updated",
"clients_title": "Clients", "clients_title": "Clients",
"clients_desc": "Configure devices connected to AdGuard Home", "clients_desc": "Configure devices connected to AdGuard Home",

View File

@ -4,9 +4,10 @@ import axios from 'axios';
import endsWith from 'lodash/endsWith'; import endsWith from 'lodash/endsWith';
import escapeRegExp from 'lodash/escapeRegExp'; import escapeRegExp from 'lodash/escapeRegExp';
import React from 'react';
import { splitByNewLine, sortClients } from '../helpers/helpers'; import { splitByNewLine, sortClients } from '../helpers/helpers';
import { import {
BLOCK_ACTIONS, CHECK_TIMEOUT, STATUS_RESPONSE, SETTINGS_NAMES, FORM_NAME, BLOCK_ACTIONS, CHECK_TIMEOUT, STATUS_RESPONSE, SETTINGS_NAMES, FORM_NAME, GETTING_STARTED_LINK,
} from '../helpers/constants'; } from '../helpers/constants';
import { areEqualVersions } from '../helpers/version'; import { areEqualVersions } from '../helpers/version';
import { getTlsStatus } from './encryption'; import { getTlsStatus } from './encryption';
@ -184,7 +185,14 @@ export const getUpdate = () => async (dispatch, getState) => {
dispatch(getUpdateRequest()); dispatch(getUpdateRequest());
const handleRequestError = () => { const handleRequestError = () => {
dispatch(addNoticeToast({ error: 'update_failed' })); const options = {
components: {
a: <a href={GETTING_STARTED_LINK} target="_blank"
rel="noopener noreferrer" />,
},
};
dispatch(addNoticeToast({ error: 'update_failed', options }));
dispatch(getUpdateFailure()); dispatch(getUpdateFailure());
}; };

View File

@ -388,3 +388,28 @@
.logs__table .loading:before { .logs__table .loading:before {
min-height: 100%; min-height: 100%;
} }
.logs__whois {
display: inline;
font-size: 12px;
white-space: nowrap;
}
.logs__whois::after {
content: "|";
padding: 0 5px;
opacity: 0.3;
}
.logs__whois:last-child::after {
content: "";
}
.logs__whois-icon.icons {
position: relative;
top: -2px;
width: 12px;
height: 12px;
margin-right: 1px;
opacity: 0.5;
}

View File

@ -14,7 +14,7 @@ const getFormattedWhois = (value, t) => {
<div key={key} title={t(key)}> <div key={key} title={t(key)}>
{icon && ( {icon && (
<Fragment> <Fragment>
<svg className="logs__whois-icon text-muted-dark icons"> <svg className="logs__whois-icon text-muted-dark icons icon--24">
<use xlinkHref={`#${icon}`} /> <use xlinkHref={`#${icon}`} />
</svg> </svg>
&nbsp; &nbsp;

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next'; import { Trans } from 'react-i18next';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { TOAST_TIMEOUTS } from '../../helpers/constants'; import { TOAST_TIMEOUTS } from '../../helpers/constants';
import { removeToast } from '../../actions'; import { removeToast } from '../../actions';
@ -9,8 +9,8 @@ const Toast = ({
id, id,
message, message,
type, type,
options,
}) => { }) => {
const { t } = useTranslation();
const dispatch = useDispatch(); const dispatch = useDispatch();
const [timerId, setTimerId] = useState(null); const [timerId, setTimerId] = useState(null);
@ -30,7 +30,12 @@ const Toast = ({
return <div className={`toast toast--${type}`} return <div className={`toast toast--${type}`}
onMouseOver={clearRemoveToastTimeout} onMouseOver={clearRemoveToastTimeout}
onMouseOut={setRemoveToastTimeout}> onMouseOut={setRemoveToastTimeout}>
<p className="toast__content">{t(message)}</p> <p className="toast__content">
<Trans
i18nKey={message}
{...options}
/>
</p>
<button className="toast__dismiss" onClick={removeCurrentToast}> <button className="toast__dismiss" onClick={removeCurrentToast}>
<svg stroke="#fff" fill="none" width="20" height="20" strokeWidth="2" <svg stroke="#fff" fill="none" width="20" height="20" strokeWidth="2"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@ -45,6 +50,7 @@ Toast.propTypes = {
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
message: PropTypes.string.isRequired, message: PropTypes.string.isRequired,
type: PropTypes.string.isRequired, type: PropTypes.string.isRequired,
options: PropTypes.object,
}; };
export default Toast; export default Toast;

View File

@ -53,6 +53,8 @@ export const REPOSITORY = {
export const PRIVACY_POLICY_LINK = 'https://adguard.com/privacy/home.html'; export const PRIVACY_POLICY_LINK = 'https://adguard.com/privacy/home.html';
export const PORT_53_FAQ_LINK = 'https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ#bindinuse'; export const PORT_53_FAQ_LINK = 'https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ#bindinuse';
export const GETTING_STARTED_LINK = 'https://github.com/AdguardTeam/AdGuardHome/wiki/Getting-Started#update';
export const ADDRESS_IN_USE_TEXT = 'address already in use'; export const ADDRESS_IN_USE_TEXT = 'address already in use';
export const INSTALL_FIRST_STEP = 1; export const INSTALL_FIRST_STEP = 1;
@ -76,8 +78,6 @@ export const EMPTY_DATE = '0001-01-01T00:00:00Z';
export const DEBOUNCE_TIMEOUT = 300; export const DEBOUNCE_TIMEOUT = 300;
export const DEBOUNCE_FILTER_TIMEOUT = 500; export const DEBOUNCE_FILTER_TIMEOUT = 500;
export const CHECK_TIMEOUT = 1000; export const CHECK_TIMEOUT = 1000;
export const SUCCESS_TOAST_TIMEOUT = 5000;
export const FAILURE_TOAST_TIMEOUT = 30000;
export const HIDE_TOOLTIP_DELAY = 300; export const HIDE_TOOLTIP_DELAY = 300;
export const SHOW_TOOLTIP_DELAY = 200; export const SHOW_TOOLTIP_DELAY = 200;
export const MODAL_OPEN_TIMEOUT = 150; export const MODAL_OPEN_TIMEOUT = 150;
@ -540,8 +540,11 @@ export const TOAST_TYPES = {
NOTICE: 'notice', NOTICE: 'notice',
}; };
export const SUCCESS_TOAST_TIMEOUT = 5000;
export const FAILURE_TOAST_TIMEOUT = 30000;
export const TOAST_TIMEOUTS = { export const TOAST_TIMEOUTS = {
[TOAST_TYPES.SUCCESS]: 5000, [TOAST_TYPES.SUCCESS]: SUCCESS_TOAST_TIMEOUT,
[TOAST_TYPES.ERROR]: 30000, [TOAST_TYPES.ERROR]: FAILURE_TOAST_TIMEOUT,
[TOAST_TYPES.NOTICE]: 30000, [TOAST_TYPES.NOTICE]: FAILURE_TOAST_TIMEOUT,
}; };

View File

@ -9,7 +9,7 @@ const getFormattedWhois = (whois) => {
.map((key) => { .map((key) => {
const icon = WHOIS_ICONS[key]; const icon = WHOIS_ICONS[key];
return ( return (
<span className="logs__whois text-muted " key={key} title={whoisInfo[key]}> <span className="logs__whois text-muted" key={key} title={whoisInfo[key]}>
{icon && ( {icon && (
<> <>
<svg className="logs__whois-icon icons icon--18"> <svg className="logs__whois-icon icons icon--18">

View File

@ -15,6 +15,7 @@ const toasts = handleActions({
const errorToast = { const errorToast = {
id: nanoid(), id: nanoid(),
message, message,
options: payload.options,
type: TOAST_TYPES.ERROR, type: TOAST_TYPES.ERROR,
}; };
@ -35,6 +36,7 @@ const toasts = handleActions({
const noticeToast = { const noticeToast = {
id: nanoid(), id: nanoid(),
message: payload.error.toString(), message: payload.error.toString(),
options: payload.options,
type: TOAST_TYPES.NOTICE, type: TOAST_TYPES.NOTICE,
}; };