11import reportsSelector from '@selectors/Attributes' ;
2- import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
2+ import React , { useEffect , useState } from 'react' ;
33import { usePersonalDetails } from '@components/OnyxListItemProvider' ;
44import { useOptionsList } from '@components/OptionListContextProvider' ;
5- // eslint-disable-next-line no-restricted-imports
6- import SelectionList from '@components/SelectionListWithSections' ;
7- import InviteMemberListItem from '@components/SelectionListWithSections/InviteMemberListItem' ;
5+ import InviteMemberListItem from '@components/SelectionList/ListItem/InviteMemberListItem' ;
6+ import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections' ;
87import useArchivedReportsIdSet from '@hooks/useArchivedReportsIdSet' ;
98import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails' ;
109import useDebouncedState from '@hooks/useDebouncedState' ;
@@ -13,7 +12,8 @@ import useOnyx from '@hooks/useOnyx';
1312import useScreenWrapperTransitionStatus from '@hooks/useScreenWrapperTransitionStatus' ;
1413import { canUseTouchScreen } from '@libs/DeviceCapabilities' ;
1514import { createOptionFromReport , filterAndOrderOptions , formatSectionsFromSearchTerm , getAlternateText , getSearchOptions } from '@libs/OptionsListUtils' ;
16- import type { Option , Section } from '@libs/OptionsListUtils' ;
15+ import type { Option } from '@libs/OptionsListUtils' ;
16+ import type { OptionWithKey , SelectionListSections } from '@libs/OptionsListUtils/types' ;
1717import type { OptionData } from '@libs/ReportUtils' ;
1818import Navigation from '@navigation/Navigation' ;
1919import { searchInServer } from '@userActions/Report' ;
@@ -59,53 +59,44 @@ function SearchFiltersChatsSelector({initialReportIDs, onFiltersUpdate, isScreen
5959 const [ reportAttributesDerived ] = useOnyx ( ONYXKEYS . DERIVED . REPORT_ATTRIBUTES , { canBeMissing : true , selector : reportsSelector } ) ;
6060 const [ selectedReportIDs , setSelectedReportIDs ] = useState < string [ ] > ( initialReportIDs ) ;
6161 const [ searchTerm , debouncedSearchTerm , setSearchTerm ] = useDebouncedState ( '' ) ;
62- const cleanSearchTerm = useMemo ( ( ) => searchTerm . trim ( ) . toLowerCase ( ) , [ searchTerm ] ) ;
62+ const cleanSearchTerm = searchTerm . trim ( ) . toLowerCase ( ) ;
6363 const [ draftComments ] = useOnyx ( ONYXKEYS . COLLECTION . REPORT_DRAFT_COMMENT , { canBeMissing : true } ) ;
6464 const archivedReportsIdSet = useArchivedReportsIdSet ( ) ;
6565 const [ nvpDismissedProductTraining ] = useOnyx ( ONYXKEYS . NVP_DISMISSED_PRODUCT_TRAINING , { canBeMissing : true } ) ;
6666
67- const selectedOptions = useMemo < OptionData [ ] > ( ( ) => {
68- return selectedReportIDs . map ( ( id ) => {
69- const report = getSelectedOptionData (
70- createOptionFromReport ( { ...reports ?. [ `${ ONYXKEYS . COLLECTION . REPORT } ${ id } ` ] , reportID : id } , personalDetails , currentUserAccountID , reportAttributesDerived ) ,
71- ) ;
72- const isReportArchived = archivedReportsIdSet . has ( `${ ONYXKEYS . COLLECTION . REPORT_NAME_VALUE_PAIRS } ${ report . reportID } ` ) ;
73- const alternateText = getAlternateText ( report , { } , isReportArchived , currentUserAccountID , { } ) ;
74- return { ...report , alternateText} ;
75- } ) ;
76- } , [ archivedReportsIdSet , personalDetails , reportAttributesDerived , reports , selectedReportIDs , currentUserAccountID ] ) ;
77-
78- const defaultOptions = useMemo ( ( ) => {
79- if ( ! areOptionsInitialized || ! isScreenTransitionEnd ) {
80- return defaultListOptions ;
81- }
82- return getSearchOptions ( {
83- options,
84- draftComments,
85- nvpDismissedProductTraining,
86- betas : undefined ,
87- isUsedInChatFinder : false ,
88- countryCode,
89- loginList,
90- currentUserAccountID,
91- currentUserEmail,
92- personalDetails,
93- } ) ;
94- } , [ areOptionsInitialized , isScreenTransitionEnd , options , draftComments , nvpDismissedProductTraining , countryCode , loginList , currentUserAccountID , currentUserEmail , personalDetails ] ) ;
67+ const selectedOptions : OptionData [ ] = selectedReportIDs . map ( ( id ) => {
68+ const report = getSelectedOptionData (
69+ createOptionFromReport ( { ...reports ?. [ `${ ONYXKEYS . COLLECTION . REPORT } ${ id } ` ] , reportID : id } , personalDetails , currentUserAccountID , reportAttributesDerived ) ,
70+ ) ;
71+ const isReportArchived = archivedReportsIdSet . has ( `${ ONYXKEYS . COLLECTION . REPORT_NAME_VALUE_PAIRS } ${ report . reportID } ` ) ;
72+ const alternateText = getAlternateText ( report , { } , isReportArchived , currentUserAccountID , { } ) ;
73+ return { ...report , alternateText} ;
74+ } ) ;
9575
96- const chatOptions = useMemo ( ( ) => {
97- return filterAndOrderOptions ( defaultOptions , cleanSearchTerm , countryCode , loginList , currentUserEmail , currentUserAccountID , personalDetails , {
98- selectedOptions,
99- excludeLogins : CONST . EXPENSIFY_EMAILS_OBJECT ,
100- } ) ;
101- } , [ defaultOptions , cleanSearchTerm , countryCode , loginList , selectedOptions , currentUserAccountID , currentUserEmail , personalDetails ] ) ;
76+ const defaultOptions =
77+ ! areOptionsInitialized || ! isScreenTransitionEnd
78+ ? defaultListOptions
79+ : getSearchOptions ( {
80+ options,
81+ draftComments,
82+ nvpDismissedProductTraining,
83+ betas : undefined ,
84+ isUsedInChatFinder : false ,
85+ countryCode,
86+ loginList,
87+ currentUserAccountID,
88+ currentUserEmail,
89+ personalDetails,
90+ } ) ;
91+
92+ const chatOptions = filterAndOrderOptions ( defaultOptions , cleanSearchTerm , countryCode , loginList , currentUserEmail , currentUserAccountID , personalDetails , {
93+ selectedOptions,
94+ excludeLogins : CONST . EXPENSIFY_EMAILS_OBJECT ,
95+ } ) ;
10296
103- const { sections, headerMessage} = useMemo ( ( ) => {
104- const newSections : Section [ ] = [ ] ;
105- if ( ! areOptionsInitialized ) {
106- return { sections : [ ] , headerMessage : undefined } ;
107- }
97+ const sections : SelectionListSections = [ ] ;
10898
99+ if ( areOptionsInitialized ) {
109100 const formattedResults = formatSectionsFromSearchTerm (
110101 cleanSearchTerm ,
111102 selectedOptions ,
@@ -118,102 +109,80 @@ function SearchFiltersChatsSelector({initialReportIDs, onFiltersUpdate, isScreen
118109 reportAttributesDerived ,
119110 ) ;
120111
121- newSections . push ( formattedResults . section ) ;
112+ sections . push ( formattedResults . section ) ;
122113
123114 const visibleReportsWhenSearchTermNonEmpty = chatOptions . recentReports . map ( ( report ) => ( selectedReportIDs . includes ( report . reportID ) ? getSelectedOptionData ( report ) : report ) ) ;
124115 const visibleReportsWhenSearchTermEmpty = chatOptions . recentReports . filter ( ( report ) => ! selectedReportIDs . includes ( report . reportID ) ) ;
125116 const reportsFiltered = cleanSearchTerm === '' ? visibleReportsWhenSearchTermEmpty : visibleReportsWhenSearchTermNonEmpty ;
126117
127- newSections . push ( {
118+ sections . push ( {
128119 title : undefined ,
129120 data : reportsFiltered ,
130- shouldShow : chatOptions . recentReports . length > 0 ,
121+ sectionIndex : 1 ,
131122 } ) ;
132-
133- const areResultsFound = didScreenTransitionEnd && formattedResults . section . data . length === 0 && reportsFiltered . length === 0 ;
134- const message = areResultsFound ? translate ( 'common.noResultsFound' ) : undefined ;
135-
136- return {
137- sections : newSections ,
138- headerMessage : message ,
139- } ;
140- } , [
141- areOptionsInitialized ,
142- chatOptions . personalDetails ,
143- chatOptions . recentReports ,
144- cleanSearchTerm ,
145- didScreenTransitionEnd ,
146- personalDetails ,
147- reportAttributesDerived ,
148- selectedOptions ,
149- selectedReportIDs ,
150- translate ,
151- currentUserAccountID ,
152- ] ) ;
123+ }
124+ const noResultsFound = didScreenTransitionEnd && sections . at ( 0 ) ?. data . length === 0 && sections . at ( 1 ) ?. data . length === 0 ;
125+ const headerMessage = noResultsFound ? translate ( 'common.noResultsFound' ) : undefined ;
153126
154127 useEffect ( ( ) => {
155128 searchInServer ( debouncedSearchTerm . trim ( ) ) ;
156129 } , [ debouncedSearchTerm ] ) ;
157130
158- const handleParticipantSelection = useCallback (
159- ( selectedOption : Option ) => {
160- const optionReportID = selectedOption . reportID ;
161- if ( ! optionReportID ) {
162- return ;
163- }
164- const foundOptionIndex = selectedReportIDs . findIndex ( ( reportID : string ) => {
165- return reportID && reportID !== '' && selectedOption . reportID === reportID ;
166- } ) ;
167-
168- if ( foundOptionIndex < 0 ) {
169- setSelectedReportIDs ( [ ...selectedReportIDs , optionReportID ] ) ;
170- } else {
171- const newSelectedReports = [ ...selectedReportIDs . slice ( 0 , foundOptionIndex ) , ...selectedReportIDs . slice ( foundOptionIndex + 1 ) ] ;
172- setSelectedReportIDs ( newSelectedReports ) ;
173- }
174- } ,
175- [ selectedReportIDs ] ,
176- ) ;
131+ const handleParticipantSelection = ( selectedOption : OptionWithKey ) => {
132+ const optionReportID = selectedOption . reportID ;
133+ if ( ! optionReportID ) {
134+ return ;
135+ }
136+ const foundOptionIndex = selectedReportIDs . findIndex ( ( reportID : string ) => {
137+ return reportID && reportID !== '' && selectedOption . reportID === reportID ;
138+ } ) ;
177139
178- const applyChanges = useCallback ( ( ) => {
140+ if ( foundOptionIndex < 0 ) {
141+ setSelectedReportIDs ( [ ...selectedReportIDs , optionReportID ] ) ;
142+ } else {
143+ const newSelectedReports = [ ...selectedReportIDs . slice ( 0 , foundOptionIndex ) , ...selectedReportIDs . slice ( foundOptionIndex + 1 ) ] ;
144+ setSelectedReportIDs ( newSelectedReports ) ;
145+ }
146+ } ;
147+
148+ const applyChanges = ( ) => {
179149 onFiltersUpdate ( selectedReportIDs ) ;
180150 Navigation . goBack ( ROUTES . SEARCH_ADVANCED_FILTERS . getRoute ( ) ) ;
181- } , [ onFiltersUpdate , selectedReportIDs ] ) ;
151+ } ;
182152
183- const resetChanges = useCallback ( ( ) => {
153+ const resetChanges = ( ) => {
184154 setSelectedReportIDs ( [ ] ) ;
185- } , [ ] ) ;
186-
187- const footerContent = useMemo (
188- ( ) => (
189- < SearchFilterPageFooterButtons
190- applyChanges = { applyChanges }
191- resetChanges = { resetChanges }
192- />
193- ) ,
194- [ resetChanges , applyChanges ] ,
155+ } ;
156+
157+ const footerContent = (
158+ < SearchFilterPageFooterButtons
159+ applyChanges = { applyChanges }
160+ resetChanges = { resetChanges }
161+ />
195162 ) ;
196163
197164 const isLoadingNewOptions = ! ! isSearchingForReports ;
198165 const showLoadingPlaceholder = ! didScreenTransitionEnd || ! areOptionsInitialized || ! initialReportIDs || ! personalDetails ;
199166
167+ const textInputOptions = {
168+ value : searchTerm ,
169+ label : translate ( 'selectionList.nameEmailOrPhoneNumber' ) ,
170+ onChangeText : setSearchTerm ,
171+ headerMessage,
172+ } ;
173+
200174 return (
201- < SelectionList
202- canSelectMultiple
175+ < SelectionListWithSections
203176 sections = { sections }
177+ onSelectRow = { handleParticipantSelection }
204178 ListItem = { InviteMemberListItem }
205- textInputLabel = { translate ( 'selectionList.nameEmailOrPhoneNumber' ) }
206- headerMessage = { headerMessage }
207- textInputValue = { searchTerm }
208179 footerContent = { footerContent }
209- showScrollIndicator
180+ canSelectMultiple
210181 shouldPreventDefaultFocusOnSelectRow = { ! canUseTouchScreen ( ) }
211- onChangeText = { ( value ) => {
212- setSearchTerm ( value ) ;
213- } }
214- onSelectRow = { handleParticipantSelection }
182+ textInputOptions = { textInputOptions }
215183 isLoadingNewOptions = { isLoadingNewOptions }
216184 showLoadingPlaceholder = { showLoadingPlaceholder }
185+ shouldShowTextInput
217186 />
218187 ) ;
219188}
0 commit comments