diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js index ba86339f7270..00e00e3b4a17 100644 --- a/src/libs/OptionsListUtils.js +++ b/src/libs/OptionsListUtils.js @@ -1585,6 +1585,64 @@ function shouldOptionShowTooltip(option) { return (!option.isChatRoom || option.isThread) && !option.isArchivedRoom; } +/** + * Handles the logic for displaying selected participants from the search term + * @param {String} searchTerm + * @param {Array} selectedOptions + * @param {Array} filteredRecentReports + * @param {Array} filteredPersonalDetails + * @param {Object} personalDetails + * @param {Boolean} shouldGetOptionDetails + * @param {Number} indexOffset + * @returns {Object} + */ +function formatSectionsFromSearchTerm(searchTerm, selectedOptions, filteredRecentReports, filteredPersonalDetails, personalDetails = {}, shouldGetOptionDetails = false, indexOffset) { + // We show the selected participants at the top of the list when there is no search term + // However, if there is a search term we remove the selected participants from the top of the list unless they are part of the search results + // This clears up space on mobile views, where if you create a group with 4+ people you can't see the selected participants and the search results at the same time + if (searchTerm === '') { + return { + section: { + title: undefined, + data: shouldGetOptionDetails + ? _.map(selectedOptions, (participant) => { + const isPolicyExpenseChat = lodashGet(participant, 'isPolicyExpenseChat', false); + return isPolicyExpenseChat ? getPolicyExpenseReportOption(participant) : getParticipantsOption(participant, personalDetails); + }) + : selectedOptions, + shouldShow: !_.isEmpty(selectedOptions), + indexOffset, + }, + newIndexOffset: indexOffset + selectedOptions.length, + }; + } + + // If you select a new user you don't have a contact for, they won't get returned as part of a recent report or personal details + // This will add them to the list of options, deduping them if they already exist in the other lists + const selectedParticipantsWithoutDetails = _.filter(selectedOptions, (participant) => { + const accountID = lodashGet(participant, 'accountID', null); + const isPartOfSearchTerm = participant.searchText.toLowerCase().includes(searchTerm.trim().toLowerCase()); + const isReportInRecentReports = _.some(filteredRecentReports, (report) => report.accountID === accountID); + const isReportInPersonalDetails = _.some(filteredPersonalDetails, (personalDetail) => personalDetail.accountID === accountID); + return isPartOfSearchTerm && !isReportInRecentReports && !isReportInPersonalDetails; + }); + + return { + section: { + title: undefined, + data: shouldGetOptionDetails + ? _.map(selectedParticipantsWithoutDetails, (participant) => { + const isPolicyExpenseChat = lodashGet(participant, 'isPolicyExpenseChat', false); + return isPolicyExpenseChat ? getPolicyExpenseReportOption(participant) : getParticipantsOption(participant, personalDetails); + }) + : selectedParticipantsWithoutDetails, + shouldShow: !_.isEmpty(selectedParticipantsWithoutDetails), + indexOffset, + }, + newIndexOffset: indexOffset + selectedParticipantsWithoutDetails.length, + }; +} + export { addSMSDomainIfPhoneNumber, getAvatarsForAccountIDs, @@ -1610,4 +1668,5 @@ export { hasEnabledOptions, getCategoryOptionTree, formatMemberForList, + formatSectionsFromSearchTerm, }; diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index a9401bce684e..9ee5f838aafd 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -71,16 +71,9 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i const sectionsList = []; let indexOffset = 0; - // Only show the selected participants if the search is empty - if (searchTerm === '') { - sectionsList.push({ - title: undefined, - data: selectedOptions, - shouldShow: !_.isEmpty(selectedOptions), - indexOffset, - }); - indexOffset += selectedOptions.length; - } + const formatResults = OptionsListUtils.formatSectionsFromSearchTerm(searchTerm, selectedOptions, filteredRecentReports, filteredPersonalDetails, {}, false, indexOffset); + sectionsList.push(formatResults.section); + indexOffset = formatResults.newIndexOffset; if (maxParticipantsReached) { return sectionsList; diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index 1263dd5db2b9..9f1e5a416995 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -104,19 +104,17 @@ function MoneyRequestParticipantsSelector({ const newSections = []; let indexOffset = 0; - // Only show the selected participants if the search is empty - if (searchTerm === '') { - newSections.push({ - title: undefined, - data: _.map(participants, (participant) => { - const isPolicyExpenseChat = lodashGet(participant, 'isPolicyExpenseChat', false); - return isPolicyExpenseChat ? OptionsListUtils.getPolicyExpenseReportOption(participant) : OptionsListUtils.getParticipantsOption(participant, personalDetails); - }), - shouldShow: true, - indexOffset, - }); - indexOffset += participants.length; - } + const formatResults = OptionsListUtils.formatSectionsFromSearchTerm( + searchTerm, + participants, + newChatOptions.recentReports, + newChatOptions.personalDetails, + personalDetails, + true, + indexOffset, + ); + newSections.push(formatResults.section); + indexOffset = formatResults.newIndexOffset; if (maxParticipantsReached) { return newSections;