parent
68422b8399
commit
43fcf4117d
|
@ -14978,6 +14978,11 @@
|
|||
"setimmediate": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"tiny-version-compare": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/tiny-version-compare/-/tiny-version-compare-0.9.1.tgz",
|
||||
"integrity": "sha512-kYim94l7ptSmj9rqxUMkrcMCJ448CS+hwqjA7OFcRi0ISdi0zjgdSUklQ4velVVECCjCo5frU3tNZ3oSgIKzsA=="
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"redux-thunk": "^2.3.0",
|
||||
"svg-url-loader": "^2.3.2",
|
||||
"tabler-react": "^1.10.0",
|
||||
"tiny-version-compare": "^0.9.1",
|
||||
"whatwg-fetch": "2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -164,6 +164,21 @@ export const getStats = () => async (dispatch) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const getVersionRequest = createAction('GET_VERSION_REQUEST');
|
||||
export const getVersionFailure = createAction('GET_VERSION_FAILURE');
|
||||
export const getVersionSuccess = createAction('GET_VERSION_SUCCESS');
|
||||
|
||||
export const getVersion = () => async (dispatch) => {
|
||||
dispatch(getVersionRequest());
|
||||
try {
|
||||
const newVersion = await apiClient.getGlobalVersion();
|
||||
dispatch(getVersionSuccess(newVersion));
|
||||
} catch (error) {
|
||||
dispatch(addErrorToast({ error }));
|
||||
dispatch(getVersionFailure());
|
||||
}
|
||||
};
|
||||
|
||||
export const getTopStatsRequest = createAction('GET_TOP_STATS_REQUEST');
|
||||
export const getTopStatsFailure = createAction('GET_TOP_STATS_FAILURE');
|
||||
export const getTopStatsSuccess = createAction('GET_TOP_STATS_SUCCESS');
|
||||
|
|
|
@ -31,6 +31,7 @@ export default class Api {
|
|||
GLOBAL_QUERY_LOG_ENABLE = { path: 'querylog_enable', method: 'POST' };
|
||||
GLOBAL_QUERY_LOG_DISABLE = { path: 'querylog_disable', method: 'POST' };
|
||||
GLOBAL_SET_UPSTREAM_DNS = { path: 'set_upstream_dns', method: 'POST' };
|
||||
GLOBAL_VERSION = { path: 'version.json', method: 'GET' };
|
||||
|
||||
restartGlobalFiltering() {
|
||||
const { path, method } = this.GLOBAL_RESTART;
|
||||
|
@ -107,6 +108,11 @@ export default class Api {
|
|||
return this.makeRequest(path, method, config);
|
||||
}
|
||||
|
||||
getGlobalVersion() {
|
||||
const { path, method } = this.GLOBAL_VERSION;
|
||||
return this.makeRequest(path, method);
|
||||
}
|
||||
|
||||
// Filtering
|
||||
FILTERING_STATUS = { path: 'filtering/status', method: 'GET' };
|
||||
FILTERING_ENABLE = { path: 'filtering/enable', method: 'POST' };
|
||||
|
|
|
@ -15,12 +15,13 @@ import Filters from '../../containers/Filters';
|
|||
import Logs from '../../containers/Logs';
|
||||
import Footer from '../ui/Footer';
|
||||
import Toasts from '../Toasts';
|
||||
|
||||
import Status from '../ui/Status';
|
||||
import Update from '../ui/Update';
|
||||
|
||||
class App extends Component {
|
||||
componentDidMount() {
|
||||
this.props.getDnsStatus();
|
||||
this.props.getVersion();
|
||||
}
|
||||
|
||||
handleStatusChange = () => {
|
||||
|
@ -29,9 +30,20 @@ class App extends Component {
|
|||
|
||||
render() {
|
||||
const { dashboard } = this.props;
|
||||
const updateAvailable =
|
||||
!dashboard.processingVersions &&
|
||||
dashboard.isCoreRunning &&
|
||||
dashboard.isUpdateAvailable;
|
||||
|
||||
return (
|
||||
<HashRouter hashType='noslash'>
|
||||
<Fragment>
|
||||
{updateAvailable &&
|
||||
<Update
|
||||
announcement={dashboard.announcement}
|
||||
announcementUrl={dashboard.announcementUrl}
|
||||
/>
|
||||
}
|
||||
<LoadingBar className="loading-bar" updateTime={1000} />
|
||||
<Route component={Header} />
|
||||
<div className="container container--wrap">
|
||||
|
@ -65,6 +77,7 @@ App.propTypes = {
|
|||
dashboard: PropTypes.object,
|
||||
isCoreRunning: PropTypes.bool,
|
||||
error: PropTypes.string,
|
||||
getVersion: PropTypes.func,
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -67,11 +67,15 @@
|
|||
}
|
||||
|
||||
.nav-version {
|
||||
padding: 16px 0;
|
||||
font-size: 0.85rem;
|
||||
padding: 7px 0;
|
||||
font-size: 0.80rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.nav-version__value {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.header-brand-img {
|
||||
height: 26px;
|
||||
}
|
||||
|
@ -103,7 +107,7 @@
|
|||
|
||||
.nav-version {
|
||||
padding: 0;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,12 @@ export default function Version(props) {
|
|||
const { dnsVersion, dnsAddress, dnsPort } = props;
|
||||
return (
|
||||
<div className="nav-version">
|
||||
version {dnsVersion} / address: {dnsAddress}:{dnsPort}
|
||||
<div className="nav-version__text">
|
||||
version: <span className="nav-version__value">{dnsVersion}</span>
|
||||
</div>
|
||||
<div className="nav-version__text">
|
||||
address: <span className="nav-version__value">{dnsAddress}:{dnsPort}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
.update {
|
||||
position: relative;
|
||||
z-index: 102;
|
||||
margin-bottom: 0;
|
||||
padding: 0.75rem 0;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './Update.css';
|
||||
|
||||
const Update = props => (
|
||||
<div className="alert alert-info update">
|
||||
<div className="container">
|
||||
{props.announcement} <a href={props.announcementUrl} target="_blank" rel="noopener noreferrer">Click here</a> for more info.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Update.propTypes = {
|
||||
announcement: PropTypes.string.isRequired,
|
||||
announcementUrl: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default Update;
|
|
@ -1,6 +1,7 @@
|
|||
import { combineReducers } from 'redux';
|
||||
import { handleActions } from 'redux-actions';
|
||||
import { loadingBarReducer } from 'react-redux-loading-bar';
|
||||
import versionCompare from 'tiny-version-compare';
|
||||
import nanoid from 'nanoid';
|
||||
|
||||
import * as actions from '../actions';
|
||||
|
@ -100,12 +101,36 @@ const dashboard = handleActions({
|
|||
const { queryLogEnabled } = state;
|
||||
return ({ ...state, queryLogEnabled: !queryLogEnabled, logStatusProcessing: false });
|
||||
},
|
||||
|
||||
[actions.getVersionRequest]: state => ({ ...state, processingVersion: true }),
|
||||
[actions.getVersionFailure]: state => ({ ...state, processingVersion: false }),
|
||||
[actions.getVersionSuccess]: (state, { payload }) => {
|
||||
const currentVersion = state.dnsVersion === 'undefined' ? 0 : state.dnsVersion;
|
||||
|
||||
if (versionCompare(currentVersion, payload.version) === -1) {
|
||||
const {
|
||||
announcement,
|
||||
announcement_url: announcementUrl,
|
||||
} = payload;
|
||||
|
||||
const newState = {
|
||||
...state,
|
||||
announcement,
|
||||
announcementUrl,
|
||||
isUpdateAvailable: true,
|
||||
};
|
||||
return newState;
|
||||
}
|
||||
|
||||
return state;
|
||||
},
|
||||
}, {
|
||||
processing: true,
|
||||
isCoreRunning: false,
|
||||
processingTopStats: true,
|
||||
processingStats: true,
|
||||
logStatusProcessing: false,
|
||||
processingVersion: true,
|
||||
});
|
||||
|
||||
const queryLogs = handleActions({
|
||||
|
|
Loading…
Reference in New Issue