From 63049e05218beb880ea29c6f6e22a01ac830b9bc Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Fri, 30 Aug 2019 18:35:27 +0300 Subject: [PATCH] + client: handle clear statistics --- client/src/__locales/en.json | 10 +++-- client/src/actions/stats.js | 16 ++++++++ client/src/api/Api.js | 6 +++ .../components/Settings/StatsConfig/Form.js | 4 +- .../components/Settings/StatsConfig/index.js | 30 ++++++++++---- client/src/components/Settings/index.js | 17 ++++---- client/src/containers/Settings.js | 3 +- client/src/reducers/stats.js | 39 ++++++++++++------- 8 files changed, 91 insertions(+), 34 deletions(-) diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 95f80e68..119c1828 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -369,9 +369,13 @@ "interval_24_hour": "24 hours", "interval_days": "{{count}} day", "interval_days_plural": "{{count}} days", - "time_period": "Time period", - "time_period_desc": "If you decrease the interval value, some data will be lost", "domain": "Domain", "answer": "Answer", - "filter_added_successfully": "The filter has been successfully added" + "filter_added_successfully": "The filter has been successfully added", + "statistics_logs": "Statistics and logs", + "statistics_retention": "Statistics retention", + "statistics_retention_desc": "If you decrease the interval value, some data will be lost", + "statistics_clear": " Clear statistics", + "statistics_clear_confirm": "Are you sure you want to clear statistics?", + "statistics_cleared": "Statistics successfully cleared" } diff --git a/client/src/actions/stats.js b/client/src/actions/stats.js index a6eb0f13..65902e15 100644 --- a/client/src/actions/stats.js +++ b/client/src/actions/stats.js @@ -59,3 +59,19 @@ export const getStats = () => async (dispatch) => { dispatch(getStatsFailure()); } }; + +export const resetStatsRequest = createAction('RESET_STATS_REQUEST'); +export const resetStatsFailure = createAction('RESET_STATS_FAILURE'); +export const resetStatsSuccess = createAction('RESET_STATS_SUCCESS'); + +export const resetStats = () => async (dispatch) => { + dispatch(getStatsRequest()); + try { + await apiClient.resetStats(); + dispatch(addSuccessToast('statistics_cleared')); + dispatch(resetStatsSuccess()); + } catch (error) { + dispatch(addErrorToast({ error })); + dispatch(resetStatsFailure()); + } +}; diff --git a/client/src/api/Api.js b/client/src/api/Api.js index de068563..0f63f2ea 100644 --- a/client/src/api/Api.js +++ b/client/src/api/Api.js @@ -496,6 +496,7 @@ export default class Api { GET_STATS = { path: 'stats', method: 'GET' }; STATS_INFO = { path: 'stats_info', method: 'GET' }; STATS_CONFIG = { path: 'stats_config', method: 'POST' }; + STATS_RESET = { path: 'stats_reset', method: 'POST' }; getStats() { const { path, method } = this.GET_STATS; @@ -515,4 +516,9 @@ export default class Api { }; return this.makeRequest(path, method, config); } + + resetStats() { + const { path, method } = this.STATS_RESET; + return this.makeRequest(path, method); + } } diff --git a/client/src/components/Settings/StatsConfig/Form.js b/client/src/components/Settings/StatsConfig/Form.js index 828ffa15..463476c9 100644 --- a/client/src/components/Settings/StatsConfig/Form.js +++ b/client/src/components/Settings/StatsConfig/Form.js @@ -38,10 +38,10 @@ const Form = (props) => {
- time_period_desc + statistics_retention_desc
diff --git a/client/src/components/Settings/StatsConfig/index.js b/client/src/components/Settings/StatsConfig/index.js index 5513e7d6..b649c6c9 100644 --- a/client/src/components/Settings/StatsConfig/index.js +++ b/client/src/components/Settings/StatsConfig/index.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { withNamespaces } from 'react-i18next'; +import { withNamespaces, Trans } from 'react-i18next'; import debounce from 'lodash/debounce'; import { DEBOUNCE_TIMEOUT } from '../../../helpers/constants'; @@ -12,18 +12,21 @@ class StatsConfig extends Component { this.props.setStatsConfig(values); }, DEBOUNCE_TIMEOUT); + handleReset = () => { + const { t, resetStats } = this.props; + // eslint-disable-next-line no-alert + if (window.confirm(t('statistics_clear_confirm'))) { + resetStats(); + } + }; + render() { const { - t, - interval, - processing, + t, interval, processing, processingReset, } = this.props; return ( - +
+ +
); @@ -42,7 +54,9 @@ class StatsConfig extends Component { StatsConfig.propTypes = { interval: PropTypes.number.isRequired, processing: PropTypes.bool.isRequired, + processingReset: PropTypes.bool.isRequired, setStatsConfig: PropTypes.func.isRequired, + resetStats: PropTypes.func.isRequired, t: PropTypes.func.isRequired, }; diff --git a/client/src/components/Settings/index.js b/client/src/components/Settings/index.js index c928d393..5f7f2fd6 100644 --- a/client/src/components/Settings/index.js +++ b/client/src/components/Settings/index.js @@ -68,6 +68,7 @@ class Settings extends Component { services, setBlockedServices, setStatsConfig, + resetStats, stats, t, } = this.props; @@ -89,7 +90,9 @@ class Settings extends Component {
@@ -107,13 +110,13 @@ class Settings extends Component { } Settings.propTypes = { - initSettings: PropTypes.func, - settings: PropTypes.object, - settingsList: PropTypes.object, - toggleSetting: PropTypes.func, - getStatsConfig: PropTypes.func, - setStatsConfig: PropTypes.func, - t: PropTypes.func, + initSettings: PropTypes.func.isRequired, + settings: PropTypes.object.isRequired, + toggleSetting: PropTypes.func.isRequired, + getStatsConfig: PropTypes.func.isRequired, + setStatsConfig: PropTypes.func.isRequired, + resetStats: PropTypes.func.isRequired, + t: PropTypes.func.isRequired, }; export default withNamespaces()(Settings); diff --git a/client/src/containers/Settings.js b/client/src/containers/Settings.js index d13048ae..14f08cfc 100644 --- a/client/src/containers/Settings.js +++ b/client/src/containers/Settings.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import { initSettings, toggleSetting } from '../actions'; import { getBlockedServices, setBlockedServices } from '../actions/services'; -import { getStatsConfig, setStatsConfig } from '../actions/stats'; +import { getStatsConfig, setStatsConfig, resetStats } from '../actions/stats'; import Settings from '../components/Settings'; const mapStateToProps = (state) => { @@ -21,6 +21,7 @@ const mapDispatchToProps = { setBlockedServices, getStatsConfig, setStatsConfig, + resetStats, }; export default connect( diff --git a/client/src/reducers/stats.js b/client/src/reducers/stats.js index 3bae662d..88c33a12 100644 --- a/client/src/reducers/stats.js +++ b/client/src/reducers/stats.js @@ -2,6 +2,22 @@ import { handleActions } from 'redux-actions'; import * as actions from '../actions/stats'; +const defaultStats = { + dnsQueries: [], + blockedFiltering: [], + replacedParental: [], + replacedSafebrowsing: [], + topBlockedDomains: [], + topClients: [], + topQueriedDomains: [], + numBlockedFiltering: 0, + numDnsQueries: 0, + numReplacedParental: 0, + numReplacedSafebrowsing: 0, + numReplacedSafesearch: 0, + avgProcessingTime: 0, +}; + const stats = handleActions( { [actions.getStatsConfigRequest]: state => ({ ...state, processingGetConfig: true }), @@ -59,25 +75,22 @@ const stats = handleActions( return newState; }, + + [actions.resetStatsRequest]: state => ({ ...state, processingReset: true }), + [actions.resetStatsFailure]: state => ({ ...state, processingReset: false }), + [actions.resetStatsSuccess]: state => ({ + ...state, + ...defaultStats, + processingReset: false, + }), }, { processingGetConfig: false, processingSetConfig: false, processingStats: true, + processingReset: false, interval: 1, - dnsQueries: [], - blockedFiltering: [], - replacedParental: [], - replacedSafebrowsing: [], - topBlockedDomains: [], - topClients: [], - topQueriedDomains: [], - numBlockedFiltering: 0, - numDnsQueries: 0, - numReplacedParental: 0, - numReplacedSafebrowsing: 0, - numReplacedSafesearch: 0, - avgProcessingTime: 0, + ...defaultStats, }, );