diff --git a/lib/DynamicSelection/DynamicSelection.js b/lib/DynamicSelection/DynamicSelection.js index 343a6fc0..db0468f6 100644 --- a/lib/DynamicSelection/DynamicSelection.js +++ b/lib/DynamicSelection/DynamicSelection.js @@ -22,8 +22,8 @@ export const DynamicSelection = ({ const { options = initialOptions, isLoading, - inputValue, - setInputValue, + searchQuery, + setSearchQuery, } = useDebouncedQuery({ api, dataFormatter, @@ -31,15 +31,15 @@ export const DynamicSelection = ({ }); const onFilter = useCallback((filterValue) => { - setInputValue(filterValue); + setSearchQuery(filterValue); return options; - }, [options, setInputValue]); + }, [options, setSearchQuery]); return ( } + emptyMessage={!searchQuery && } loading={isLoading} loadingMessage={} name={name} diff --git a/lib/DynamicSelection/DynamicSelection.test.js b/lib/DynamicSelection/DynamicSelection.test.js index b8b73124..379b44cd 100644 --- a/lib/DynamicSelection/DynamicSelection.test.js +++ b/lib/DynamicSelection/DynamicSelection.test.js @@ -14,8 +14,8 @@ jest.mock('../hooks', () => ({ useDebouncedQuery: jest.fn(() => ({ options: [], isLoading: false, - inputValue: '', - setInputValue: jest.fn(), + searchQuery: '', + setSearchQuery: jest.fn(), })), })); @@ -51,7 +51,7 @@ describe('DynamicSelection', () => { isLoading: false, options: [{ label: '11111', value: 'poLine-1' }], inputValue: '', - setInputValue: mockSetInputValue, + setSearchQuery: mockSetInputValue, }); }); diff --git a/lib/DynamicSelectionFilter/DynamicSelectionFilter.test.js b/lib/DynamicSelectionFilter/DynamicSelectionFilter.test.js index 4b882869..563f788a 100644 --- a/lib/DynamicSelectionFilter/DynamicSelectionFilter.test.js +++ b/lib/DynamicSelectionFilter/DynamicSelectionFilter.test.js @@ -18,8 +18,8 @@ jest.mock('../hooks', () => ({ useDebouncedQuery: jest.fn(() => ({ options: [{ label: '11111', value: 'poLine-1' }], isLoading: false, - inputValue: '', - setInputValue: jest.fn(), + searchQuery: '', + setSearchQuery: jest.fn(), })), })); diff --git a/lib/hooks/useDebouncedQuery/useDebouncedQuery.js b/lib/hooks/useDebouncedQuery/useDebouncedQuery.js index ebc0cba3..fa187e79 100644 --- a/lib/hooks/useDebouncedQuery/useDebouncedQuery.js +++ b/lib/hooks/useDebouncedQuery/useDebouncedQuery.js @@ -12,30 +12,31 @@ import { const LIST_ITEMS_LIMIT = 100; const DEBOUNCE_DELAY = 500; +const DEFAULT_DATA_FORMATTER = (data) => data; export const useDebouncedQuery = ({ api, queryBuilder, - dataFormatter, + dataFormatter = DEFAULT_DATA_FORMATTER, debounceDelay = DEBOUNCE_DELAY, limit = LIST_ITEMS_LIMIT, }) => { - const [inputValue, setInputValue] = useState(''); + const [searchQuery, setSearchQuery] = useState(''); const [options, setOptions] = useState([]); + const [namespace] = useNamespace({ key: api }); const ky = useOkapiKy(); - const [namespace] = useNamespace({ key: 'debounced-query' }); - const debouncedSetInputValue = useMemo(() => { - return debounce((value) => setInputValue(value), debounceDelay); + const debounceSetSearchQuery = useMemo(() => { + return debounce((value) => setSearchQuery(value), debounceDelay); }, [debounceDelay]); const { isLoading } = useQuery({ - queryKey: [namespace, inputValue], + queryKey: [namespace, searchQuery], queryFn: async ({ signal }) => { - if (!inputValue) return []; + if (!searchQuery) return []; const searchParams = { - query: queryBuilder(inputValue), + query: queryBuilder(searchQuery), limit, }; @@ -43,7 +44,7 @@ export const useDebouncedQuery = ({ return dataFormatter(res); }, - enabled: Boolean(inputValue), + enabled: Boolean(searchQuery), onSuccess: (data) => { setOptions(data); }, @@ -55,7 +56,7 @@ export const useDebouncedQuery = ({ return { options, isLoading, - inputValue, - setInputValue: debouncedSetInputValue, + searchQuery, + setSearchQuery: debounceSetSearchQuery, }; }; diff --git a/lib/hooks/useDebouncedQuery/useDebouncedQuery.test.js b/lib/hooks/useDebouncedQuery/useDebouncedQuery.test.js index 265a1535..f2ea128b 100644 --- a/lib/hooks/useDebouncedQuery/useDebouncedQuery.test.js +++ b/lib/hooks/useDebouncedQuery/useDebouncedQuery.test.js @@ -9,6 +9,7 @@ import { useOkapiKy } from '@folio/stripes/core'; import { useDebouncedQuery } from './useDebouncedQuery'; const DELAY = 300; +const mockData = { poLines: [{ id: 'poLine-1', poLineNumber: '11111' }] }; jest.useFakeTimers('modern'); const mockDataFormatter = jest.fn(({ poLines }) => { @@ -27,7 +28,7 @@ describe('useDebouncedQuery', () => { jest.clearAllMocks(); useOkapiKy.mockReturnValue({ get: jest.fn(() => ({ - json: () => Promise.resolve({ poLines: [{ id: 'poLine-1', poLineNumber: '11111' }] }), + json: () => Promise.resolve(mockData), })), }); }); @@ -41,7 +42,7 @@ describe('useDebouncedQuery', () => { }), { wrapper }); await act(async () => { - await result.current.setInputValue(''); + await result.current.setSearchQuery(''); jest.advanceTimersByTime(1500); }); @@ -57,11 +58,25 @@ describe('useDebouncedQuery', () => { }), { wrapper }); await act(async () => { - await result.current.setInputValue('test'); + await result.current.setSearchQuery('test'); jest.advanceTimersByTime(1500); }); expect(mockDataFormatter).toHaveBeenCalledTimes(1); expect(result.current.options).toEqual([{ label: '11111', value: 'poLine-1' }]); }); + + it('should call default `dataFormatter` when `dataFormatter` is not present', async () => { + const { result } = renderHook(() => useDebouncedQuery({ + api: 'api', + queryBuilder: jest.fn(), + }), { wrapper }); + + await act(async () => { + await result.current.setSearchQuery('test'); + jest.advanceTimersByTime(1500); + }); + + expect(result.current.options).toEqual(mockData); + }); });