Skip to content

Commit

Permalink
Debounce keyword validation request. (#18343)
Browse files Browse the repository at this point in the history
* Debounce keyword validation request.

* Cleanup code.

* Adding changelog.

* Remove not needed import.
  • Loading branch information
linuspahl authored Feb 21, 2024
1 parent 74930ad commit 3cf9f89
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 12 deletions.
4 changes: 4 additions & 0 deletions changelog/unreleased/pr-18343.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type = "c"
message = "Improve keyword validation in time range picker."

pulls = ["18219"]
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jest.mock('stores/tools/ToolsStore', () => ({
testNaturalDate: jest.fn(),
}));

jest.mock('views/logic/debounceWithPromise', () => (fn: any) => fn);

const TabKeywordTimeRange = ({ defaultValue, ...props }: { defaultValue: string } & React.ComponentProps<typeof TabKeywordTimeRange>) => (
<Formik initialValues={{ timeRangeTabs: { keyword: { type: 'keyword', keyword: defaultValue } }, activeTab: 'keyword' }}
onSubmit={() => {}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ import ToolsStore from 'stores/tools/ToolsStore';
import type { KeywordTimeRange } from 'views/logic/queries/Query';
import useUserDateTime from 'hooks/useUserDateTime';
import { InputDescription } from 'components/common';
import debounceWithPromise from 'views/logic/debounceWithPromise';

import { EMPTY_RANGE } from '../TimeRangeDisplay';

type KeywordPreview = { from: string, to: string, timezone: string }

const Headline = styled.h3`
margin-bottom: 5px;
`;
Expand Down Expand Up @@ -62,27 +65,41 @@ const _parseKeywordPreview = (data: Pick<KeywordTimeRange, 'from' | 'to' | 'time
type Props = {
defaultValue: string,
disabled: boolean,
setValidatingKeyword: (boolean) => void
setValidatingKeyword: (isValidating: boolean) => void
};

const debouncedTestNaturalDate = debounceWithPromise((
keyword: string,
userTZ: string,
mounted: React.RefObject<boolean>,
setSuccessfulPreview: (response: KeywordPreview) => void,
setFailedPreview: () => void,
) => ToolsStore.testNaturalDate(keyword, userTZ).then((response) => {
if (mounted.current) {
setSuccessfulPreview(response);
}
}).catch(() => {
setFailedPreview();

return 'Unable to parse keyword.';
}), 350);

const TabKeywordTimeRange = ({ defaultValue, disabled, setValidatingKeyword }: Props) => {
const { formatTime, userTimezone } = useUserDateTime();
const [nextRangeProps, , nextRangeHelpers] = useField('timeRangeTabs.keyword');
const mounted = useRef(true);
const keywordRef = useRef<string>();
const [keywordPreview, setKeywordPreview] = useState({ from: '', to: '', timezone: '' });
const [keywordPreview, setKeywordPreview] = useState<KeywordPreview>({ from: '', to: '', timezone: '' });

const _setSuccessfulPreview = useCallback((response: { from: string, to: string, timezone: string }) => {
const _setSuccessfulPreview = useCallback((response: KeywordPreview) => {
setValidatingKeyword(false);

return setKeywordPreview(_parseKeywordPreview(response, formatTime));
setKeywordPreview(_parseKeywordPreview(response, formatTime));
},
[setValidatingKeyword, formatTime]);

const _setFailedPreview = useCallback(() => {
setKeywordPreview({ from: EMPTY_RANGE, to: EMPTY_RANGE, timezone: userTimezone });

return 'Unable to parse keyword.';
}, [userTimezone]);

const _validateKeyword = useCallback((keyword: string) => {
Expand All @@ -97,11 +114,7 @@ const TabKeywordTimeRange = ({ defaultValue, disabled, setValidatingKeyword }: P

return trim(keyword) === ''
? Promise.resolve('Keyword must not be empty!')
: ToolsStore.testNaturalDate(keyword, userTimezone)
.then((response) => {
if (mounted.current) _setSuccessfulPreview(response);
})
.catch(_setFailedPreview);
: debouncedTestNaturalDate(keyword, userTimezone, mounted, _setSuccessfulPreview, _setFailedPreview);
}

return undefined;
Expand All @@ -125,7 +138,7 @@ const TabKeywordTimeRange = ({ defaultValue, disabled, setValidatingKeyword }: P
keyword,
...restPreview,
...keywordPreview,
});
}, false);
}
}
}, [nextRangeProps.value, keywordPreview, nextRangeHelpers]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { adminUser } from 'fixtures/users';
import OriginalTimeRangePicker from './TimeRangePicker';

jest.mock('hooks/useCurrentUser');
jest.mock('views/logic/debounceWithPromise', () => (fn: any) => fn);

jest.mock('views/stores/SearchConfigStore', () => ({
SearchConfigActions: {
Expand Down

0 comments on commit 3cf9f89

Please sign in to comment.