import { useCallback, useEffect } from 'react'; import { useDebounce } from 'react-use'; import { backendSrv } from 'app/core/services/backend_srv'; import { SearchSrv } from 'app/core/services/search_srv'; import { FETCH_RESULTS, FETCH_ITEMS, TOGGLE_SECTION, SEARCH_START, FETCH_ITEMS_START } from '../reducers/actionTypes'; import { DashboardSection, UseSearch } from '../types'; import { hasId, getParsedQuery } from '../utils'; const searchSrv = new SearchSrv(); /** * Base hook for search functionality. * Returns state and dispatch, among others, from 'reducer' param, so it can be * further extended. * @param query * @param reducer - return result of useReducer * @param params - custom params */ export const useSearch: UseSearch = (query, reducer, params = {}) => { const { queryParsing } = params; const [state, dispatch] = reducer; const search = () => { dispatch({ type: SEARCH_START }); const parsedQuery = getParsedQuery(query, queryParsing); searchSrv.search(parsedQuery).then((results) => { dispatch({ type: FETCH_RESULTS, payload: results }); }); }; // Set loading state before debounced search useEffect(() => { dispatch({ type: SEARCH_START }); }, [query.tag, query.sort, query.starred, query.layout, dispatch]); useDebounce(search, 300, [query, queryParsing]); const onToggleSection = useCallback( (section: DashboardSection) => { if (hasId(section.title) && !section.items.length) { dispatch({ type: FETCH_ITEMS_START, payload: section.id }); backendSrv.search({ folderIds: [section.id] }).then((items) => { dispatch({ type: FETCH_ITEMS, payload: { section, items } }); dispatch({ type: TOGGLE_SECTION, payload: section }); }); } else { dispatch({ type: TOGGLE_SECTION, payload: section }); } }, [dispatch] ); return { state, dispatch, onToggleSection }; };