diff --git a/frontend/common/useThrottle.ts b/frontend/common/useDebounce.ts similarity index 68% rename from frontend/common/useThrottle.ts rename to frontend/common/useDebounce.ts index 01e4239f1dcc..c526e508c09b 100644 --- a/frontend/common/useThrottle.ts +++ b/frontend/common/useDebounce.ts @@ -1,9 +1,9 @@ import { useState } from 'react' -export default function useThrottle(func: any, delay: number) { +export default function useDebounce(func: any, delay: number) { const [timeout, saveTimeout] = useState(null) - const throttledFunc = function () { + const debouncedFunc = function () { //eslint-disable-next-line const args = arguments if (timeout) { @@ -20,10 +20,10 @@ export default function useThrottle(func: any, delay: number) { saveTimeout(newTimeout) } - return throttledFunc as typeof func + return debouncedFunc as typeof func } /* Usage example: -const searchItems = useThrottle((search:string) => { +const searchItems = useDebounce((search:string) => { doThing() -}, 100) +}, 500) */ diff --git a/frontend/common/useDebouncedSearch.ts b/frontend/common/useDebouncedSearch.ts new file mode 100644 index 000000000000..7901b7bccddd --- /dev/null +++ b/frontend/common/useDebouncedSearch.ts @@ -0,0 +1,27 @@ +import { useState } from 'react' +import useDebounce from './useDebounce' + +export default function useDebouncedSearch(initialValue = '') { + const [searchInput, setSearchInput] = useState(initialValue) + const [search, setSearch] = useState(initialValue) + + const debouncedSearch = useDebounce((value: string) => { + setSearch(value) + }, 500) + + const handleSearchInput = (value: string) => { + setSearchInput(value) + debouncedSearch(value) + } + + return { + search, + searchInput, + setSearchInput: handleSearchInput + } +} +/* Usage example: +const searchItems = useDebounce((search:string) => { + doThing() +}, 500) +*/ diff --git a/frontend/common/useInfiniteScroll.ts b/frontend/common/useInfiniteScroll.ts index c3cd56b40338..1f3d3c1866f8 100644 --- a/frontend/common/useInfiniteScroll.ts +++ b/frontend/common/useInfiniteScroll.ts @@ -3,7 +3,7 @@ import { useCallback, useEffect, useState } from 'react' import { PagedRequest } from './types/requests' import { PagedResponse } from './types/responses' import { QueryDefinition } from '@reduxjs/toolkit/query' -import useThrottle from './useThrottle' +import useDebounce from './useDebounce' import { SubscriptionOptions } from '@reduxjs/toolkit/src/query/core/apiState' const useInfiniteScroll = < @@ -12,7 +12,7 @@ const useInfiniteScroll = < >( useGetDataListQuery: UseQuery>, queryParameters: REQ, - throttle = 100, + throttle = 500, queryOptions?: SubscriptionOptions & { skip?: boolean refetchOnMountOrArgChange?: boolean | number @@ -54,7 +54,7 @@ const useInfiniteScroll = < [queryResponse?.data] ) - const searchItems = useThrottle((search: string) => { + const searchItems = useDebounce((search: string) => { if (q !== search) { setLoadingCombinedData(true) } diff --git a/frontend/common/useSearchThrottle.ts b/frontend/common/useSearchThrottle.ts deleted file mode 100644 index 5f3d62c3666b..000000000000 --- a/frontend/common/useSearchThrottle.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { useEffect, useRef, useState } from 'react' -import useThrottle from './useThrottle' - -export default function useSearchThrottle( - defaultValue?: string, - cb?: () => void, -) { - const firstRender = useRef(true) - const [search, setSearch] = useState(defaultValue || '') - const [searchInput, setSearchInput] = useState(search) - const searchItems = useThrottle((search: string) => { - setSearch(search) - cb?.() - }, 100) - useEffect(() => { - if (firstRender.current && !searchInput) { - firstRender.current = false - return - } - firstRender.current = false - searchItems(searchInput) - //eslint-disable-next-line - }, [searchInput]); - return { search, searchInput, setSearchInput } -} -/* Usage example: -const searchItems = useThrottle((search:string) => { - doThing() -}, 100) -*/ diff --git a/frontend/web/components/AuditLog.tsx b/frontend/web/components/AuditLog.tsx index be8731926882..f0f145975b15 100644 --- a/frontend/web/components/AuditLog.tsx +++ b/frontend/web/components/AuditLog.tsx @@ -2,7 +2,7 @@ import React, { FC, ReactNode, useEffect, useRef, useState } from 'react' // we import Utils from 'common/utils/utils' import { AuditLogItem, Environment } from 'common/types/responses' import { useGetAuditLogsQuery } from 'common/services/useAuditLog' -import useSearchThrottle from 'common/useSearchThrottle' +import useDebouncedSearch from 'common/useDebouncedSearch' import { Link, withRouter } from 'react-router-dom' import ProjectStore from 'common/stores/project-store' import Button from './base/forms/Button' @@ -35,16 +35,7 @@ type AuditLogType = { const widths = [210, 310, 150] const AuditLog: FC = (props) => { const [page, setPage] = useState(Utils.fromParam().page ?? 1) - const { search, searchInput, setSearchInput } = useSearchThrottle( - Utils.fromParam().search, - () => { - if (searchInput !== search) { - return setPage(1) - } - - setPage(Utils.fromParam().page) - }, - ) + const { search, searchInput, setSearchInput } = useDebouncedSearch() const { data: subscriptionMeta } = useGetSubscriptionMetadataQuery({ id: AccountStore.getOrganisation()?.id, }) diff --git a/frontend/web/components/ConversionEventSelect.tsx b/frontend/web/components/ConversionEventSelect.tsx index 64f7f608519d..97ef0c9ec31d 100644 --- a/frontend/web/components/ConversionEventSelect.tsx +++ b/frontend/web/components/ConversionEventSelect.tsx @@ -1,6 +1,6 @@ import React, { FC, useEffect, useState } from 'react' import { useGetConversionEventsQuery } from 'common/services/useConversionEvent' -import useSearchThrottle from 'common/useSearchThrottle' +import useDebouncedSearch from 'common/useDebouncedSearch' import { ConversionEvent } from 'common/types/responses' import ProjectStore from 'common/stores/project-store' @@ -13,7 +13,7 @@ const ConversionEventSelect: FC = ({ environmentId, onChange, }) => { - const { search, searchInput, setSearchInput } = useSearchThrottle('') + const { search, searchInput, setSearchInput } = useDebouncedSearch('') const { data } = useGetConversionEventsQuery({ environment_id: ProjectStore.getEnvironmentIdFromKey(environmentId), q: `${search}`, diff --git a/frontend/web/components/modals/CreateSegment.tsx b/frontend/web/components/modals/CreateSegment.tsx index 294f3040f28b..3d51af8724fc 100644 --- a/frontend/web/components/modals/CreateSegment.tsx +++ b/frontend/web/components/modals/CreateSegment.tsx @@ -8,7 +8,6 @@ import React, { } from 'react' import Constants from 'common/constants' -import useSearchThrottle from 'common/useSearchThrottle' import AccountStore from 'common/stores/account-store' import { EdgePagedResponse, @@ -45,6 +44,7 @@ import { useGetSupportedContentTypeQuery } from 'common/services/useSupportedCon import { setInterceptClose } from './base/ModalDefault' import CreateSegmentRulesTabForm from './CreateSegmentRulesTabForm' import CreateSegmentUsersTabContent from './CreateSegmentUsersTabContent' +import useDebouncedSearch from 'common/useDebouncedSearch' type PageType = { number: number @@ -602,16 +602,7 @@ const LoadingCreateSegment: FC = (props) => { pages: undefined, }) - const { search, searchInput, setSearchInput } = useSearchThrottle( - Utils.fromParam().search, - () => { - setPage({ - number: 1, - pageType: undefined, - pages: undefined, - }) - }, - ) + const { search, searchInput, setSearchInput } = useDebouncedSearch('') useEffect(() => { if (segmentData) { diff --git a/frontend/web/components/pages/SegmentsPage.tsx b/frontend/web/components/pages/SegmentsPage.tsx index 62e3499e1907..41627e0822fc 100644 --- a/frontend/web/components/pages/SegmentsPage.tsx +++ b/frontend/web/components/pages/SegmentsPage.tsx @@ -3,7 +3,7 @@ import { RouterChildContext } from 'react-router' import { find, sortBy } from 'lodash' import Constants from 'common/constants' -import useSearchThrottle from 'common/useSearchThrottle' +import useDebouncedSearch from 'common/useDebouncedSearch' import { Environment, Segment } from 'common/types/responses' import { useDeleteSegmentMutation, @@ -45,7 +45,7 @@ const SegmentsPage: FC = (props) => { )?.api_key const params = Utils.fromParam() const id = params.id - const { search, searchInput, setSearchInput } = useSearchThrottle('') + const { search, searchInput, setSearchInput } = useDebouncedSearch('') const [page, setPage] = useState(1) const [showFeatureSpecific, setShowFeatureSpecific] = useState( params.featureSpecific === 'true', diff --git a/frontend/web/components/pages/SplitTestPage.tsx b/frontend/web/components/pages/SplitTestPage.tsx index 7128c5413dac..9915eaa1570a 100644 --- a/frontend/web/components/pages/SplitTestPage.tsx +++ b/frontend/web/components/pages/SplitTestPage.tsx @@ -14,7 +14,7 @@ import { useGetConversionEventsQuery } from 'common/services/useConversionEvent' import InfoMessage from 'components/InfoMessage' import PanelSearch from 'components/PanelSearch' import ErrorMessage from 'components/ErrorMessage' -import useSearchThrottle from 'common/useSearchThrottle' +import useDebouncedSearch from 'common/useDebouncedSearch' import { useGetSplitTestQuery } from 'common/services/useSplitTest' import { IonIcon } from '@ionic/react' import { chevronDown, chevronForward } from 'ionicons/icons' @@ -38,7 +38,7 @@ const innerWidths = [200, 150, 150] const SplitTestPage: FC = (props) => { const projectId = props.match.params.projectId const environmentId = props.match.params.environmentId - const { search, searchInput, setSearchInput } = useSearchThrottle() + const { search, searchInput, setSearchInput } = useDebouncedSearch() const [conversion_event_type_id, setConversionEvent] = useState< number | null >(null) diff --git a/frontend/web/components/pages/UserPage.tsx b/frontend/web/components/pages/UserPage.tsx index 94a4955fe903..5c0753b494b4 100644 --- a/frontend/web/components/pages/UserPage.tsx +++ b/frontend/web/components/pages/UserPage.tsx @@ -61,7 +61,7 @@ import SegmentsIcon from 'components/svg/SegmentsIcon' import UsersIcon from 'components/svg/UsersIcon' import IdentityTraits from 'components/IdentityTraits' import { useGetIdentitySegmentsQuery } from 'common/services/useIdentitySegment' -import useSearchThrottle from 'common/useSearchThrottle' +import useDebouncedSearch from 'common/useDebouncedSearch' const width = [200, 48, 78] @@ -138,11 +138,7 @@ const UserPage: FC = (props) => { useState>() const [preselect, setPreselect] = useState(Utils.fromParam().flag) const [segmentsPage, setSegmentsPage] = useState(1) - const { - search, - searchInput: segmentSearchInput, - setSearchInput: setSegmentSearchInput, - } = useSearchThrottle('') + const { search, searchInput, setSearchInput } = useDebouncedSearch('') const { data: segments, isFetching: isFetchingSegments, @@ -952,9 +948,9 @@ const UserPage: FC = (props) => { className='no-pad' title='Segments' isLoading={isFetchingSegments} - search={segmentSearchInput} + search={searchInput} onChange={(e) => { - setSegmentSearchInput( + setSearchInput( Utils.safeParseEventValue(e), ) }} diff --git a/frontend/web/components/pages/UsersPage.tsx b/frontend/web/components/pages/UsersPage.tsx index 68a91aa76bd9..3399d8ec1995 100644 --- a/frontend/web/components/pages/UsersPage.tsx +++ b/frontend/web/components/pages/UsersPage.tsx @@ -9,7 +9,7 @@ import { deleteIdentity, useGetIdentitiesQuery, } from 'common/services/useIdentity' -import useSearchThrottle from 'common/useSearchThrottle' +import useDebouncedSearch from 'common/useDebouncedSearch' import { Req } from 'common/types/requests' import CreateUserModal from 'components/modals/CreateUser' import PanelSearch from 'components/PanelSearch' @@ -78,16 +78,7 @@ const UsersPage: FC = (props) => { pages: Req['getIdentities']['pages'] }>({ number: 1, pageType: undefined, pages: undefined }) - const { search, searchInput, setSearchInput } = useSearchThrottle( - Utils.fromParam().search, - () => { - setPage({ - number: 1, - pageType: undefined, - pages: undefined, - }) - }, - ) + const { search, searchInput, setSearchInput } = useDebouncedSearch('') const isEdge = Utils.getIsEdge() const showAliases = isEdge && Utils.getFlagsmithHasFeature('identity_aliases') diff --git a/frontend/web/components/tables/TableValueFilter.tsx b/frontend/web/components/tables/TableValueFilter.tsx index c4503fde1b62..2c33ae00e886 100644 --- a/frontend/web/components/tables/TableValueFilter.tsx +++ b/frontend/web/components/tables/TableValueFilter.tsx @@ -2,7 +2,7 @@ import React, { FC, useEffect, useMemo, useRef, useState } from 'react' import TableFilter from './TableFilter' import Utils from 'common/utils/utils' import InputGroup from 'components/base/forms/InputGroup' -import useSearchThrottle from 'common/useSearchThrottle' +import useDebouncedSearch from 'common/useDebouncedSearch' type TableFilterType = { value: { @@ -34,15 +34,7 @@ const TableTagFilter: FC = ({ onChange, value, }) => { - const { searchInput, setSearchInput } = useSearchThrottle( - value.valueSearch || '', - () => { - onChange({ - enabled: value.enabled, - valueSearch: searchInput, - }) - }, - ) + const { searchInput, setSearchInput } = useDebouncedSearch('') return (