diff --git a/frontend/src/container/LogControls/index.tsx b/frontend/src/container/LogControls/index.tsx index 6f55b8f531..ef8b8819a8 100644 --- a/frontend/src/container/LogControls/index.tsx +++ b/frontend/src/container/LogControls/index.tsx @@ -5,19 +5,14 @@ import { } from '@ant-design/icons'; import { Button, Divider, Select } from 'antd'; import React, { memo } from 'react'; -import { connect, useDispatch, useSelector } from 'react-redux'; -import { bindActionCreators, Dispatch } from 'redux'; -import { ThunkDispatch } from 'redux-thunk'; -import { getLogs } from 'store/actions/logs/getLogs'; +import { useDispatch, useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; -import AppActions from 'types/actions'; import { GET_NEXT_LOG_LINES, GET_PREVIOUS_LOG_LINES, RESET_ID_START_AND_END, SET_LOG_LINES_PER_PAGE, } from 'types/actions/logs'; -import { GlobalReducer } from 'types/reducer/globalTime'; import { ILogsReducer } from 'types/reducer/logs'; import { Container } from './styles'; @@ -26,20 +21,10 @@ const { Option } = Select; const ITEMS_PER_PAGE_OPTIONS = [25, 50, 100, 200]; -interface LogControlsProps { - getLogs: (props: Parameters[0]) => ReturnType; -} -function LogControls({ getLogs }: LogControlsProps): JSX.Element | null { - const { maxTime, minTime } = useSelector( - (state) => state.globalTime, +function LogControls(): JSX.Element | null { + const { logLinesPerPage, liveTail } = useSelector( + (state) => state.logs, ); - const { - logLinesPerPage, - idStart, - idEnd, - liveTail, - searchFilter: { queryString }, - } = useSelector((state) => state.logs); const dispatch = useDispatch(); const handleLogLinesPerPageChange = (e: number): void => { @@ -53,18 +38,6 @@ function LogControls({ getLogs }: LogControlsProps): JSX.Element | null { dispatch({ type: RESET_ID_START_AND_END, }); - - if (liveTail === 'STOPPED') - getLogs({ - q: queryString, - limit: logLinesPerPage, - orderBy: 'timestamp', - order: 'desc', - timestampStart: minTime, - timestampEnd: maxTime, - ...(idStart ? { idGt: idStart } : {}), - ...(idEnd ? { idLt: idEnd } : {}), - }); }; const handleNavigatePrevious = (): void => { @@ -106,16 +79,4 @@ function LogControls({ getLogs }: LogControlsProps): JSX.Element | null { ); } -interface DispatchProps { - getLogs: ( - props: Parameters[0], - ) => (dispatch: Dispatch) => void; -} - -const mapDispatchToProps = ( - dispatch: ThunkDispatch, -): DispatchProps => ({ - getLogs: bindActionCreators(getLogs, dispatch), -}); - -export default connect(null, mapDispatchToProps)(memo(LogControls)); +export default memo(LogControls); diff --git a/frontend/src/container/LogsSearchFilter/index.tsx b/frontend/src/container/LogsSearchFilter/index.tsx index cf71f3d3bd..c8f4a9021e 100644 --- a/frontend/src/container/LogsSearchFilter/index.tsx +++ b/frontend/src/container/LogsSearchFilter/index.tsx @@ -1,7 +1,14 @@ import { Input, InputRef, Popover } from 'antd'; import useUrlQuery from 'hooks/useUrlQuery'; import getStep from 'lib/getStep'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { debounce } from 'lodash-es'; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import { connect, useDispatch, useSelector } from 'react-redux'; import { bindActionCreators, Dispatch } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; @@ -22,12 +29,31 @@ function SearchFilter({ getLogsAggregate, }: SearchFilterProps): JSX.Element { const { - queryString, updateParsedQuery, updateQueryString, + queryString, } = useSearchParser(); + const [searchText, setSearchText] = useState(queryString); const [showDropDown, setShowDropDown] = useState(false); const searchRef = useRef(null); + const { logLinesPerPage, idEnd, idStart, liveTail } = useSelector< + AppState, + ILogsReducer + >((state) => state.logs); + const { maxTime, minTime } = useSelector( + (state) => state.globalTime, + ); + const dispatch = useDispatch>(); + + // keep sync with url queryString + useEffect(() => { + setSearchText(queryString); + }, [queryString]); + + const debouncedupdateQueryString = useMemo( + () => debounce(updateQueryString, 300), + [updateQueryString], + ); const onDropDownToggleHandler = useCallback( (value: boolean) => (): void => { @@ -36,17 +62,6 @@ function SearchFilter({ [], ); - const { logLinesPerPage, idEnd, idStart, liveTail } = useSelector< - AppState, - ILogsReducer - >((state) => state.logs); - - const { maxTime, minTime } = useSelector( - (state) => state.globalTime, - ); - - const dispatch = useDispatch>(); - const handleSearch = useCallback( (customQuery) => { if (liveTail === 'PLAYING') { @@ -102,10 +117,14 @@ function SearchFilter({ const urlQuery = useUrlQuery(); const urlQueryString = urlQuery.get('q'); + const debouncedHandleSearch = useMemo(() => debounce(handleSearch, 600), [ + handleSearch, + ]); + useEffect(() => { - handleSearch(urlQueryString || ''); + debouncedHandleSearch(urlQueryString || ''); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [urlQueryString, maxTime, minTime]); + }, [urlQueryString, maxTime, minTime, idEnd, idStart]); return ( @@ -132,9 +151,11 @@ function SearchFilter({ { - updateQueryString(e.target.value); + const { value } = e.target; + setSearchText(value); + debouncedupdateQueryString(value); }} allowClear onSearch={handleSearch} diff --git a/frontend/src/container/LogsSearchFilter/useSearchParser.ts b/frontend/src/container/LogsSearchFilter/useSearchParser.ts index 7bb43eeea0..588f37cf9e 100644 --- a/frontend/src/container/LogsSearchFilter/useSearchParser.ts +++ b/frontend/src/container/LogsSearchFilter/useSearchParser.ts @@ -23,12 +23,10 @@ export function useSearchParser(): { const updateQueryString = useCallback( (updatedQueryString) => { - if (updatedQueryString) { - history.push({ - pathname: history.location.pathname, - search: updatedQueryString ? `?q=${updatedQueryString}` : '', - }); - } + history.replace({ + pathname: history.location.pathname, + search: updatedQueryString ? `?q=${updatedQueryString}` : '', + }); dispatch({ type: SET_SEARCH_QUERY_STRING,