Skip to content

fix: Reduce frequency of identity search requests in frontend #5379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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<NodeJS.Timeout | null>(null)

const throttledFunc = function () {
const debouncedFunc = function () {
//eslint-disable-next-line
const args = arguments
if (timeout) {
Expand All @@ -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)
*/
27 changes: 27 additions & 0 deletions frontend/common/useDebouncedSearch.ts
Original file line number Diff line number Diff line change
@@ -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)
*/
6 changes: 3 additions & 3 deletions frontend/common/useInfiniteScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <
Expand All @@ -12,7 +12,7 @@ const useInfiniteScroll = <
>(
useGetDataListQuery: UseQuery<QueryDefinition<REQ, any, any, RES>>,
queryParameters: REQ,
throttle = 100,
throttle = 500,
queryOptions?: SubscriptionOptions & {
skip?: boolean
refetchOnMountOrArgChange?: boolean | number
Expand Down Expand Up @@ -54,7 +54,7 @@ const useInfiniteScroll = <
[queryResponse?.data]
)

const searchItems = useThrottle((search: string) => {
const searchItems = useDebounce((search: string) => {
if (q !== search) {
setLoadingCombinedData(true)
}
Expand Down
30 changes: 0 additions & 30 deletions frontend/common/useSearchThrottle.ts

This file was deleted.

13 changes: 2 additions & 11 deletions frontend/web/components/AuditLog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -35,16 +35,7 @@ type AuditLogType = {
const widths = [210, 310, 150]
const AuditLog: FC<AuditLogType> = (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,
})
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/components/ConversionEventSelect.tsx
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -13,7 +13,7 @@ const ConversionEventSelect: FC<ConversionEventSelectType> = ({
environmentId,
onChange,
}) => {
const { search, searchInput, setSearchInput } = useSearchThrottle('')
const { search, searchInput, setSearchInput } = useDebouncedSearch('')
const { data } = useGetConversionEventsQuery({
environment_id: ProjectStore.getEnvironmentIdFromKey(environmentId),
q: `${search}`,
Expand Down
13 changes: 2 additions & 11 deletions frontend/web/components/modals/CreateSegment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -602,16 +602,7 @@ const LoadingCreateSegment: FC<LoadingCreateSegmentType> = (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) {
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/components/pages/SegmentsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -45,7 +45,7 @@ const SegmentsPage: FC<SegmentsPageType> = (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',
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/components/pages/SplitTestPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -38,7 +38,7 @@ const innerWidths = [200, 150, 150]
const SplitTestPage: FC<AuditLogType> = (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)
Expand Down
12 changes: 4 additions & 8 deletions frontend/web/components/pages/UserPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down Expand Up @@ -138,11 +138,7 @@ const UserPage: FC<UserPageType> = (props) => {
useState<Record<string, IdentityFeatureState>>()
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,
Expand Down Expand Up @@ -952,9 +948,9 @@ const UserPage: FC<UserPageType> = (props) => {
className='no-pad'
title='Segments'
isLoading={isFetchingSegments}
search={segmentSearchInput}
search={searchInput}
onChange={(e) => {
setSegmentSearchInput(
setSearchInput(
Utils.safeParseEventValue(e),
)
}}
Expand Down
13 changes: 2 additions & 11 deletions frontend/web/components/pages/UsersPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -78,16 +78,7 @@ const UsersPage: FC<UsersPageType> = (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')

Expand Down
12 changes: 2 additions & 10 deletions frontend/web/components/tables/TableValueFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -34,15 +34,7 @@ const TableTagFilter: FC<TableFilterType> = ({
onChange,
value,
}) => {
const { searchInput, setSearchInput } = useSearchThrottle(
value.valueSearch || '',
() => {
onChange({
enabled: value.enabled,
valueSearch: searchInput,
})
},
)
const { searchInput, setSearchInput } = useDebouncedSearch('')

return (
<div className={isLoading ? 'disabled' : ''}>
Expand Down
Loading