diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index a4ca631632d9..9b74b1f6ef70 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -329,16 +329,18 @@ function MoneyRequestConfirmationList({ const hasRoute = hasRouteUtil(transaction, isDistanceRequest); const isDistanceRequestWithPendingRoute = isDistanceRequest && (!hasRoute || !rate) && !isMovingTransactionFromTrackExpense; + const distanceRequestAmount = DistanceRequestUtils.getDistanceRequestAmount(distance, unit ?? CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES, rate ?? 0); const formattedAmount = isDistanceRequestWithPendingRoute ? '' : convertToDisplayString(shouldCalculateDistanceAmount ? distanceRequestAmount : iouAmount, isDistanceRequest ? currency : iouCurrencyCode); - const formattedAmountPerAttendee = isDistanceRequestWithPendingRoute - ? '' - : convertToDisplayString( - (shouldCalculateDistanceAmount ? distanceRequestAmount : iouAmount) / (iouAttendees?.length && iouAttendees.length > 0 ? iouAttendees.length : 1), - isDistanceRequest ? currency : iouCurrencyCode, - ); + const formattedAmountPerAttendee = + isDistanceRequestWithPendingRoute || isScanRequest + ? '' + : convertToDisplayString( + (shouldCalculateDistanceAmount ? distanceRequestAmount : iouAmount) / (iouAttendees?.length && iouAttendees.length > 0 ? iouAttendees.length : 1), + isDistanceRequest ? currency : iouCurrencyCode, + ); const isFocused = useIsFocused(); const [formError, debouncedFormError, setFormError] = useDebouncedState(''); diff --git a/src/components/MoneyRequestConfirmationListFooter.tsx b/src/components/MoneyRequestConfirmationListFooter.tsx index 1898ba99c3bd..15b5cf32d0bd 100644 --- a/src/components/MoneyRequestConfirmationListFooter.tsx +++ b/src/components/MoneyRequestConfirmationListFooter.tsx @@ -618,7 +618,7 @@ function MoneyRequestConfirmationListFooter({ shouldShowRightIcon title={iouAttendees?.map((item) => item?.displayName ?? item?.login).join(', ')} description={`${translate('iou.attendees')} ${ - iouAttendees?.length && iouAttendees.length > 1 ? `\u00B7 ${formattedAmountPerAttendee} ${translate('common.perPerson')}` : '' + iouAttendees?.length && iouAttendees.length > 1 && formattedAmountPerAttendee ? `\u00B7 ${formattedAmountPerAttendee} ${translate('common.perPerson')}` : '' }`} style={[styles.moneyRequestMenuItem]} titleStyle={styles.flex1} diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 52b60b4ee471..871aaf384e27 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -162,10 +162,16 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals const isEmptyMerchant = transactionMerchant === '' || transactionMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT; const isDistanceRequest = isDistanceRequestTransactionUtils(transaction); const isPerDiemRequest = isPerDiemRequestTransactionUtils(transaction); + const hasReceipt = hasReceiptTransactionUtils(updatedTransaction ?? transaction); + const isReceiptBeingScanned = hasReceipt && isReceiptBeingScannedTransactionUtils(updatedTransaction ?? transaction); + const didReceiptScanSucceed = hasReceipt && didReceiptScanSucceedTransactionUtils(transaction); const hasRoute = hasRouteTransactionUtils(transactionBackup ?? transaction, isDistanceRequest); const shouldDisplayTransactionAmount = ((isDistanceRequest && hasRoute) || !!transactionAmount) && transactionAmount !== undefined; const formattedTransactionAmount = shouldDisplayTransactionAmount ? convertToDisplayString(transactionAmount, transactionCurrency) : ''; - const formattedPerAttendeeAmount = shouldDisplayTransactionAmount ? convertToDisplayString(transactionAmount / (transactionAttendees?.length ?? 1), transactionCurrency) : ''; + const formattedPerAttendeeAmount = + shouldDisplayTransactionAmount && !isReceiptBeingScanned && didReceiptScanSucceed + ? convertToDisplayString(transactionAmount / (transactionAttendees?.length ?? 1), transactionCurrency) + : ''; const formattedOriginalAmount = transactionOriginalAmount && transactionOriginalCurrency && convertToDisplayString(transactionOriginalAmount, transactionOriginalCurrency); const isCardTransaction = isCardTransactionTransactionUtils(transaction); const cardProgramName = getCardName(transaction); @@ -194,9 +200,6 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals const canEditMerchant = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.MERCHANT); const canEditDate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DATE); const canEditReceipt = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT); - const hasReceipt = hasReceiptTransactionUtils(updatedTransaction ?? transaction); - const isReceiptBeingScanned = hasReceipt && isReceiptBeingScannedTransactionUtils(updatedTransaction ?? transaction); - const didReceiptScanSucceed = hasReceipt && didReceiptScanSucceedTransactionUtils(transaction); const canEditDistance = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE); const canEditDistanceRate = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE_RATE); const canEditReport = canUserPerformWriteAction && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.REPORT); @@ -207,7 +210,16 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals const policyTagLists = useMemo(() => getTagLists(policyTagList), [policyTagList]); - const iouType = isTrackExpense ? CONST.IOU.TYPE.TRACK : CONST.IOU.TYPE.SUBMIT; + const iouType = useMemo(() => { + if (isTrackExpense) { + return CONST.IOU.TYPE.TRACK; + } + if (isInvoice) { + return CONST.IOU.TYPE.INVOICE; + } + + return CONST.IOU.TYPE.SUBMIT; + }, [isTrackExpense, isInvoice]); // Flags for showing categories and tags // transactionCategory can be an empty string @@ -749,7 +761,9 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals shouldShowRightIcon title={Array.isArray(transactionAttendees) ? transactionAttendees.map((item) => item?.displayName ?? item?.login).join(', ') : ''} description={`${translate('iou.attendees')} ${ - Array.isArray(transactionAttendees) && transactionAttendees.length > 1 ? `${formattedPerAttendeeAmount} ${translate('common.perPerson')}` : '' + Array.isArray(transactionAttendees) && transactionAttendees.length > 1 && formattedPerAttendeeAmount + ? `${formattedPerAttendeeAmount} ${translate('common.perPerson')}` + : '' }`} style={[styles.moneyRequestMenuItem]} titleStyle={styles.flex1} diff --git a/src/components/SelectionList/InviteMemberListItem.tsx b/src/components/SelectionList/InviteMemberListItem.tsx index 31bdeff63475..3e00f5996e6c 100644 --- a/src/components/SelectionList/InviteMemberListItem.tsx +++ b/src/components/SelectionList/InviteMemberListItem.tsx @@ -48,10 +48,10 @@ function InviteMemberListItem({ const theme = useTheme(); const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); - const [betas] = useOnyx(ONYXKEYS.BETAS); + const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); const {renderProductTrainingTooltip, shouldShowProductTrainingTooltip} = useProductTrainingContext( CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SCAN_TEST_TOOLTIP_MANAGER, - !getIsUserSubmittedExpenseOrScannedReceipt() && Permissions.canUseManagerMcTest(betas) && isSelectedManagerMcTest(item.login), + !getIsUserSubmittedExpenseOrScannedReceipt() && Permissions.canUseManagerMcTest(betas) && isSelectedManagerMcTest(item.login) && !item.isSelected, ); const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor; diff --git a/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts b/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts index 96eb81324b81..0f05a460332b 100644 --- a/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts +++ b/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts @@ -29,6 +29,7 @@ type CategorizeTrackedExpenseParams = { guidedSetupData?: string; engagementChoice?: string; description?: string; + attendees?: string; }; export default CategorizeTrackedExpenseParams; diff --git a/src/libs/API/parameters/CreateDistanceRequestParams.ts b/src/libs/API/parameters/CreateDistanceRequestParams.ts index 915a3e4cc133..73f08deb6c4f 100644 --- a/src/libs/API/parameters/CreateDistanceRequestParams.ts +++ b/src/libs/API/parameters/CreateDistanceRequestParams.ts @@ -21,6 +21,7 @@ type CreateDistanceRequestParams = { splits?: string; chatType?: string; description?: string; + attendees?: string; }; export default CreateDistanceRequestParams; diff --git a/src/libs/API/parameters/CreatePerDiemRequestParams.ts b/src/libs/API/parameters/CreatePerDiemRequestParams.ts index b2fe0b541cc5..480acd9ca23d 100644 --- a/src/libs/API/parameters/CreatePerDiemRequestParams.ts +++ b/src/libs/API/parameters/CreatePerDiemRequestParams.ts @@ -20,6 +20,7 @@ type CreatePerDiemRequestParams = { transactionThreadReportID: string; createdReportActionIDForThread: string | undefined; billable?: boolean; + attendees?: string; }; export default CreatePerDiemRequestParams; diff --git a/src/libs/API/parameters/ShareTrackedExpenseParams.ts b/src/libs/API/parameters/ShareTrackedExpenseParams.ts index dcdf87cf74cf..ff991f10677d 100644 --- a/src/libs/API/parameters/ShareTrackedExpenseParams.ts +++ b/src/libs/API/parameters/ShareTrackedExpenseParams.ts @@ -31,6 +31,7 @@ type ShareTrackedExpenseParams = { description?: string; accountantEmail: string; policyName?: string; + attendees?: string; }; export default ShareTrackedExpenseParams; diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 9f62e34b182f..afa9750cc1e3 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -2,6 +2,7 @@ /* eslint-disable no-continue */ import {Str} from 'expensify-common'; +import keyBy from 'lodash/keyBy'; import lodashOrderBy from 'lodash/orderBy'; import Onyx from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; @@ -42,7 +43,7 @@ import Navigation from './Navigation/Navigation'; import Parser from './Parser'; import Performance from './Performance'; import Permissions from './Permissions'; -import {getDisplayNameOrDefault, getPersonalDetailsByIDs} from './PersonalDetailsUtils'; +import {getDisplayNameOrDefault, getPersonalDetailByEmail, getPersonalDetailsByIDs} from './PersonalDetailsUtils'; import {addSMSDomainIfPhoneNumber, parsePhoneNumber} from './PhoneNumber'; import {canSendInvoiceFromWorkspace, getSubmitToAccountID, isUserInvitedToWorkspace} from './PolicyUtils'; import { @@ -222,7 +223,7 @@ type GetOptionsConfig = { excludeLogins?: Record; includeRecentReports?: boolean; includeSelectedOptions?: boolean; - recentAttendees?: Attendee[]; + recentAttendees?: Option[]; excludeHiddenThreads?: boolean; excludeHiddenChatRoom?: boolean; canShowManagerMcTest?: boolean; @@ -1876,11 +1877,24 @@ function getAttendeeOptions( includeInvoiceRooms = false, action: IOUAction | undefined = undefined, ) { + const personalDetailList = keyBy( + personalDetails.map(({item}) => item), + 'accountID', + ); + const filteredRecentAttendees = recentAttendees + .filter((attendee) => !attendees.find(({email, displayName}) => (attendee.email ? email === attendee.email : displayName === attendee.displayName))) + .map((attendee) => ({ + ...attendee, + login: attendee.email ?? attendee.displayName, + ...getPersonalDetailByEmail(attendee.email), + })) + .map((attendee) => getParticipantsOption(attendee, personalDetailList as never)); + return getValidOptions( {reports, personalDetails}, { betas, - selectedOptions: attendees, + selectedOptions: attendees.map((attendee) => ({...attendee, login: attendee.email})), excludeLogins: CONST.EXPENSIFY_EMAILS_OBJECT, includeOwnedWorkspaceChats, includeRecentReports: false, @@ -1889,7 +1903,7 @@ function getAttendeeOptions( includeSelfDM: false, includeInvoiceRooms, action, - recentAttendees, + recentAttendees: filteredRecentAttendees, }, ); } diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index e43306352be4..e918182da96b 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -325,7 +325,6 @@ function isMerchantMissing(transaction: OnyxEntry) { // eslint-disable-next-line @typescript-eslint/no-unused-vars function shouldShowAttendees(iouType: IOUType, policy: OnyxEntry): boolean { - return false; // To be renabled once feature is complete: https://github.com/Expensify/App/issues/44725 // Keep this disabled for per diem expense return iouType === CONST.IOU.TYPE.SUBMIT && !!policy?.id && (policy?.type === CONST.POLICY.TYPE.CORPORATE || policy?.type === CONST.POLICY.TYPE.TEAM); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 05c138aff3db..9c420e3ea97d 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -272,6 +272,7 @@ type TrackedExpenseTransactionParams = Omit & { }; type PerDiemExpenseTransactionParams = Omit & { + attendees?: Attendee[]; customUnit: TransactionCustomUnit; comment?: string; }; @@ -454,6 +456,7 @@ type BuildOnyxDataForMoneyRequestParams = { }; type DistanceRequestTransactionParams = BaseTransactionParams & { + attendees?: Attendee[]; validWaypoints: WaypointCollection; splitShares?: SplitShares; }; @@ -472,6 +475,7 @@ type CreateDistanceRequestInformation = { type CreateSplitsTransactionParams = Omit & { splitShares: SplitShares; iouRequestType?: IOURequestType; + attendees?: Attendee[]; }; type CreateSplitsAndOnyxDataParams = { @@ -500,6 +504,7 @@ type TrackExpenseTransactionParams = { linkedTrackedExpenseReportAction?: OnyxTypes.ReportAction; linkedTrackedExpenseReportID?: string; customUnitRateID?: string; + attendees?: Attendee[]; }; type TrackExpenseAccountantParams = { @@ -559,6 +564,7 @@ type GetTrackExpenseInformationTransactionParams = { taxAmount?: number; billable?: boolean; linkedTrackedExpenseReportAction?: OnyxTypes.ReportAction; + attendees?: Attendee[]; }; type GetTrackExpenseInformationParticipantParams = { @@ -3317,7 +3323,7 @@ function getPerDiemExpenseInformation(perDiemExpenseInformation: PerDiemExpenseI const {parentChatReport, transactionParams, participantParams, policyParams = {}, moneyRequestReportID = ''} = perDiemExpenseInformation; const {payeeAccountID = userAccountID, payeeEmail = currentUserEmail, participant} = participantParams; const {policy, policyCategories, policyTagList} = policyParams; - const {comment = '', currency, created, category, tag, customUnit, billable} = transactionParams; + const {comment = '', currency, created, category, tag, customUnit, billable, attendees} = transactionParams; const amount = computePerDiemExpenseAmount(customUnit); const merchant = computePerDiemExpenseMerchant(customUnit, policy); @@ -3396,6 +3402,7 @@ function getPerDiemExpenseInformation(perDiemExpenseInformation: PerDiemExpenseI customUnit, billable, pendingFields: {subRates: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, + attendees, }, }); // This is to differentiate between a normal expense and a per diem expense @@ -3522,7 +3529,7 @@ function getTrackExpenseInformation(params: GetTrackExpenseInformationParams): T const {parentChatReport, moneyRequestReportID = '', existingTransactionID, participantParams, policyParams, transactionParams, retryParams} = params; const {payeeAccountID = userAccountID, payeeEmail = currentUserEmail, participant} = participantParams; const {policy, policyCategories, policyTagList} = policyParams; - const {comment, amount, currency, created, merchant, receipt, category, tag, taxCode, taxAmount, billable, linkedTrackedExpenseReportAction} = transactionParams; + const {comment, amount, currency, created, merchant, receipt, category, tag, taxCode, taxAmount, billable, linkedTrackedExpenseReportAction, attendees} = transactionParams; const optimisticData: OnyxUpdate[] = []; const successData: OnyxUpdate[] = []; @@ -3626,6 +3633,7 @@ function getTrackExpenseInformation(params: GetTrackExpenseInformationParams): T pendingFields: isDistanceRequest ? {waypoints: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD} : undefined, reimbursable: false, filename, + attendees, }, }); @@ -4858,6 +4866,7 @@ function categorizeTrackedExpense(trackedExpenseParams: TrackedExpenseParams) { engagementChoice: createdWorkspaceParams?.engagementChoice, guidedSetupData: createdWorkspaceParams?.guidedSetupData, description: transactionParams.comment, + attendees: transactionParams.attendees ? JSON.stringify(transactionParams.attendees) : undefined, }; API.write(WRITE_COMMANDS.CATEGORIZE_TRACKED_EXPENSE, parameters, {optimisticData, successData, failureData}); @@ -4960,6 +4969,7 @@ function shareTrackedExpense(trackedExpenseParams: TrackedExpenseParams) { guidedSetupData: createdWorkspaceParams?.guidedSetupData, policyName: createdWorkspaceParams?.policyName, description: transactionParams.comment, + attendees: transactionParams.attendees ? JSON.stringify(transactionParams.attendees) : undefined, accountantEmail, }; @@ -5156,7 +5166,7 @@ function requestMoney(requestMoneyInformation: RequestMoneyInformation) { function submitPerDiemExpense(submitPerDiemExpenseInformation: PerDiemExpenseInformation) { const {report, participantParams, policyParams = {}, transactionParams} = submitPerDiemExpenseInformation; const {payeeAccountID} = participantParams; - const {currency, comment = '', category, tag, created, customUnit} = transactionParams; + const {currency, comment = '', category, tag, created, customUnit, attendees} = transactionParams; if ( isEmptyObject(policyParams.policy) || @@ -5217,6 +5227,7 @@ function submitPerDiemExpense(submitPerDiemExpenseInformation: PerDiemExpenseInf transactionThreadReportID, createdReportActionIDForThread, billable, + attendees: attendees ? JSON.stringify(attendees) : undefined, }; API.write(WRITE_COMMANDS.CREATE_PER_DIEM_REQUEST, parameters, onyxData); @@ -5323,6 +5334,7 @@ function trackExpense(params: CreateTrackExpenseParams) { linkedTrackedExpenseReportAction, linkedTrackedExpenseReportID, customUnitRateID, + attendees, } = transactionData; const isMoneyRequestReport = isMoneyRequestReportReportUtils(report); @@ -5403,6 +5415,7 @@ function trackExpense(params: CreateTrackExpenseParams) { taxAmount, billable, linkedTrackedExpenseReportAction, + attendees, }, policyParams: { policy, @@ -5442,6 +5455,7 @@ function trackExpense(params: CreateTrackExpenseParams) { receipt: isFileUploadable(trackedReceipt) ? trackedReceipt : undefined, waypoints: sanitizedWaypoints, customUnitRateID: mileageRate, + attendees, }; const policyParams: TrackedExpensePolicyParams = { policyID: chatReport?.policyID, @@ -5488,6 +5502,7 @@ function trackExpense(params: CreateTrackExpenseParams) { receipt: isFileUploadable(trackedReceipt) ? trackedReceipt : undefined, waypoints: sanitizedWaypoints, customUnitRateID: mileageRate, + attendees, }; const policyParams: TrackedExpensePolicyParams = { policyID: chatReport?.policyID, @@ -5628,6 +5643,7 @@ function createSplitsAndOnyxData({ iouRequestType = CONST.IOU.REQUEST_TYPE.MANUAL, taxCode = '', taxAmount = 0, + attendees, }, }: CreateSplitsAndOnyxDataParams): SplitsAndOnyxData { const currentUserEmailForIOUSplit = addSMSDomainIfPhoneNumber(currentUserLogin); @@ -5657,6 +5673,7 @@ function createSplitsAndOnyxData({ taxAmount, billable, pendingFields: isDistanceRequest ? {waypoints: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD} : undefined, + attendees, }, }); @@ -6870,7 +6887,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest const {policy, policyCategories, policyTagList} = policyParams; const parsedComment = getParsedComment(transactionParams.comment); transactionParams.comment = parsedComment; - const {amount, comment, currency, created, category, tag, taxAmount, taxCode, merchant, billable, validWaypoints, customUnitRateID = '', splitShares = {}} = transactionParams; + const {amount, comment, currency, created, category, tag, taxAmount, taxCode, merchant, billable, validWaypoints, customUnitRateID = '', splitShares = {}, attendees} = transactionParams; // If the report is an iou or expense report, we should get the linked chat report to be passed to the getMoneyRequestInformation function const isMoneyRequestReport = isMoneyRequestReportReportUtils(report); @@ -6908,6 +6925,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest iouRequestType: CONST.IOU.REQUEST_TYPE.DISTANCE, taxCode, taxAmount, + attendees, }, }); onyxData = splitOnyxData; @@ -6931,6 +6949,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest splits: JSON.stringify(splits), chatType: splitData.chatType, description: parsedComment, + attendees: attendees ? JSON.stringify(attendees) : undefined, }; } else { const participant = participants.at(0) ?? {}; @@ -6972,6 +6991,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest taxCode, taxAmount, billable, + attendees, }, }); @@ -6998,6 +7018,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest payerEmail, customUnitRateID, description: parsedComment, + attendees: attendees ? JSON.stringify(attendees) : undefined, }; } diff --git a/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx b/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx index d2337b685e92..87fe59e2cd67 100644 --- a/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx +++ b/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx @@ -6,7 +6,7 @@ import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; import EmptySelectionListContent from '@components/EmptySelectionListContent'; import FormHelpMessage from '@components/FormHelpMessage'; -import {usePersonalDetails, useSession} from '@components/OnyxProvider'; +import {usePersonalDetails} from '@components/OnyxProvider'; import {useOptionsList} from '@components/OptionListContextProvider'; import SelectionList from '@components/SelectionList'; import InviteMemberListItem from '@components/SelectionList/InviteMemberListItem'; @@ -63,21 +63,18 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde const {isOffline} = useNetwork(); const personalDetails = usePersonalDetails(); const {didScreenTransitionEnd} = useScreenWrapperTransitionStatus(); - const [betas] = useOnyx(ONYXKEYS.BETAS); - const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); - const session = useSession(); - const isCurrentUserAttendee = attendees.some((attendee) => attendee.email === session?.email); - const [recentAttendees] = useOnyx(ONYXKEYS.NVP_RECENT_ATTENDEES); + const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: false}); + const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true}); + const [recentAttendees] = useOnyx(ONYXKEYS.NVP_RECENT_ATTENDEES, {canBeMissing: true}); const policy = usePolicy(activePolicyID); - const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false}); + const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false, canBeMissing: true}); const {options, areOptionsInitialized} = useOptionsList({ shouldInitialize: didScreenTransitionEnd, }); - const cleanSearchTerm = useMemo(() => debouncedSearchTerm.trim().toLowerCase(), [debouncedSearchTerm]); + const cleanSearchTerm = useMemo(() => searchTerm.trim().toLowerCase(), [searchTerm]); const offlineMessage: string = isOffline ? `${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}` : ''; const isPaidGroupPolicy = useMemo(() => isPaidGroupPolicyFn(policy), [policy]); - const isCategorizeOrShareAction = [CONST.IOU.ACTION.CATEGORIZE, CONST.IOU.ACTION.SHARE].some((option) => option === action); useEffect(() => { searchInServer(debouncedSearchTerm.trim()); @@ -87,17 +84,7 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde if (!areOptionsInitialized || !didScreenTransitionEnd) { getEmptyOptions(); } - const optionList = getAttendeeOptions( - options.reports, - options.personalDetails, - betas, - attendees, - recentAttendees ?? [], - iouType === CONST.IOU.TYPE.SUBMIT && action !== CONST.IOU.ACTION.SUBMIT, - !isCategorizeOrShareAction, - iouType === CONST.IOU.TYPE.INVOICE, - action, - ); + const optionList = getAttendeeOptions(options.reports, options.personalDetails, betas, attendees, recentAttendees ?? [], iouType === CONST.IOU.TYPE.SUBMIT, true, false, action); if (isPaidGroupPolicy) { const orderedOptions = orderOptions(optionList, searchTerm, { preferChatRoomsOverThreads: true, @@ -107,25 +94,8 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde optionList.recentReports = orderedOptions.recentReports; optionList.personalDetails = orderedOptions.personalDetails; } - if (optionList.currentUserOption && !isCurrentUserAttendee) { - optionList.recentReports = [optionList.currentUserOption, ...optionList.personalDetails]; - } return optionList; - }, [ - areOptionsInitialized, - didScreenTransitionEnd, - options.reports, - options.personalDetails, - betas, - attendees, - recentAttendees, - iouType, - action, - isCategorizeOrShareAction, - isPaidGroupPolicy, - isCurrentUserAttendee, - searchTerm, - ]); + }, [areOptionsInitialized, didScreenTransitionEnd, options.reports, options.personalDetails, betas, attendees, recentAttendees, iouType, action, isPaidGroupPolicy, searchTerm]); const chatOptions = useMemo(() => { if (!areOptionsInitialized) { @@ -137,14 +107,14 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde headerMessage: '', }; } - const newOptions = filterAndOrderOptions(defaultOptions, debouncedSearchTerm, { + const newOptions = filterAndOrderOptions(defaultOptions, cleanSearchTerm, { excludeLogins: CONST.EXPENSIFY_EMAILS_OBJECT, maxRecentReportsToShow: CONST.IOU.MAX_RECENT_REPORTS_TO_SHOW, preferPolicyExpenseChat: isPaidGroupPolicy, shouldAcceptName: true, }); return newOptions; - }, [areOptionsInitialized, defaultOptions, debouncedSearchTerm, isPaidGroupPolicy]); + }, [areOptionsInitialized, defaultOptions, cleanSearchTerm, isPaidGroupPolicy]); /** * Returns the sections needed for the OptionsSelector @@ -159,7 +129,7 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde const contactsWithRestOfRecents = [...restOfRecents, ...chatOptions.personalDetails]; const formatResults = formatSectionsFromSearchTerm( - debouncedSearchTerm, + cleanSearchTerm, attendees.map((attendee) => ({ ...attendee, reportID: CONST.DEFAULT_NUMBER_ID.toString(), @@ -203,7 +173,7 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde const headerMessage = getHeaderMessage( (chatOptions.personalDetails ?? []).length + (chatOptions.recentReports ?? []).length !== 0, !!chatOptions?.userToInvite, - debouncedSearchTerm.trim(), + cleanSearchTerm, attendees.some((attendee) => getPersonalDetailSearchTerms(attendee).join(' ').toLowerCase().includes(cleanSearchTerm)), ); @@ -211,7 +181,6 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde }, [ areOptionsInitialized, didScreenTransitionEnd, - debouncedSearchTerm, attendees, chatOptions.recentReports, chatOptions.personalDetails, @@ -258,7 +227,6 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde }, ]; } - onAttendeesAdded(newSelectedOptions); }, [attendees, iouType, onAttendeesAdded], @@ -302,20 +270,17 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde message={translate('iou.error.atLeastOneAttendee')} /> )} - - {!isCategorizeOrShareAction && ( -