client: add ignore domains for stats
This commit is contained in:
parent
eefc3891d0
commit
24d75c4376
|
@ -523,6 +523,7 @@
|
||||||
"statistics_retention_confirm": "Are you sure you want to change statistics retention? If you decrease the interval value, some data will be lost",
|
"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",
|
"statistics_cleared": "Statistics successfully cleared",
|
||||||
"statistics_enable": "Enable statistics",
|
"statistics_enable": "Enable statistics",
|
||||||
|
"statistics_ignore_domains": "Ignore domains (separated by newline)",
|
||||||
"interval_hours": "{{count}} hour",
|
"interval_hours": "{{count}} hour",
|
||||||
"interval_hours_plural": "{{count}} hours",
|
"interval_hours_plural": "{{count}} hours",
|
||||||
"filters_configuration": "Filters configuration",
|
"filters_configuration": "Filters configuration",
|
||||||
|
|
|
@ -13,7 +13,7 @@ export const getStatsConfigSuccess = createAction('GET_STATS_CONFIG_SUCCESS');
|
||||||
export const getStatsConfig = () => async (dispatch) => {
|
export const getStatsConfig = () => async (dispatch) => {
|
||||||
dispatch(getStatsConfigRequest());
|
dispatch(getStatsConfigRequest());
|
||||||
try {
|
try {
|
||||||
const data = await apiClient.getStatsInfo();
|
const data = await apiClient.getStatsConfig();
|
||||||
dispatch(getStatsConfigSuccess(data));
|
dispatch(getStatsConfigSuccess(data));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(addErrorToast({ error }));
|
dispatch(addErrorToast({ error }));
|
||||||
|
|
|
@ -497,9 +497,9 @@ class Api {
|
||||||
// Settings for statistics
|
// Settings for statistics
|
||||||
GET_STATS = { path: 'stats', method: 'GET' };
|
GET_STATS = { path: 'stats', method: 'GET' };
|
||||||
|
|
||||||
STATS_INFO = { path: 'stats_info', method: 'GET' };
|
GET_STATS_CONFIG = { path: 'stats/config', method: 'GET' };
|
||||||
|
|
||||||
STATS_CONFIG = { path: 'stats_config', method: 'POST' };
|
UPDATE_STATS_CONFIG = { path: 'stats/config/update', method: 'PUT' };
|
||||||
|
|
||||||
STATS_RESET = { path: 'stats_reset', method: 'POST' };
|
STATS_RESET = { path: 'stats_reset', method: 'POST' };
|
||||||
|
|
||||||
|
@ -508,13 +508,13 @@ class Api {
|
||||||
return this.makeRequest(path, method);
|
return this.makeRequest(path, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatsInfo() {
|
getStatsConfig() {
|
||||||
const { path, method } = this.STATS_INFO;
|
const { path, method } = this.GET_STATS_CONFIG;
|
||||||
return this.makeRequest(path, method);
|
return this.makeRequest(path, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
setStatsConfig(data) {
|
setStatsConfig(data) {
|
||||||
const { path, method } = this.STATS_CONFIG;
|
const { path, method } = this.UPDATE_STATS_CONFIG;
|
||||||
const config = {
|
const config = {
|
||||||
data,
|
data,
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,23 +4,31 @@ import { Field, reduxForm } from 'redux-form';
|
||||||
import { Trans, withTranslation } from 'react-i18next';
|
import { Trans, withTranslation } from 'react-i18next';
|
||||||
import flow from 'lodash/flow';
|
import flow from 'lodash/flow';
|
||||||
|
|
||||||
import { renderRadioField, toNumber, CheckboxField } from '../../../helpers/form';
|
import {
|
||||||
import { FORM_NAME, STATS_INTERVALS_DAYS, DISABLED_STATS_INTERVAL } from '../../../helpers/constants';
|
renderRadioField,
|
||||||
|
toNumber,
|
||||||
|
CheckboxField,
|
||||||
|
renderTextareaField,
|
||||||
|
} from '../../../helpers/form';
|
||||||
|
import {
|
||||||
|
FORM_NAME,
|
||||||
|
STATS_INTERVALS_DAYS,
|
||||||
|
DAY,
|
||||||
|
} from '../../../helpers/constants';
|
||||||
import '../FormButton.css';
|
import '../FormButton.css';
|
||||||
|
|
||||||
const getIntervalTitle = (interval, t) => {
|
const getIntervalTitle = (intervalMs, t) => {
|
||||||
switch (interval) {
|
switch (intervalMs / DAY) {
|
||||||
case 1:
|
case 1:
|
||||||
return t('interval_24_hour');
|
return t('interval_24_hour');
|
||||||
default:
|
default:
|
||||||
return t('interval_days', { count: interval });
|
return t('interval_days', { count: intervalMs / DAY });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Form = (props) => {
|
const Form = (props) => {
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
change,
|
|
||||||
processing,
|
processing,
|
||||||
submitting,
|
submitting,
|
||||||
invalid,
|
invalid,
|
||||||
|
@ -38,13 +46,6 @@ const Form = (props) => {
|
||||||
component={CheckboxField}
|
component={CheckboxField}
|
||||||
placeholder={t('statistics_enable')}
|
placeholder={t('statistics_enable')}
|
||||||
disabled={processing}
|
disabled={processing}
|
||||||
onChange={(event) => {
|
|
||||||
if (event.target.checked) {
|
|
||||||
change('interval', STATS_INTERVALS_DAYS[0]);
|
|
||||||
} else {
|
|
||||||
change('interval', DISABLED_STATS_INTERVAL);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<label className="form__label form__label--with-desc">
|
<label className="form__label form__label--with-desc">
|
||||||
|
@ -65,15 +66,19 @@ const Form = (props) => {
|
||||||
placeholder={getIntervalTitle(interval, t)}
|
placeholder={getIntervalTitle(interval, t)}
|
||||||
normalize={toNumber}
|
normalize={toNumber}
|
||||||
disabled={processing}
|
disabled={processing}
|
||||||
onChange={(event) => {
|
|
||||||
if (event.target.checked) {
|
|
||||||
change('enabled', true);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="form__group form__group--settings">
|
||||||
|
<Field
|
||||||
|
name="ignored"
|
||||||
|
type="textarea"
|
||||||
|
component={renderTextareaField}
|
||||||
|
placeholder={t('statistics_ignore_domains')}
|
||||||
|
disabled={processing}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="mt-5">
|
<div className="mt-5">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|
|
@ -6,9 +6,13 @@ import Card from '../../ui/Card';
|
||||||
import Form from './Form';
|
import Form from './Form';
|
||||||
|
|
||||||
class StatsConfig extends Component {
|
class StatsConfig extends Component {
|
||||||
handleFormSubmit = (values) => {
|
handleFormSubmit = ({ enabled, interval, ignored }) => {
|
||||||
const { t, interval: prevInterval } = this.props;
|
const { t, interval: prevInterval } = this.props;
|
||||||
const config = { interval: values.interval };
|
const config = {
|
||||||
|
enabled,
|
||||||
|
interval,
|
||||||
|
ignored: ignored ? ignored.split('\n') : [],
|
||||||
|
};
|
||||||
|
|
||||||
if (config.interval < prevInterval) {
|
if (config.interval < prevInterval) {
|
||||||
if (window.confirm(t('statistics_retention_confirm'))) {
|
if (window.confirm(t('statistics_retention_confirm'))) {
|
||||||
|
@ -29,7 +33,7 @@ class StatsConfig extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
t, interval, processing, processingReset,
|
t, interval, processing, processingReset, ignored, enabled,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -42,7 +46,8 @@ class StatsConfig extends Component {
|
||||||
<Form
|
<Form
|
||||||
initialValues={{
|
initialValues={{
|
||||||
interval,
|
interval,
|
||||||
enabled: !!interval,
|
enabled,
|
||||||
|
ignored: ignored.join('\n'),
|
||||||
}}
|
}}
|
||||||
onSubmit={this.handleFormSubmit}
|
onSubmit={this.handleFormSubmit}
|
||||||
processing={processing}
|
processing={processing}
|
||||||
|
@ -57,6 +62,8 @@ class StatsConfig extends Component {
|
||||||
|
|
||||||
StatsConfig.propTypes = {
|
StatsConfig.propTypes = {
|
||||||
interval: PropTypes.number.isRequired,
|
interval: PropTypes.number.isRequired,
|
||||||
|
ignored: PropTypes.array.isRequired,
|
||||||
|
enabled: PropTypes.bool.isRequired,
|
||||||
processing: PropTypes.bool.isRequired,
|
processing: PropTypes.bool.isRequired,
|
||||||
processingReset: PropTypes.bool.isRequired,
|
processingReset: PropTypes.bool.isRequired,
|
||||||
setStatsConfig: PropTypes.func.isRequired,
|
setStatsConfig: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -109,6 +109,8 @@ class Settings extends Component {
|
||||||
<div className="col-md-12">
|
<div className="col-md-12">
|
||||||
<StatsConfig
|
<StatsConfig
|
||||||
interval={stats.interval}
|
interval={stats.interval}
|
||||||
|
ignored={stats.ignored}
|
||||||
|
enabled={stats.enabled}
|
||||||
processing={stats.processingSetConfig}
|
processing={stats.processingSetConfig}
|
||||||
processingReset={stats.processingReset}
|
processingReset={stats.processingReset}
|
||||||
setStatsConfig={setStatsConfig}
|
setStatsConfig={setStatsConfig}
|
||||||
|
@ -139,6 +141,8 @@ Settings.propTypes = {
|
||||||
stats: PropTypes.shape({
|
stats: PropTypes.shape({
|
||||||
processingGetConfig: PropTypes.bool,
|
processingGetConfig: PropTypes.bool,
|
||||||
interval: PropTypes.number,
|
interval: PropTypes.number,
|
||||||
|
enabled: PropTypes.bool,
|
||||||
|
ignored: PropTypes.array,
|
||||||
processingSetConfig: PropTypes.bool,
|
processingSetConfig: PropTypes.bool,
|
||||||
processingReset: PropTypes.bool,
|
processingReset: PropTypes.bool,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -211,7 +211,12 @@ export const FILTERED = 'Filtered';
|
||||||
export const NOT_FILTERED = 'NotFiltered';
|
export const NOT_FILTERED = 'NotFiltered';
|
||||||
|
|
||||||
export const DISABLED_STATS_INTERVAL = 0;
|
export const DISABLED_STATS_INTERVAL = 0;
|
||||||
export const STATS_INTERVALS_DAYS = [1, 7, 30, 90];
|
|
||||||
|
export const HOUR = 60 * 60 * 1000;
|
||||||
|
|
||||||
|
export const DAY = HOUR * 24;
|
||||||
|
|
||||||
|
export const STATS_INTERVALS_DAYS = [DAY, DAY * 7, DAY * 30, DAY * 90];
|
||||||
|
|
||||||
export const QUERY_LOG_INTERVALS_DAYS = [0.25, 1, 7, 30, 90];
|
export const QUERY_LOG_INTERVALS_DAYS = [0.25, 1, 7, 30, 90];
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ const stats = handleActions(
|
||||||
[actions.getStatsConfigFailure]: (state) => ({ ...state, processingGetConfig: false }),
|
[actions.getStatsConfigFailure]: (state) => ({ ...state, processingGetConfig: false }),
|
||||||
[actions.getStatsConfigSuccess]: (state, { payload }) => ({
|
[actions.getStatsConfigSuccess]: (state, { payload }) => ({
|
||||||
...state,
|
...state,
|
||||||
interval: payload.interval,
|
...payload,
|
||||||
processingGetConfig: false,
|
processingGetConfig: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ const stats = handleActions(
|
||||||
[actions.setStatsConfigFailure]: (state) => ({ ...state, processingSetConfig: false }),
|
[actions.setStatsConfigFailure]: (state) => ({ ...state, processingSetConfig: false }),
|
||||||
[actions.setStatsConfigSuccess]: (state, { payload }) => ({
|
[actions.setStatsConfigSuccess]: (state, { payload }) => ({
|
||||||
...state,
|
...state,
|
||||||
interval: payload.interval,
|
...payload,
|
||||||
processingSetConfig: false,
|
processingSetConfig: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue