client: add ignore domains for stats

This commit is contained in:
Vladislav Abdulmyanov 2023-03-21 18:21:13 +02:00
parent eefc3891d0
commit 24d75c4376
8 changed files with 53 additions and 31 deletions

View File

@ -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",

View File

@ -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 }));

View File

@ -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,
}; };

View File

@ -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"

View File

@ -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,

View File

@ -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,
}), }),

View File

@ -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];

View File

@ -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,
}), }),