+ client: add button for check updates
This commit is contained in:
parent
5d60bb05ab
commit
0e9df33a40
|
@ -312,5 +312,7 @@
|
||||||
"access_disallowed_desc": "A list of CIDR or IP addresses. If configured, AdGuard Home will drop requests from these IP addresses.",
|
"access_disallowed_desc": "A list of CIDR or IP addresses. If configured, AdGuard Home will drop requests from these IP addresses.",
|
||||||
"access_blocked_title": "Blocked domains",
|
"access_blocked_title": "Blocked domains",
|
||||||
"access_blocked_desc": "Don't confuse this with filters. AdGuard Home will drop DNS queries with these domains in query's question.",
|
"access_blocked_desc": "Don't confuse this with filters. AdGuard Home will drop DNS queries with these domains in query's question.",
|
||||||
"access_settings_saved": "Access settings successfully saved"
|
"access_settings_saved": "Access settings successfully saved",
|
||||||
|
"updates_checked": "Updates successfully checked",
|
||||||
|
"check_updates_now": "Check updates now"
|
||||||
}
|
}
|
|
@ -145,11 +145,14 @@ export const getVersionRequest = createAction('GET_VERSION_REQUEST');
|
||||||
export const getVersionFailure = createAction('GET_VERSION_FAILURE');
|
export const getVersionFailure = createAction('GET_VERSION_FAILURE');
|
||||||
export const getVersionSuccess = createAction('GET_VERSION_SUCCESS');
|
export const getVersionSuccess = createAction('GET_VERSION_SUCCESS');
|
||||||
|
|
||||||
export const getVersion = () => async (dispatch) => {
|
export const getVersion = (recheck = false) => async (dispatch) => {
|
||||||
dispatch(getVersionRequest());
|
dispatch(getVersionRequest());
|
||||||
try {
|
try {
|
||||||
const newVersion = await apiClient.getGlobalVersion();
|
const newVersion = await apiClient.getGlobalVersion({ recheck_now: recheck });
|
||||||
dispatch(getVersionSuccess(newVersion));
|
dispatch(getVersionSuccess(newVersion));
|
||||||
|
if (recheck) {
|
||||||
|
dispatch(addSuccessToast('updates_checked'));
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(addErrorToast({ error }));
|
dispatch(addErrorToast({ error }));
|
||||||
dispatch(getVersionFailure());
|
dispatch(getVersionFailure());
|
||||||
|
|
|
@ -36,7 +36,7 @@ export default class Api {
|
||||||
GLOBAL_QUERY_LOG_DISABLE = { path: 'querylog_disable', method: 'POST' };
|
GLOBAL_QUERY_LOG_DISABLE = { path: 'querylog_disable', method: 'POST' };
|
||||||
GLOBAL_SET_UPSTREAM_DNS = { path: 'set_upstreams_config', method: 'POST' };
|
GLOBAL_SET_UPSTREAM_DNS = { path: 'set_upstreams_config', method: 'POST' };
|
||||||
GLOBAL_TEST_UPSTREAM_DNS = { path: 'test_upstream_dns', method: 'POST' };
|
GLOBAL_TEST_UPSTREAM_DNS = { path: 'test_upstream_dns', method: 'POST' };
|
||||||
GLOBAL_VERSION = { path: 'version.json', method: 'GET' };
|
GLOBAL_VERSION = { path: 'version.json', method: 'POST' };
|
||||||
GLOBAL_ENABLE_PROTECTION = { path: 'enable_protection', method: 'POST' };
|
GLOBAL_ENABLE_PROTECTION = { path: 'enable_protection', method: 'POST' };
|
||||||
GLOBAL_DISABLE_PROTECTION = { path: 'disable_protection', method: 'POST' };
|
GLOBAL_DISABLE_PROTECTION = { path: 'disable_protection', method: 'POST' };
|
||||||
GLOBAL_UPDATE = { path: 'update', method: 'POST' };
|
GLOBAL_UPDATE = { path: 'update', method: 'POST' };
|
||||||
|
@ -125,9 +125,13 @@ export default class Api {
|
||||||
return this.makeRequest(path, method, config);
|
return this.makeRequest(path, method, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
getGlobalVersion() {
|
getGlobalVersion(data) {
|
||||||
const { path, method } = this.GLOBAL_VERSION;
|
const { path, method } = this.GLOBAL_VERSION;
|
||||||
return this.makeRequest(path, method);
|
const config = {
|
||||||
|
data,
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
};
|
||||||
|
return this.makeRequest(path, method, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
enableGlobalProtection() {
|
enableGlobalProtection() {
|
||||||
|
|
|
@ -65,8 +65,7 @@ class App extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dashboard, encryption } = this.props;
|
const { dashboard, encryption } = this.props;
|
||||||
const updateAvailable =
|
const updateAvailable = dashboard.isCoreRunning && dashboard.isUpdateAvailable;
|
||||||
!dashboard.processingVersions && dashboard.isCoreRunning && dashboard.isUpdateAvailable;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HashRouter hashType="noslash">
|
<HashRouter hashType="noslash">
|
||||||
|
|
|
@ -50,8 +50,26 @@ class Dashboard extends Component {
|
||||||
dashboard.processingClients ||
|
dashboard.processingClients ||
|
||||||
dashboard.processingTopStats;
|
dashboard.processingTopStats;
|
||||||
|
|
||||||
const refreshFullButton = <button type="button" className="btn btn-outline-primary btn-sm" onClick={() => this.getAllStats()}><Trans>refresh_statics</Trans></button>;
|
const refreshFullButton = (
|
||||||
const refreshButton = <button type="button" className="btn btn-outline-primary btn-sm card-refresh" onClick={() => this.getAllStats()} />;
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-outline-primary btn-sm"
|
||||||
|
onClick={() => this.getAllStats()}
|
||||||
|
>
|
||||||
|
<Trans>refresh_statics</Trans>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
const refreshButton = (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-icon btn-outline-primary btn-sm"
|
||||||
|
onClick={() => this.getAllStats()}
|
||||||
|
>
|
||||||
|
<svg className="icons">
|
||||||
|
<use xlinkHref="#refresh" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|
|
@ -75,7 +75,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-version__value {
|
.nav-version__value {
|
||||||
|
max-width: 110px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-version__link {
|
.nav-version__link {
|
||||||
|
@ -85,6 +89,11 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-version__text {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
.header-brand-img {
|
.header-brand-img {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,26 @@ import { Trans, withNamespaces } from 'react-i18next';
|
||||||
|
|
||||||
import { getDnsAddress } from '../../helpers/helpers';
|
import { getDnsAddress } from '../../helpers/helpers';
|
||||||
|
|
||||||
function Version(props) {
|
const Version = (props) => {
|
||||||
const { dnsVersion, dnsAddresses, dnsPort } = props;
|
const {
|
||||||
|
dnsVersion, dnsAddresses, dnsPort, processingVersion, t,
|
||||||
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="nav-version">
|
<div className="nav-version">
|
||||||
<div className="nav-version__text">
|
<div className="nav-version__text">
|
||||||
<Trans>version</Trans>: <span className="nav-version__value">{dnsVersion}</span>
|
<Trans>version</Trans>: <span className="nav-version__value" title={dnsVersion}>{dnsVersion}</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-icon btn-icon-sm btn-outline-primary btn-sm ml-2"
|
||||||
|
onClick={() => props.getVersion(true)}
|
||||||
|
disabled={processingVersion}
|
||||||
|
title={t('check_updates_now')}
|
||||||
|
>
|
||||||
|
<svg className="icons">
|
||||||
|
<use xlinkHref="#refresh" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="nav-version__link">
|
<div className="nav-version__link">
|
||||||
<div className="popover__trigger popover__trigger--address">
|
<div className="popover__trigger popover__trigger--address">
|
||||||
|
@ -17,20 +31,23 @@ function Version(props) {
|
||||||
</div>
|
</div>
|
||||||
<div className="popover__body popover__body--address">
|
<div className="popover__body popover__body--address">
|
||||||
<div className="popover__list">
|
<div className="popover__list">
|
||||||
{dnsAddresses
|
{dnsAddresses.map(ip => (
|
||||||
.map(ip => <li key={ip}>{getDnsAddress(ip, dnsPort)}</li>)
|
<li key={ip}>{getDnsAddress(ip, dnsPort)}</li>
|
||||||
}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
Version.propTypes = {
|
Version.propTypes = {
|
||||||
dnsVersion: PropTypes.string.isRequired,
|
dnsVersion: PropTypes.string.isRequired,
|
||||||
dnsAddresses: PropTypes.array.isRequired,
|
dnsAddresses: PropTypes.array.isRequired,
|
||||||
dnsPort: PropTypes.number.isRequired,
|
dnsPort: PropTypes.number.isRequired,
|
||||||
|
getVersion: PropTypes.func.isRequired,
|
||||||
|
processingVersion: PropTypes.bool.isRequired,
|
||||||
|
t: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withNamespaces()(Version);
|
export default withNamespaces()(Version);
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Header extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dashboard } = this.props;
|
const { dashboard, getVersion, location } = this.props;
|
||||||
const { isMenuOpen } = this.state;
|
const { isMenuOpen } = this.state;
|
||||||
const badgeClass = classnames({
|
const badgeClass = classnames({
|
||||||
'badge dns-status': true,
|
'badge dns-status': true,
|
||||||
|
@ -51,7 +51,7 @@ class Header extends Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Menu
|
<Menu
|
||||||
location={this.props.location}
|
location={location}
|
||||||
isMenuOpen={isMenuOpen}
|
isMenuOpen={isMenuOpen}
|
||||||
toggleMenuOpen={this.toggleMenuOpen}
|
toggleMenuOpen={this.toggleMenuOpen}
|
||||||
closeMenu={this.closeMenu}
|
closeMenu={this.closeMenu}
|
||||||
|
@ -59,7 +59,8 @@ class Header extends Component {
|
||||||
{!dashboard.processing &&
|
{!dashboard.processing &&
|
||||||
<div className="col col-sm-6 col-lg-3">
|
<div className="col col-sm-6 col-lg-3">
|
||||||
<Version
|
<Version
|
||||||
{ ...this.props.dashboard }
|
{ ...dashboard }
|
||||||
|
getVersion={getVersion}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -71,8 +72,9 @@ class Header extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
Header.propTypes = {
|
Header.propTypes = {
|
||||||
dashboard: PropTypes.object,
|
dashboard: PropTypes.object.isRequired,
|
||||||
location: PropTypes.object,
|
location: PropTypes.object.isRequired,
|
||||||
|
getVersion: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withNamespaces()(Header);
|
export default withNamespaces()(Header);
|
||||||
|
|
|
@ -88,3 +88,10 @@
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-icon-sm {
|
||||||
|
width: 23px;
|
||||||
|
height: 23px;
|
||||||
|
min-width: 23px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
|
@ -33,21 +33,6 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-refresh {
|
|
||||||
height: 26px;
|
|
||||||
width: 26px;
|
|
||||||
background-size: 14px;
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI0IiBzdHJva2U9IiM0NjdmY2YiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMjMgNHY2aC02Ii8+PHBhdGggZD0ibTEgMjB2LTZoNiIvPjxwYXRoIGQ9Im0zLjUxIDlhOSA5IDAgMCAxIDE0Ljg1LTMuMzZsNC42NCA0LjM2bS0yMiA0IDQuNjQgNC4zNmE5IDkgMCAwIDAgMTQuODUtMy4zNiIvPjwvc3ZnPg==");
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-refresh:hover,
|
|
||||||
.card-refresh:not(:disabled):not(.disabled):active,
|
|
||||||
.card-refresh:focus:active {
|
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI0IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMjMgNHY2aC02Ii8+PHBhdGggZD0ibTEgMjB2LTZoNiIvPjxwYXRoIGQ9Im0zLjUxIDlhOSA5IDAgMCAxIDE0Ljg1LTMuMzZsNC42NCA0LjM2bS0yMiA0IDQuNjQgNC4zNmE5IDkgMCAwIDAgMTQuODUtMy4zNiIvPjwvc3ZnPg==");
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-title-stats {
|
.card-title-stats {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #9aa0ac;
|
color: #9aa0ac;
|
||||||
|
|
|
@ -55,6 +55,10 @@ const Icons = () => (
|
||||||
<symbol id="settings" viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2">
|
<symbol id="settings" viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2">
|
||||||
<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"/>
|
<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"/>
|
||||||
</symbol>
|
</symbol>
|
||||||
|
|
||||||
|
<symbol id="refresh" viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2">
|
||||||
|
<path d="M23 4v6h-6M1 20v-6h6"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>
|
||||||
|
</symbol>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,7 @@ const dashboard = handleActions({
|
||||||
newVersion,
|
newVersion,
|
||||||
canAutoUpdate,
|
canAutoUpdate,
|
||||||
isUpdateAvailable: true,
|
isUpdateAvailable: true,
|
||||||
|
processingVersion: false,
|
||||||
};
|
};
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue