Skip to content

Commit abe8996

Browse files
authored
Merge pull request Expensify#77757 from abzokhattab/fix/debounce-searchforreports-inputs
Debounce server search in selectors
2 parents b3e7be7 + 984e0f6 commit abe8996

8 files changed

Lines changed: 162 additions & 63 deletions

File tree

src/pages/InviteReportParticipantsPage.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,20 @@ function InviteReportParticipantsPage({report}: InviteReportParticipantsPageProp
5959
return res;
6060
}, [report]);
6161

62-
const {searchTerm, setSearchTerm, availableOptions, selectedOptions, selectedOptionsForDisplay, toggleSelection, areOptionsInitialized, onListEndReached} = useSearchSelector({
63-
selectionMode: CONST.SEARCH_SELECTOR.SELECTION_MODE_MULTI,
64-
searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_MEMBER_INVITE,
65-
includeUserToInvite: true,
66-
excludeLogins: excludedUsers,
67-
includeRecentReports: true,
68-
shouldInitialize: didScreenTransitionEnd,
69-
});
62+
const {searchTerm, debouncedSearchTerm, setSearchTerm, availableOptions, selectedOptions, selectedOptionsForDisplay, toggleSelection, areOptionsInitialized, onListEndReached} =
63+
useSearchSelector({
64+
selectionMode: CONST.SEARCH_SELECTOR.SELECTION_MODE_MULTI,
65+
searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_MEMBER_INVITE,
66+
includeUserToInvite: true,
67+
excludeLogins: excludedUsers,
68+
includeRecentReports: true,
69+
shouldInitialize: didScreenTransitionEnd,
70+
});
7071

7172
useEffect(() => {
72-
updateUserSearchPhrase(searchTerm);
73-
searchInServer(searchTerm);
74-
}, [searchTerm]);
73+
updateUserSearchPhrase(debouncedSearchTerm);
74+
searchInServer(debouncedSearchTerm);
75+
}, [debouncedSearchTerm]);
7576

7677
const sections = useMemo(() => {
7778
const sectionsArray: Sections = [];
@@ -149,7 +150,7 @@ function InviteReportParticipantsPage({report}: InviteReportParticipantsPageProp
149150
}, [selectedOptions, goBack, reportID, validate, formatPhoneNumber]);
150151

151152
const headerMessage = useMemo(() => {
152-
const processedLogin = searchTerm.trim().toLowerCase();
153+
const processedLogin = debouncedSearchTerm.trim().toLowerCase();
153154
const expensifyEmails = CONST.EXPENSIFY_EMAILS;
154155
if (!availableOptions.userToInvite && expensifyEmails.includes(processedLogin)) {
155156
return translate('messages.errorMessageInvalidEmail');
@@ -170,7 +171,7 @@ function InviteReportParticipantsPage({report}: InviteReportParticipantsPageProp
170171
false,
171172
);
172173
}, [
173-
searchTerm,
174+
debouncedSearchTerm,
174175
availableOptions.userToInvite,
175176
availableOptions.recentReports.length,
176177
availableOptions.personalDetails.length,

src/pages/OnboardingWorkspaceInvite/BaseOnboardingWorkspaceInvite.tsx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,15 @@ function BaseOnboardingWorkspaceInvite({shouldUseNativeStyles}: BaseOnboardingWo
6868
);
6969
}, [policy?.employeeList]);
7070

71-
const {searchTerm, setSearchTerm, availableOptions, selectedOptions, selectedOptionsForDisplay, toggleSelection, areOptionsInitialized, searchOptions} = useSearchSelector({
72-
selectionMode: CONST.SEARCH_SELECTOR.SELECTION_MODE_MULTI,
73-
searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_MEMBER_INVITE,
74-
includeUserToInvite: true,
75-
excludeLogins: excludedUsers,
76-
includeRecentReports: false,
77-
shouldInitialize: didScreenTransitionEnd,
78-
});
71+
const {searchTerm, debouncedSearchTerm, setSearchTerm, availableOptions, selectedOptions, selectedOptionsForDisplay, toggleSelection, areOptionsInitialized, searchOptions} =
72+
useSearchSelector({
73+
selectionMode: CONST.SEARCH_SELECTOR.SELECTION_MODE_MULTI,
74+
searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_MEMBER_INVITE,
75+
includeUserToInvite: true,
76+
excludeLogins: excludedUsers,
77+
includeRecentReports: false,
78+
shouldInitialize: didScreenTransitionEnd,
79+
});
7980

8081
const welcomeNoteSubject = useMemo(
8182
() => `# ${currentUserPersonalDetails?.displayName ?? ''} invited you to ${policy?.name ?? 'a workspace'}`,
@@ -85,8 +86,8 @@ function BaseOnboardingWorkspaceInvite({shouldUseNativeStyles}: BaseOnboardingWo
8586
const welcomeNote = useMemo(() => translate('workspace.common.welcomeNote'), [translate]);
8687

8788
useEffect(() => {
88-
searchInServer(searchTerm);
89-
}, [searchTerm]);
89+
searchInServer(debouncedSearchTerm);
90+
}, [debouncedSearchTerm]);
9091

9192
const sections: Sections[] = useMemo(() => {
9293
const sectionsArr: Sections[] = [];
@@ -194,7 +195,7 @@ function BaseOnboardingWorkspaceInvite({shouldUseNativeStyles}: BaseOnboardingWo
194195
}, [completeOnboarding, onboardingPolicyID, policy?.employeeList, selectedOptions, welcomeNote, welcomeNoteSubject, formatPhoneNumber]);
195196

196197
const headerMessage = useMemo(() => {
197-
const searchValue = searchTerm.trim().toLowerCase();
198+
const searchValue = debouncedSearchTerm.trim().toLowerCase();
198199
if (!availableOptions.userToInvite && CONST.EXPENSIFY_EMAILS_OBJECT[searchValue]) {
199200
return translate('messages.errorMessageInvalidEmail');
200201
}
@@ -206,7 +207,7 @@ function BaseOnboardingWorkspaceInvite({shouldUseNativeStyles}: BaseOnboardingWo
206207
}
207208
return getHeaderMessage(searchOptions.personalDetails.length + selectedOptions.length !== 0, !!searchOptions.userToInvite, searchValue, countryCode, false);
208209
}, [
209-
searchTerm,
210+
debouncedSearchTerm,
210211
availableOptions.userToInvite,
211212
excludedUsers,
212213
countryCode,

src/pages/iou/request/MoneyRequestParticipantsSelector.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ function MoneyRequestParticipantsSelector({
215215
[isIOUSplit, iouType, onParticipantsAdded],
216216
);
217217

218-
const {searchTerm, setSearchTerm, availableOptions, selectedOptions, toggleSelection, areOptionsInitialized, onListEndReached, contactState} = useSearchSelector({
218+
const {searchTerm, debouncedSearchTerm, setSearchTerm, availableOptions, selectedOptions, toggleSelection, areOptionsInitialized, onListEndReached, contactState} = useSearchSelector({
219219
selectionMode: isIOUSplit ? CONST.SEARCH_SELECTOR.SELECTION_MODE_MULTI : CONST.SEARCH_SELECTOR.SELECTION_MODE_SINGLE,
220220
searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_GENERAL,
221221
includeUserToInvite: !isCategorizeOrShareAction && !isPerDiemRequest,
@@ -236,19 +236,19 @@ function MoneyRequestParticipantsSelector({
236236
},
237237
});
238238

239-
const cleanSearchTerm = useMemo(() => searchTerm.trim().toLowerCase(), [searchTerm]);
239+
const cleanSearchTerm = useMemo(() => debouncedSearchTerm.trim().toLowerCase(), [debouncedSearchTerm]);
240240

241241
useEffect(() => {
242-
searchInServer(searchTerm.trim());
243-
}, [searchTerm]);
242+
searchInServer(debouncedSearchTerm.trim());
243+
}, [debouncedSearchTerm]);
244244

245245
const inputHelperText = useMemo(
246246
() =>
247247
getHeaderMessage(
248248
(availableOptions.personalDetails ?? []).length + (availableOptions.recentReports ?? []).length + (availableOptions.workspaceChats ?? []).length !== 0 ||
249249
!isEmptyObject(availableOptions.selfDMChat),
250250
!!availableOptions?.userToInvite,
251-
searchTerm.trim(),
251+
debouncedSearchTerm.trim(),
252252
countryCode,
253253
participants.some((participant) => getPersonalDetailSearchTerms(participant).join(' ').toLowerCase().includes(cleanSearchTerm)),
254254
),
@@ -261,7 +261,7 @@ function MoneyRequestParticipantsSelector({
261261
availableOptions?.userToInvite,
262262
availableOptions.workspaceChats,
263263
cleanSearchTerm,
264-
searchTerm,
264+
debouncedSearchTerm,
265265
participants,
266266
countryCode,
267267
],

src/pages/settings/Profile/CustomStatus/VacationDelegatePage.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function VacationDelegatePage() {
3535
const [vacationDelegate] = useOnyx(ONYXKEYS.NVP_PRIVATE_VACATION_DELEGATE, {canBeMissing: true});
3636
const currentVacationDelegate = vacationDelegate?.delegate;
3737
const delegatePersonalDetails = getPersonalDetailByEmail(currentVacationDelegate ?? '');
38-
const icons = useMemoizedLazyExpensifyIcons(['FallbackAvatar'] as const);
38+
const icons = useMemoizedLazyExpensifyIcons(['FallbackAvatar']);
3939

4040
const excludeLogins = useMemo(
4141
() => ({
@@ -45,7 +45,7 @@ function VacationDelegatePage() {
4545
[currentVacationDelegate],
4646
);
4747

48-
const {searchTerm, setSearchTerm, availableOptions, areOptionsInitialized, onListEndReached} = useSearchSelector({
48+
const {searchTerm, debouncedSearchTerm, setSearchTerm, availableOptions, areOptionsInitialized, onListEndReached} = useSearchSelector({
4949
selectionMode: CONST.SEARCH_SELECTOR.SELECTION_MODE_SINGLE,
5050
maxRecentReportsToShow: CONST.IOU.MAX_RECENT_REPORTS_TO_SHOW,
5151
searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_GENERAL,
@@ -60,11 +60,11 @@ function VacationDelegatePage() {
6060
return getHeaderMessage(
6161
(availableOptions.recentReports?.length || 0) + (availableOptions.personalDetails?.length || 0) !== 0,
6262
!!availableOptions.userToInvite,
63-
searchTerm.trim(),
63+
debouncedSearchTerm.trim(),
6464
countryCode,
6565
false,
6666
);
67-
}, [availableOptions.recentReports?.length, availableOptions.personalDetails?.length, availableOptions.userToInvite, searchTerm, countryCode]);
67+
}, [availableOptions.recentReports?.length, availableOptions.personalDetails?.length, availableOptions.userToInvite, debouncedSearchTerm, countryCode]);
6868

6969
const sections = useMemo(() => {
7070
const sectionsList = [];
@@ -161,8 +161,8 @@ function VacationDelegatePage() {
161161
);
162162

163163
useEffect(() => {
164-
searchInServer(searchTerm);
165-
}, [searchTerm]);
164+
searchInServer(debouncedSearchTerm);
165+
}, [debouncedSearchTerm]);
166166

167167
return (
168168
<>

src/pages/workspace/WorkspaceInvitePage.tsx

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,26 @@ function WorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) {
9595
});
9696
}, [invitedEmailsToAccountIDsDraft, personalDetails]);
9797

98-
const {searchTerm, setSearchTerm, availableOptions, selectedOptions, selectedOptionsForDisplay, toggleSelection, areOptionsInitialized, onListEndReached, searchOptions} =
99-
useSearchSelector({
100-
selectionMode: CONST.SEARCH_SELECTOR.SELECTION_MODE_MULTI,
101-
searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_MEMBER_INVITE,
102-
includeUserToInvite: true,
103-
excludeLogins: excludedUsers,
104-
includeRecentReports: false,
105-
shouldInitialize: didScreenTransitionEnd,
106-
initialSelected: initiallySelectedOptions,
107-
});
98+
const {
99+
searchTerm,
100+
debouncedSearchTerm,
101+
setSearchTerm,
102+
availableOptions,
103+
selectedOptions,
104+
selectedOptionsForDisplay,
105+
toggleSelection,
106+
areOptionsInitialized,
107+
onListEndReached,
108+
searchOptions,
109+
} = useSearchSelector({
110+
selectionMode: CONST.SEARCH_SELECTOR.SELECTION_MODE_MULTI,
111+
searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_MEMBER_INVITE,
112+
includeUserToInvite: true,
113+
excludeLogins: excludedUsers,
114+
includeRecentReports: false,
115+
shouldInitialize: didScreenTransitionEnd,
116+
initialSelected: initiallySelectedOptions,
117+
});
108118

109119
const sections: Sections[] = useMemo(() => {
110120
const sectionsArr: Sections[] = [];
@@ -180,7 +190,7 @@ function WorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) {
180190
);
181191

182192
const headerMessage = useMemo(() => {
183-
const searchValue = searchTerm.trim().toLowerCase();
193+
const searchValue = debouncedSearchTerm.trim().toLowerCase();
184194
if (!availableOptions.userToInvite && CONST.EXPENSIFY_EMAILS_OBJECT[searchValue]) {
185195
return translate('messages.errorMessageInvalidEmail');
186196
}
@@ -192,7 +202,7 @@ function WorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) {
192202
}
193203
return getHeaderMessage(searchOptions.personalDetails.length + selectedOptions.length !== 0, !!searchOptions.userToInvite, searchValue, countryCode, false);
194204
}, [
195-
searchTerm,
205+
debouncedSearchTerm,
196206
availableOptions.userToInvite,
197207
excludedUsers,
198208
countryCode,
@@ -219,8 +229,8 @@ function WorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) {
219229
);
220230

221231
useEffect(() => {
222-
searchInServer(searchTerm);
223-
}, [searchTerm]);
232+
searchInServer(debouncedSearchTerm);
233+
}, [debouncedSearchTerm]);
224234

225235
return (
226236
<AccessOrNotFoundWrapper

src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function AssigneeStep({route}: AssigneeStepProps) {
4141
const {translate, formatPhoneNumber, localeCompare} = useLocalize();
4242
const styles = useThemeStyles();
4343
const {isOffline} = useNetwork();
44-
const icons = useMemoizedLazyExpensifyIcons(['FallbackAvatar'] as const);
44+
const icons = useMemoizedLazyExpensifyIcons(['FallbackAvatar']);
4545
const policy = usePolicy(policyID);
4646
const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD, {canBeMissing: true});
4747
const [countryCode = CONST.DEFAULT_COUNTRY_CODE] = useOnyx(ONYXKEYS.COUNTRY_CODE, {canBeMissing: false});
@@ -222,16 +222,16 @@ function AssigneeStep({route}: AssigneeStepProps) {
222222
]);
223223

224224
useEffect(() => {
225-
searchInServer(searchTerm);
226-
}, [searchTerm]);
225+
searchInServer(debouncedSearchTerm);
226+
}, [debouncedSearchTerm]);
227227

228228
const headerMessage = useMemo(() => {
229-
const searchValue = searchTerm.trim().toLowerCase();
229+
const searchValue = debouncedSearchTerm.trim().toLowerCase();
230230
if (!availableOptions.userToInvite && CONST.EXPENSIFY_EMAILS_OBJECT[searchValue]) {
231231
return translate('messages.errorMessageInvalidEmail');
232232
}
233233
return getHeaderMessage(assignees.length > 0, !!availableOptions.userToInvite, searchValue, countryCode, false);
234-
}, [searchTerm, availableOptions.userToInvite, assignees?.length, countryCode, translate]);
234+
}, [debouncedSearchTerm, availableOptions.userToInvite, assignees?.length, countryCode, translate]);
235235

236236
const textInputOptions = useMemo(
237237
() => ({

src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React, {useEffect, useMemo, useState} from 'react';
22
import type {OnyxEntry} from 'react-native-onyx';
3-
import * as Expensicons from '@components/Icon/Expensicons';
43
import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
54
import SelectionList from '@components/SelectionList';
65
import UserListItem from '@components/SelectionList/ListItem/UserListItem';
76
import type {ListItem} from '@components/SelectionList/types';
87
import Text from '@components/Text';
98
import useCurrencyForExpensifyCard from '@hooks/useCurrencyForExpensifyCard';
9+
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
1010
import useLocalize from '@hooks/useLocalize';
1111
import useNetwork from '@hooks/useNetwork';
1212
import useOnyx from '@hooks/useOnyx';
@@ -44,6 +44,7 @@ type AssigneeStepProps = {
4444
function AssigneeStep({policy, stepNames, startStepIndex, route}: AssigneeStepProps) {
4545
const {translate, formatPhoneNumber, localeCompare} = useLocalize();
4646
const styles = useThemeStyles();
47+
const icons = useMemoizedLazyExpensifyIcons(['FallbackAvatar']);
4748
const {isOffline} = useNetwork();
4849
const policyID = route.params.policyID;
4950
const [issueNewCard] = useOnyx(`${ONYXKEYS.COLLECTION.ISSUE_NEW_EXPENSIFY_CARD}${policyID}`, {canBeMissing: true});
@@ -136,7 +137,7 @@ function AssigneeStep({policy, stepNames, startStepIndex, route}: AssigneeStepPr
136137
isSelected: issueNewCard?.data?.assigneeEmail === email,
137138
icons: [
138139
{
139-
source: personalDetail?.avatar ?? Expensicons.FallbackAvatar,
140+
source: personalDetail?.avatar ?? icons.FallbackAvatar,
140141
name: formatPhoneNumber(email),
141142
type: CONST.ICON_TYPE_AVATAR,
142143
id: personalDetail?.accountID,
@@ -148,7 +149,7 @@ function AssigneeStep({policy, stepNames, startStepIndex, route}: AssigneeStepPr
148149
membersList = sortAlphabetically(membersList, 'text', localeCompare);
149150

150151
return membersList;
151-
}, [policy?.employeeList, localeCompare, isOffline, issueNewCard?.data?.assigneeEmail, formatPhoneNumber]);
152+
}, [policy?.employeeList, localeCompare, isOffline, issueNewCard?.data?.assigneeEmail, formatPhoneNumber, icons.FallbackAvatar]);
152153

153154
const assignees = useMemo(() => {
154155
if (!debouncedSearchTerm) {
@@ -187,16 +188,16 @@ function AssigneeStep({policy, stepNames, startStepIndex, route}: AssigneeStepPr
187188
]);
188189

189190
useEffect(() => {
190-
searchInServer(searchTerm);
191-
}, [searchTerm]);
191+
searchInServer(debouncedSearchTerm);
192+
}, [debouncedSearchTerm]);
192193

193194
const headerMessage = useMemo(() => {
194-
const searchValue = searchTerm.trim().toLowerCase();
195+
const searchValue = debouncedSearchTerm.trim().toLowerCase();
195196
if (!availableOptions.userToInvite && CONST.EXPENSIFY_EMAILS_OBJECT[searchValue]) {
196197
return translate('messages.errorMessageInvalidEmail');
197198
}
198199
return getHeaderMessage(assignees.length > 0, !!availableOptions.userToInvite, searchValue, countryCode, false);
199-
}, [searchTerm, availableOptions.userToInvite, assignees.length, countryCode, translate]);
200+
}, [debouncedSearchTerm, availableOptions.userToInvite, assignees.length, countryCode, translate]);
200201

201202
const textInputOptions = useMemo(
202203
() => ({

0 commit comments

Comments
 (0)