add filters config form
This commit is contained in:
@@ -37,7 +37,6 @@ const renderIcons = (iconsData: any) =>
|
||||
));
|
||||
|
||||
interface renderCheckboxFieldProps {
|
||||
// https://redux-form.com/8.3.0/docs/api/field.md/#props
|
||||
input: {
|
||||
name: 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 { withTranslation } from 'react-i18next';
|
||||
import debounce from 'lodash/debounce';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
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';
|
||||
|
||||
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}
|
||||
/>
|
||||
);
|
||||
return t('interval_hours', { count: interval });
|
||||
};
|
||||
|
||||
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 FiltersConfig from './FiltersConfig';
|
||||
import { FiltersConfig } from './FiltersConfig';
|
||||
|
||||
import Checkbox from '../ui/Checkbox';
|
||||
|
||||
@@ -136,23 +136,14 @@ class Settings extends Component<SettingsProps> {
|
||||
render() {
|
||||
const {
|
||||
settings,
|
||||
|
||||
setStatsConfig,
|
||||
|
||||
resetStats,
|
||||
|
||||
stats,
|
||||
|
||||
queryLogs,
|
||||
|
||||
setLogsConfig,
|
||||
|
||||
clearLogs,
|
||||
|
||||
filtering,
|
||||
|
||||
setFiltersConfig,
|
||||
|
||||
t,
|
||||
} = this.props;
|
||||
|
||||
@@ -163,6 +154,7 @@ class Settings extends Component<SettingsProps> {
|
||||
<PageTitle title={t('general_settings')} />
|
||||
|
||||
{!isDataReady && <Loading />}
|
||||
|
||||
{isDataReady && (
|
||||
<div className="content">
|
||||
<div className="row">
|
||||
|
||||
@@ -24,7 +24,6 @@ import { ip4ToInt, isValidAbsolutePath } from './form';
|
||||
import { isIpInCidr, parseSubnetMask } from './helpers';
|
||||
|
||||
// Validation functions
|
||||
// https://redux-form.com/8.3.0/examples/fieldlevelvalidation/
|
||||
// If the value is valid, the validation function should return undefined.
|
||||
/**
|
||||
* @param value {string|number}
|
||||
|
||||
@@ -42,6 +42,4 @@ const Devices = ({ interfaces, dnsIp, dnsPort }: DevicesProps) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
export default flow([
|
||||
withTranslation(),
|
||||
])(Devices);
|
||||
export default flow([withTranslation()])(Devices);
|
||||
|
||||
@@ -26,11 +26,8 @@ const Submit = (props: SubmitProps) => (
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* TODO props webIp webPort */}
|
||||
<Controls openDashboard={props.openDashboard} ip={props.webIp} port={props.webPort} />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default flow([
|
||||
withTranslation(),
|
||||
])(Submit);
|
||||
export default flow([withTranslation()])(Submit);
|
||||
|
||||
Reference in New Issue
Block a user