diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index d3700869..41d97778 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -174,7 +174,7 @@ "rule_added_to_custom_filtering_toast": "Rule added to the custom filtering rules", "query_log_response_status": "Status: {{value}}", "query_log_filtered": "Filtered by {{filter}}", - "query_log_confirm_clear": "Are you sure you want to clear the entire query log? This will also clear statistics on the dashboard.", + "query_log_confirm_clear": "Are you sure you want to clear the entire query log?", "query_log_cleared": "The query log has been successfully cleared", "query_log_clear": "Clear query logs", "query_log_retention": "Query logs retention", @@ -182,6 +182,7 @@ "query_log_configuration": "Logs configuration", "query_log_disabled": "The query log is disabled and can be configured in the <0>settings</0>", "query_log_strict_search": "Use double quotes for strict search", + "query_log_retention_confirm": "Are you sure you want to change query log retention? If you decrease the interval value, some data will be lost", "source_label": "Source", "found_in_known_domain_db": "Found in the known domains database.", "category_label": "Category", @@ -378,6 +379,7 @@ "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_retention_confirm": "Are you sure you want to change statistics retention? If you decrease the interval value, some data will be lost", "statistics_cleared": "Statistics successfully cleared", "interval_hours": "{{count}} hour", "interval_hours_plural": "{{count}} hours", diff --git a/client/src/components/Settings/LogsConfig/Form.js b/client/src/components/Settings/LogsConfig/Form.js index e90c6487..3daf2b8d 100644 --- a/client/src/components/Settings/LogsConfig/Form.js +++ b/client/src/components/Settings/LogsConfig/Form.js @@ -7,7 +7,7 @@ import flow from 'lodash/flow'; import { renderSelectField, renderRadioField, toNumber } from '../../../helpers/form'; import { QUERY_LOG_INTERVALS_DAYS } from '../../../helpers/constants'; -const getIntervalFields = (processing, t, handleChange, toNumber) => +const getIntervalFields = (processing, t, toNumber) => QUERY_LOG_INTERVALS_DAYS.map((interval) => { const title = interval === 1 ? t('interval_24_hour') : t('interval_days', { count: interval }); @@ -20,7 +20,6 @@ const getIntervalFields = (processing, t, handleChange, toNumber) => component={renderRadioField} value={interval} placeholder={title} - onChange={handleChange} normalize={toNumber} disabled={processing} /> @@ -29,48 +28,56 @@ const getIntervalFields = (processing, t, handleChange, toNumber) => const Form = (props) => { const { - handleSubmit, handleChange, processing, t, + handleSubmit, submitting, invalid, processing, processingClear, handleClear, t, } = props; return ( <form onSubmit={handleSubmit}> - <div className="row"> - <div className="col-12"> - <div className="form__group form__group--settings"> - <Field - name="enabled" - type="checkbox" - component={renderSelectField} - placeholder={t('query_log_enable')} - onChange={handleChange} - disabled={processing} - /> - </div> - </div> - <div className="col-12"> - <label className="form__label"> - <Trans>query_log_retention</Trans> - </label> - </div> - <div className="col-12"> - <div className="form__group form__group--settings"> - <div className="custom-controls-stacked"> - {getIntervalFields(processing, t, handleChange, toNumber)} - </div> - </div> + <div className="form__group form__group--settings"> + <Field + name="enabled" + type="checkbox" + component={renderSelectField} + placeholder={t('query_log_enable')} + disabled={processing} + /> + </div> + <label className="form__label"> + <Trans>query_log_retention</Trans> + </label> + <div className="form__group form__group--settings"> + <div className="custom-controls-stacked"> + {getIntervalFields(processing, t, toNumber)} </div> </div> + <div className="mt-5"> + <button + type="submit" + className="btn btn-success btn-standard btn-large" + disabled={submitting || invalid || processing} + > + <Trans>save_btn</Trans> + </button> + <button + type="button" + className="btn btn-outline-secondary btn-standard ml-5" + onClick={() => handleClear()} + disabled={processingClear} + > + <Trans>query_log_clear</Trans> + </button> + </div> </form> ); }; Form.propTypes = { handleSubmit: PropTypes.func.isRequired, - handleChange: PropTypes.func, - change: PropTypes.func.isRequired, + handleClear: PropTypes.func.isRequired, submitting: PropTypes.bool.isRequired, invalid: PropTypes.bool.isRequired, processing: PropTypes.bool.isRequired, + processingClear: PropTypes.bool.isRequired, t: PropTypes.func.isRequired, }; diff --git a/client/src/components/Settings/LogsConfig/index.js b/client/src/components/Settings/LogsConfig/index.js index 8b519827..e45b785c 100644 --- a/client/src/components/Settings/LogsConfig/index.js +++ b/client/src/components/Settings/LogsConfig/index.js @@ -1,16 +1,24 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { withNamespaces, Trans } from 'react-i18next'; -import debounce from 'lodash/debounce'; +import { withNamespaces } from 'react-i18next'; -import { DEBOUNCE_TIMEOUT } from '../../../helpers/constants'; import Card from '../../ui/Card'; import Form from './Form'; class LogsConfig extends Component { - handleFormChange = debounce((values) => { - this.props.setLogsConfig(values); - }, DEBOUNCE_TIMEOUT); + handleFormSubmit = (values) => { + const { t, interval: prevInterval } = this.props; + const { interval } = values; + + if (interval !== prevInterval) { + // eslint-disable-next-line no-alert + if (window.confirm(t('query_log_retention_confirm'))) { + this.props.setLogsConfig(values); + } + } else { + this.props.setLogsConfig(values); + } + }; handleClear = () => { const { t, clearLogs } = this.props; @@ -37,19 +45,11 @@ class LogsConfig extends Component { enabled, interval, }} - onSubmit={this.handleFormChange} - onChange={this.handleFormChange} + onSubmit={this.handleFormSubmit} processing={processing} + processingClear={processingClear} + handleClear={this.handleClear} /> - - <button - type="button" - className="btn btn-outline-secondary btn-sm" - onClick={this.handleClear} - disabled={processingClear} - > - <Trans>query_log_clear</Trans> - </button> </div> </Card> ); diff --git a/client/src/components/Settings/StatsConfig/Form.js b/client/src/components/Settings/StatsConfig/Form.js index 7da5286f..5762ba69 100644 --- a/client/src/components/Settings/StatsConfig/Form.js +++ b/client/src/components/Settings/StatsConfig/Form.js @@ -7,7 +7,7 @@ import flow from 'lodash/flow'; import { renderRadioField, toNumber } from '../../../helpers/form'; import { STATS_INTERVALS_DAYS } from '../../../helpers/constants'; -const getIntervalFields = (processing, t, handleChange, toNumber) => +const getIntervalFields = (processing, t, toNumber) => STATS_INTERVALS_DAYS.map((interval) => { const title = interval === 1 ? t('interval_24_hour') : t('interval_days', { count: interval }); @@ -20,7 +20,6 @@ const getIntervalFields = (processing, t, handleChange, toNumber) => component={renderRadioField} value={interval} placeholder={title} - onChange={handleChange} normalize={toNumber} disabled={processing} /> @@ -29,39 +28,51 @@ const getIntervalFields = (processing, t, handleChange, toNumber) => const Form = (props) => { const { - handleSubmit, handleChange, processing, t, + handleSubmit, processing, submitting, invalid, handleReset, processingReset, t, } = props; return ( <form onSubmit={handleSubmit}> - <div className="row"> - <div className="col-12"> - <label className="form__label form__label--with-desc"> - <Trans>statistics_retention</Trans> - </label> - <div className="form__desc form__desc--top"> - <Trans>statistics_retention_desc</Trans> - </div> - </div> - <div className="col-12"> - <div className="form__group form__group--settings mt-2"> - <div className="custom-controls-stacked"> - {getIntervalFields(processing, t, handleChange, toNumber)} - </div> - </div> + <label className="form__label form__label--with-desc"> + <Trans>statistics_retention</Trans> + </label> + <div className="form__desc form__desc--top"> + <Trans>statistics_retention_desc</Trans> + </div> + <div className="form__group form__group--settings mt-2"> + <div className="custom-controls-stacked"> + {getIntervalFields(processing, t, toNumber)} </div> </div> + <div className="mt-5"> + <button + type="submit" + className="btn btn-success btn-standard btn-large" + disabled={submitting || invalid || processing} + > + <Trans>save_btn</Trans> + </button> + <button + type="button" + className="btn btn-outline-secondary btn-standard ml-5" + onClick={() => handleReset()} + disabled={processingReset} + > + <Trans>statistics_clear</Trans> + </button> + </div> </form> ); }; Form.propTypes = { handleSubmit: PropTypes.func.isRequired, - handleChange: PropTypes.func, + handleReset: PropTypes.func.isRequired, change: PropTypes.func.isRequired, submitting: PropTypes.bool.isRequired, invalid: PropTypes.bool.isRequired, processing: PropTypes.bool.isRequired, + processingReset: PropTypes.bool.isRequired, t: PropTypes.func.isRequired, }; diff --git a/client/src/components/Settings/StatsConfig/index.js b/client/src/components/Settings/StatsConfig/index.js index 86c23b38..79c3cdda 100644 --- a/client/src/components/Settings/StatsConfig/index.js +++ b/client/src/components/Settings/StatsConfig/index.js @@ -1,16 +1,18 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { withNamespaces, Trans } from 'react-i18next'; -import debounce from 'lodash/debounce'; +import { withNamespaces } from 'react-i18next'; -import { DEBOUNCE_TIMEOUT } from '../../../helpers/constants'; import Card from '../../ui/Card'; import Form from './Form'; class StatsConfig extends Component { - handleFormChange = debounce((values) => { - this.props.setStatsConfig(values); - }, DEBOUNCE_TIMEOUT); + handleFormSubmit = (values) => { + const { t } = this.props; + // eslint-disable-next-line no-alert + if (window.confirm(t('statistics_retention_confirm'))) { + this.props.setStatsConfig(values); + } + }; handleReset = () => { const { t, resetStats } = this.props; @@ -29,22 +31,12 @@ class StatsConfig extends Component { <Card title={t('statistics_configuration')} bodyType="card-body box-body--settings"> <div className="form"> <Form - initialValues={{ - interval, - }} - onSubmit={this.handleFormChange} - onChange={this.handleFormChange} + initialValues={{ interval }} + onSubmit={this.handleFormSubmit} processing={processing} + processingReset={processingReset} + handleReset={this.handleReset} /> - - <button - type="button" - className="btn btn-outline-secondary btn-sm" - onClick={this.handleReset} - disabled={processingReset} - > - <Trans>statistics_clear</Trans> - </button> </div> </Card> ); diff --git a/client/src/components/Settings/index.js b/client/src/components/Settings/index.js index 936e05c9..9c05f680 100644 --- a/client/src/components/Settings/index.js +++ b/client/src/components/Settings/index.js @@ -101,15 +101,6 @@ class Settings extends Component { </div> </Card> </div> - <div className="col-md-12"> - <StatsConfig - interval={stats.interval} - processing={stats.processingSetConfig} - processingReset={stats.processingReset} - setStatsConfig={setStatsConfig} - resetStats={resetStats} - /> - </div> <div className="col-md-12"> <LogsConfig enabled={queryLogs.enabled} @@ -120,6 +111,15 @@ class Settings extends Component { clearLogs={clearLogs} /> </div> + <div className="col-md-12"> + <StatsConfig + interval={stats.interval} + processing={stats.processingSetConfig} + processingReset={stats.processingReset} + setStatsConfig={setStatsConfig} + resetStats={resetStats} + /> + </div> <div className="col-md-12"> <Services services={services}