diff --git a/client/src/components/Logs/Filters/Form.tsx b/client/src/components/Logs/Filters/Form.tsx
index f1b5b7be..317062e0 100644
--- a/client/src/components/Logs/Filters/Form.tsx
+++ b/client/src/components/Logs/Filters/Form.tsx
@@ -1,15 +1,14 @@
import React, { useEffect } from 'react';
-import { Field, type InjectedFormProps, reduxForm } from 'redux-form';
import { useTranslation } from 'react-i18next';
-import { shallowEqual, useDispatch, useSelector } from 'react-redux';
+import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
import classNames from 'classnames';
+import { useForm } from 'react-hook-form';
import {
DEBOUNCE_FILTER_TIMEOUT,
DEFAULT_LOGS_FILTER,
- FORM_NAME,
RESPONSE_FILTER,
RESPONSE_FILTER_QUERIES,
} from '../../../helpers/constants';
@@ -18,182 +17,115 @@ import useDebounce from '../../../helpers/useDebounce';
import { createOnBlurHandler, getLogsUrlParams } from '../../../helpers/helpers';
-import Tooltip from '../../ui/Tooltip';
-import { RootState } from '../../../initialState';
+import { SearchField } from './SearchField';
-interface renderFilterFieldProps {
- input: {
- value: string;
- };
- id: string;
- onClearInputClick: (...args: unknown[]) => unknown;
- className?: string;
- placeholder?: string;
- type?: string;
- disabled?: boolean;
- autoComplete?: string;
- tooltip?: string;
- onKeyDown?: (...args: unknown[]) => unknown;
- normalizeOnBlur?: (...args: unknown[]) => unknown;
- meta: {
- touched?: boolean;
- error?: object;
- };
+export type FormValues = {
+ search: string;
+ response_status: string;
}
-const renderFilterField = ({
- input,
- id,
- className,
- placeholder,
- type,
- disabled,
- autoComplete,
- tooltip,
- meta: { touched, error },
- onClearInputClick,
- onKeyDown,
- normalizeOnBlur,
-}: renderFilterFieldProps) => {
- const onBlur = (event: any) => createOnBlurHandler(event, input, normalizeOnBlur);
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {!disabled && touched && error && {error}}
- >
- );
-};
-
-const FORM_NAMES = {
- search: 'search',
- response_status: 'response_status',
-};
-
-type FiltersFormProps = {
+type Props = {
+ initialValues: FormValues;
className?: string;
- responseStatusClass?: string;
setIsLoading: (...args: unknown[]) => unknown;
};
-const Form = (props: FiltersFormProps & InjectedFormProps) => {
- const { className = '', responseStatusClass, setIsLoading, change } = props;
-
+export const Form = ({ initialValues, className, setIsLoading }: Props) => {
const { t } = useTranslation();
const dispatch = useDispatch();
const history = useHistory();
- const { response_status, search } = useSelector(
- (state: RootState) => state?.form[FORM_NAME.LOGS_FILTER].values,
- shallowEqual,
- );
+ const {
+ register,
+ watch,
+ setValue,
+ } = useForm({
+ mode: 'onChange',
+ defaultValues: {
+ search: initialValues.search || DEFAULT_LOGS_FILTER.search,
+ response_status: initialValues.response_status || DEFAULT_LOGS_FILTER.response_status,
+ },
+ });
- const [debouncedSearch, setDebouncedSearch] = useDebounce(search.trim(), DEBOUNCE_FILTER_TIMEOUT);
+ const searchValue = watch('search');
+ const responseStatusValue = watch('response_status');
+
+ const [debouncedSearch, setDebouncedSearch] = useDebounce(
+ searchValue.trim(),
+ DEBOUNCE_FILTER_TIMEOUT
+ );
useEffect(() => {
dispatch(
setLogsFilter({
- response_status,
+ response_status: responseStatusValue,
search: debouncedSearch,
}),
);
- history.replace(`${getLogsUrlParams(debouncedSearch, response_status)}`);
- }, [response_status, debouncedSearch]);
+ history.replace(`${getLogsUrlParams(debouncedSearch, responseStatusValue)}`);
+ }, [responseStatusValue, debouncedSearch]);
- if (response_status && !(response_status in RESPONSE_FILTER_QUERIES)) {
- change(FORM_NAMES.response_status, DEFAULT_LOGS_FILTER[FORM_NAMES.response_status]);
- }
+ useEffect(() => {
+ if (responseStatusValue && !(responseStatusValue in RESPONSE_FILTER_QUERIES)) {
+ setValue('response_status', DEFAULT_LOGS_FILTER.response_status);
+ }
+ }, [responseStatusValue, setValue]);
const onInputClear = async () => {
setIsLoading(true);
- change(FORM_NAMES.search, DEFAULT_LOGS_FILTER[FORM_NAMES.search]);
+ setValue('search', DEFAULT_LOGS_FILTER.search);
setIsLoading(false);
};
- const onEnterPress = (e: any) => {
+ const onEnterPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
- setDebouncedSearch(search);
+ setDebouncedSearch(searchValue);
}
};
- const normalizeOnBlur = (data: any) => data.trim();
+ const handleBlur = (e: React.FocusEvent) =>
+ createOnBlurHandler(
+ e,
+ {
+ value: e.target.value,
+ onChange: (v: string) => setValue('search', v),
+ },
+ (data: string) => data.trim()
+ );
return (
);
};
-
-export const FiltersForm = reduxForm, FiltersFormProps>({
- form: FORM_NAME.LOGS_FILTER,
- enableReinitialize: true,
-})(Form);
diff --git a/client/src/components/Logs/Filters/SearchField.tsx b/client/src/components/Logs/Filters/SearchField.tsx
new file mode 100644
index 00000000..1113bba0
--- /dev/null
+++ b/client/src/components/Logs/Filters/SearchField.tsx
@@ -0,0 +1,56 @@
+import React, { ComponentProps } from 'react';
+import Tooltip from '../../ui/Tooltip';
+
+interface Props extends ComponentProps<'input'> {
+ handleChange: (newValue: string) => void;
+ onClear: () => void;
+ tooltip?: string;
+}
+
+export const SearchField = ({
+ handleChange,
+ onClear,
+ value,
+ tooltip,
+ className,
+ ...rest
+}: Props) => {
+ const handleInputChange = (e: React.ChangeEvent) => {
+ handleChange(e.target.value);
+ };
+
+ return (
+ <>
+
+
+
+
+ {typeof value === 'string' && value.length > 0 && (
+
+
+
+ )}
+ {tooltip && (
+
+
+
+
+
+ )}
+ >
+ );
+};
diff --git a/client/src/components/Logs/Filters/index.tsx b/client/src/components/Logs/Filters/index.tsx
index dfdbf3ec..d2c5c37a 100644
--- a/client/src/components/Logs/Filters/index.tsx
+++ b/client/src/components/Logs/Filters/index.tsx
@@ -2,17 +2,17 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
-import { FiltersForm } from './Form';
+import { Form, FormValues } from './Form';
import { refreshFilteredLogs } from '../../../actions/queryLogs';
import { addSuccessToast } from '../../../actions/toasts';
interface FiltersProps {
- filter: object;
+ initialValues: FormValues;
processingGetLogs: boolean;
setIsLoading: (...args: unknown[]) => unknown;
}
-const Filters = ({ filter, setIsLoading }: FiltersProps) => {
+const Filters = ({ initialValues, setIsLoading }: FiltersProps) => {
const { t } = useTranslation();
const dispatch = useDispatch();
@@ -38,7 +38,10 @@ const Filters = ({ filter, setIsLoading }: FiltersProps) => {
-
+
);
};
diff --git a/client/src/components/Logs/index.tsx b/client/src/components/Logs/index.tsx
index b98bc6f9..63bc557f 100644
--- a/client/src/components/Logs/index.tsx
+++ b/client/src/components/Logs/index.tsx
@@ -175,7 +175,7 @@ const Logs = () => {
const renderPage = () => (
<>