add filters config form
This commit is contained in:
@@ -37,7 +37,6 @@ const renderIcons = (iconsData: any) =>
|
|||||||
));
|
));
|
||||||
|
|
||||||
interface renderCheckboxFieldProps {
|
interface renderCheckboxFieldProps {
|
||||||
// https://redux-form.com/8.3.0/docs/api/field.md/#props
|
|
||||||
input: {
|
input: {
|
||||||
name: string;
|
name: string;
|
||||||
value: string;
|
value: string;
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Field, reduxForm } from 'redux-form';
|
|
||||||
import { Trans, withTranslation } from 'react-i18next';
|
|
||||||
import flow from 'lodash/flow';
|
|
||||||
|
|
||||||
import { CheckboxField, toNumber } from '../../../helpers/form';
|
|
||||||
import { FILTERS_INTERVALS_HOURS, FILTERS_RELATIVE_LINK, FORM_NAME } from '../../../helpers/constants';
|
|
||||||
|
|
||||||
const getTitleForInterval = (interval: any, t: any) => {
|
|
||||||
if (interval === 0) {
|
|
||||||
return t('disabled');
|
|
||||||
}
|
|
||||||
if (interval === 72 || interval === 168) {
|
|
||||||
return t('interval_days', { count: interval / 24 });
|
|
||||||
}
|
|
||||||
|
|
||||||
return t('interval_hours', { count: interval });
|
|
||||||
};
|
|
||||||
|
|
||||||
const getIntervalSelect = (processing: any, t: any, handleChange: any, toNumber: any) => (
|
|
||||||
<Field
|
|
||||||
name="interval"
|
|
||||||
className="custom-select"
|
|
||||||
component="select"
|
|
||||||
onChange={handleChange}
|
|
||||||
normalize={toNumber}
|
|
||||||
disabled={processing}>
|
|
||||||
{FILTERS_INTERVALS_HOURS.map((interval) => (
|
|
||||||
<option value={interval} key={interval}>
|
|
||||||
{getTitleForInterval(interval, t)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</Field>
|
|
||||||
);
|
|
||||||
|
|
||||||
interface FormProps {
|
|
||||||
handleSubmit: (...args: unknown[]) => string;
|
|
||||||
handleChange?: (...args: unknown[]) => unknown;
|
|
||||||
change: (...args: unknown[]) => unknown;
|
|
||||||
submitting: boolean;
|
|
||||||
invalid: boolean;
|
|
||||||
processing: boolean;
|
|
||||||
t: (...args: unknown[]) => string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Form = (props: FormProps) => {
|
|
||||||
const { handleSubmit, handleChange, processing, t } = props;
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
a: <a href={FILTERS_RELATIVE_LINK} rel="noopener noreferrer" />,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form onSubmit={handleSubmit}>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="form__group form__group--settings">
|
|
||||||
<Field
|
|
||||||
name="enabled"
|
|
||||||
type="checkbox"
|
|
||||||
modifier="checkbox--settings"
|
|
||||||
component={CheckboxField}
|
|
||||||
placeholder={t('block_domain_use_filters_and_hosts')}
|
|
||||||
subtitle={<Trans components={components}>filters_block_toggle_hint</Trans>}
|
|
||||||
onChange={handleChange}
|
|
||||||
disabled={processing}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-12 col-md-5">
|
|
||||||
<div className="form__group form__group--inner mb-5">
|
|
||||||
<label className="form__label">
|
|
||||||
<Trans>filters_interval</Trans>
|
|
||||||
</label>
|
|
||||||
{getIntervalSelect(processing, t, handleChange, toNumber)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default flow([withTranslation(), reduxForm({ form: FORM_NAME.FILTER_CONFIG })])(Form);
|
|
||||||
@@ -1,39 +1,105 @@
|
|||||||
import React from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import { withTranslation } from 'react-i18next';
|
import { useForm } from 'react-hook-form';
|
||||||
import debounce from 'lodash/debounce';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { DEBOUNCE_TIMEOUT } from '../../../helpers/constants';
|
import { toNumber } from '../../../helpers/form';
|
||||||
|
import { FILTERS_INTERVALS_HOURS, FILTERS_RELATIVE_LINK } from '../../../helpers/constants';
|
||||||
|
|
||||||
import Form from './Form';
|
const getTitleForInterval = (interval: any, t: any) => {
|
||||||
|
if (interval === 0) {
|
||||||
|
return t('disabled');
|
||||||
|
}
|
||||||
|
if (interval === 72 || interval === 168) {
|
||||||
|
return t('interval_days', { count: interval / 24 });
|
||||||
|
}
|
||||||
|
|
||||||
import { getObjDiff } from '../../../helpers/helpers';
|
return t('interval_hours', { count: interval });
|
||||||
|
|
||||||
interface FiltersConfigProps {
|
|
||||||
initialValues: object;
|
|
||||||
processing: boolean;
|
|
||||||
setFiltersConfig: (...args: unknown[]) => unknown;
|
|
||||||
t: (...args: unknown[]) => string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FiltersConfig = (props: FiltersConfigProps) => {
|
|
||||||
const { initialValues, processing } = props;
|
|
||||||
|
|
||||||
const handleFormChange = debounce((values) => {
|
|
||||||
const diff = getObjDiff(initialValues, values);
|
|
||||||
|
|
||||||
if (Object.values(diff).length > 0) {
|
|
||||||
props.setFiltersConfig(values);
|
|
||||||
}
|
|
||||||
}, DEBOUNCE_TIMEOUT);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form
|
|
||||||
initialValues={initialValues}
|
|
||||||
onSubmit={handleFormChange}
|
|
||||||
onChange={handleFormChange}
|
|
||||||
processing={processing}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withTranslation()(FiltersConfig);
|
export type FormValues = {
|
||||||
|
enabled: boolean;
|
||||||
|
interval: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
initialValues: FormValues;
|
||||||
|
setFiltersConfig: (values: FormValues) => void;
|
||||||
|
processing: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FiltersConfig = ({ initialValues, setFiltersConfig, processing }: Props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const prevFormValuesRef = useRef<FormValues>(initialValues);
|
||||||
|
|
||||||
|
const { register, watch } = useForm({
|
||||||
|
mode: 'onChange',
|
||||||
|
defaultValues: initialValues,
|
||||||
|
});
|
||||||
|
|
||||||
|
const formValues = watch();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const prevFormValues = prevFormValuesRef.current;
|
||||||
|
|
||||||
|
if (JSON.stringify(prevFormValues) !== JSON.stringify(formValues)) {
|
||||||
|
setFiltersConfig(formValues);
|
||||||
|
prevFormValuesRef.current = formValues;
|
||||||
|
}
|
||||||
|
}, [formValues]);
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
a: <a href={FILTERS_RELATIVE_LINK} rel="noopener noreferrer" />,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="form__group form__group--settings">
|
||||||
|
<label className="checkbox">
|
||||||
|
<span className="checkbox__marker" />
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="checkbox__input"
|
||||||
|
{...register('enabled')}
|
||||||
|
disabled={processing}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className="checkbox__label">
|
||||||
|
<span className="checkbox__label-text checkbox__label-text--long">
|
||||||
|
<span className="checkbox__label-title">
|
||||||
|
{t('block_domain_use_filters_and_hosts')}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<p>
|
||||||
|
<Trans components={components}>filters_block_toggle_hint</Trans>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-12 col-md-5">
|
||||||
|
<div className="form__group form__group--inner mb-5">
|
||||||
|
<label className="form__label">
|
||||||
|
<Trans>filters_interval</Trans>
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
{...register('interval', {
|
||||||
|
setValueAs: toNumber,
|
||||||
|
})}
|
||||||
|
className="custom-select"
|
||||||
|
disabled={processing}>
|
||||||
|
{FILTERS_INTERVALS_HOURS.map((interval) => (
|
||||||
|
<option value={interval} key={interval}>
|
||||||
|
{getTitleForInterval(interval, t)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import StatsConfig from './StatsConfig';
|
|||||||
|
|
||||||
import LogsConfig from './LogsConfig';
|
import LogsConfig from './LogsConfig';
|
||||||
|
|
||||||
import FiltersConfig from './FiltersConfig';
|
import { FiltersConfig } from './FiltersConfig';
|
||||||
|
|
||||||
import Checkbox from '../ui/Checkbox';
|
import Checkbox from '../ui/Checkbox';
|
||||||
|
|
||||||
@@ -136,23 +136,14 @@ class Settings extends Component<SettingsProps> {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
setStatsConfig,
|
setStatsConfig,
|
||||||
|
|
||||||
resetStats,
|
resetStats,
|
||||||
|
|
||||||
stats,
|
stats,
|
||||||
|
|
||||||
queryLogs,
|
queryLogs,
|
||||||
|
|
||||||
setLogsConfig,
|
setLogsConfig,
|
||||||
|
|
||||||
clearLogs,
|
clearLogs,
|
||||||
|
|
||||||
filtering,
|
filtering,
|
||||||
|
|
||||||
setFiltersConfig,
|
setFiltersConfig,
|
||||||
|
|
||||||
t,
|
t,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
@@ -163,6 +154,7 @@ class Settings extends Component<SettingsProps> {
|
|||||||
<PageTitle title={t('general_settings')} />
|
<PageTitle title={t('general_settings')} />
|
||||||
|
|
||||||
{!isDataReady && <Loading />}
|
{!isDataReady && <Loading />}
|
||||||
|
|
||||||
{isDataReady && (
|
{isDataReady && (
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import { ip4ToInt, isValidAbsolutePath } from './form';
|
|||||||
import { isIpInCidr, parseSubnetMask } from './helpers';
|
import { isIpInCidr, parseSubnetMask } from './helpers';
|
||||||
|
|
||||||
// Validation functions
|
// Validation functions
|
||||||
// https://redux-form.com/8.3.0/examples/fieldlevelvalidation/
|
|
||||||
// If the value is valid, the validation function should return undefined.
|
// If the value is valid, the validation function should return undefined.
|
||||||
/**
|
/**
|
||||||
* @param value {string|number}
|
* @param value {string|number}
|
||||||
|
|||||||
@@ -42,6 +42,4 @@ const Devices = ({ interfaces, dnsIp, dnsPort }: DevicesProps) => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default flow([
|
export default flow([withTranslation()])(Devices);
|
||||||
withTranslation(),
|
|
||||||
])(Devices);
|
|
||||||
|
|||||||
@@ -26,11 +26,8 @@ const Submit = (props: SubmitProps) => (
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* TODO props webIp webPort */}
|
|
||||||
<Controls openDashboard={props.openDashboard} ip={props.webIp} port={props.webPort} />
|
<Controls openDashboard={props.openDashboard} ip={props.webIp} port={props.webPort} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default flow([
|
export default flow([withTranslation()])(Submit);
|
||||||
withTranslation(),
|
|
||||||
])(Submit);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user