diff --git a/src/components/ReportWelcomeText.js b/src/components/ReportWelcomeText.js index e1a6d4d4f6c1..213d41c94a3c 100644 --- a/src/components/ReportWelcomeText.js +++ b/src/components/ReportWelcomeText.js @@ -82,11 +82,7 @@ function ReportWelcomeText(props) { {isPolicyExpenseChat && ( <> {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne')} - - {/* Use the policyExpenseChat owner's first name or their display name if it's undefined or an empty string */} - {lodashGet(props.personalDetails, [props.report.ownerAccountID, 'firstName']) || - lodashGet(props.personalDetails, [props.report.ownerAccountID, 'displayName'], '')} - + {ReportUtils.getDisplayNameForParticipant(props.report.ownerAccountID)} {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo')} {ReportUtils.getPolicyName(props.report)} {props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree')} diff --git a/src/components/UserDetailsTooltip/BaseUserDetailsTooltip.web.js b/src/components/UserDetailsTooltip/BaseUserDetailsTooltip.web.js index 871173d01b56..794ab130ed96 100644 --- a/src/components/UserDetailsTooltip/BaseUserDetailsTooltip.web.js +++ b/src/components/UserDetailsTooltip/BaseUserDetailsTooltip.web.js @@ -8,6 +8,7 @@ import Avatar from '@components/Avatar'; import Tooltip from '@components/Tooltip'; import useLocalize from '@hooks/useLocalize'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; +import * as ReportUtils from '@libs/ReportUtils'; import * as UserUtils from '@libs/UserUtils'; import styles from '@styles/styles'; import CONST from '@src/CONST'; @@ -18,7 +19,7 @@ function BaseUserDetailsTooltip(props) { const {translate} = useLocalize(); const userDetails = lodashGet(props.personalDetailsList, props.accountID, props.fallbackUserDetails); - let userDisplayName = userDetails.displayName ? userDetails.displayName.trim() : ''; + let userDisplayName = ReportUtils.getDisplayNameForParticipant(props.accountID); let userLogin = (userDetails.login || '').trim() && !_.isEqual(userDetails.login, userDetails.displayName) ? Str.removeSMSDomain(userDetails.login) : ''; let userAvatar = userDetails.avatar; let userAccountID = props.accountID; @@ -27,7 +28,7 @@ function BaseUserDetailsTooltip(props) { // the Copilot feature is implemented. if (props.delegateAccountID) { const delegateUserDetails = lodashGet(props.personalDetailsList, props.delegateAccountID, {}); - const delegateUserDisplayName = delegateUserDetails.displayName ? delegateUserDetails.displayName.trim() : ''; + const delegateUserDisplayName = ReportUtils.getDisplayNameForParticipant(props.delegateAccountID); userDisplayName = `${delegateUserDisplayName} (${translate('reportAction.asCopilot')} ${userDisplayName})`; userLogin = delegateUserDetails.login; userAvatar = delegateUserDetails.avatar; diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 1ab715b66aeb..21541d558b76 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -1229,6 +1229,7 @@ function getPersonalDetailsForAccountID(accountID) { return ( (allPersonalDetails && allPersonalDetails[accountID]) || { avatar: UserUtils.getDefaultAvatar(accountID), + isOptimisticPersonalDetail: true, } ); } @@ -1238,28 +1239,39 @@ function getPersonalDetailsForAccountID(accountID) { * * @param {Number} accountID * @param {Boolean} [shouldUseShortForm] + * @param {Boolean} shouldFallbackToHidden * @returns {String} */ -function getDisplayNameForParticipant(accountID, shouldUseShortForm = false) { +function getDisplayNameForParticipant(accountID, shouldUseShortForm = false, shouldFallbackToHidden = true) { if (!accountID) { return ''; } const personalDetails = getPersonalDetailsForAccountID(accountID); + // this is to check if account is an invite/optimistically created one + // and prevent from falling back to 'Hidden', so a correct value is shown + // when searching for a new user + if (lodashGet(personalDetails, 'isOptimisticPersonalDetail') === true) { + return personalDetails.login || ''; + } const longName = personalDetails.displayName; const shortName = personalDetails.firstName || longName; + if (!longName && !personalDetails.login && shouldFallbackToHidden) { + return Localize.translateLocal('common.hidden'); + } return shouldUseShortForm ? shortName : longName; } /** * @param {Object} personalDetailsList * @param {Boolean} isMultipleParticipantReport + * @param {Boolean} shouldFallbackToHidden * @returns {Array} */ -function getDisplayNamesWithTooltips(personalDetailsList, isMultipleParticipantReport) { +function getDisplayNamesWithTooltips(personalDetailsList, isMultipleParticipantReport, shouldFallbackToHidden) { return _.chain(personalDetailsList) .map((user) => { const accountID = Number(user.accountID); - const displayName = getDisplayNameForParticipant(accountID, isMultipleParticipantReport) || user.login || ''; + const displayName = getDisplayNameForParticipant(accountID, isMultipleParticipantReport, shouldFallbackToHidden) || user.login || ''; const avatar = UserUtils.getDefaultAvatar(accountID); let pronouns = user.pronouns; diff --git a/src/pages/home/report/ParticipantLocalTime.js b/src/pages/home/report/ParticipantLocalTime.js index 17f87f0391ea..2ce0054a3e59 100644 --- a/src/pages/home/report/ParticipantLocalTime.js +++ b/src/pages/home/report/ParticipantLocalTime.js @@ -45,6 +45,10 @@ function ParticipantLocalTime(props) { const reportRecipientDisplayName = lodashGet(props, 'participant.firstName') || lodashGet(props, 'participant.displayName'); + if (!reportRecipientDisplayName) { + return null; + } + return ( { function ReportActionItemSingle(props) { const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const actorAccountID = props.action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && props.iouReport ? props.iouReport.managerID : props.action.actorAccountID; - let {displayName} = personalDetails[actorAccountID] || {}; + let displayName = ReportUtils.getDisplayNameForParticipant(actorAccountID); const {avatar, login, pendingFields, status, fallbackIcon} = personalDetails[actorAccountID] || {}; let actorHint = (login || displayName || '').replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''); const displayAllActors = useMemo(() => props.action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && props.iouReport, [props.action.actionName, props.iouReport]); @@ -108,12 +108,12 @@ function ReportActionItemSingle(props) { // If this is a report preview, display names and avatars of both people involved let secondaryAvatar = {}; - const primaryDisplayName = displayName; + const primaryDisplayName = ReportUtils.getDisplayNameForParticipant(actorAccountID); if (displayAllActors) { // The ownerAccountID and actorAccountID can be the same if the a user requests money back from the IOU's original creator, in that case we need to use managerID to avoid displaying the same user twice const secondaryAccountId = props.iouReport.ownerAccountID === actorAccountID ? props.iouReport.managerID : props.iouReport.ownerAccountID; const secondaryUserDetails = personalDetails[secondaryAccountId] || {}; - const secondaryDisplayName = lodashGet(secondaryUserDetails, 'displayName', ''); + const secondaryDisplayName = ReportUtils.getDisplayNameForParticipant(secondaryAccountId); displayName = `${primaryDisplayName} & ${secondaryDisplayName}`; secondaryAvatar = { source: UserUtils.getAvatar(secondaryUserDetails.avatar, secondaryAccountId), diff --git a/src/pages/iou/steps/MoneyRequestConfirmPage.js b/src/pages/iou/steps/MoneyRequestConfirmPage.js index 79cf48ce634d..6b570ee872c3 100644 --- a/src/pages/iou/steps/MoneyRequestConfirmPage.js +++ b/src/pages/iou/steps/MoneyRequestConfirmPage.js @@ -71,10 +71,13 @@ function MoneyRequestConfirmPage(props) { const [receiptFile, setReceiptFile] = useState(); const participants = useMemo( () => - _.map(props.iou.participants, (participant) => { - const isPolicyExpenseChat = lodashGet(participant, 'isPolicyExpenseChat', false); - return isPolicyExpenseChat ? OptionsListUtils.getPolicyExpenseReportOption(participant) : OptionsListUtils.getParticipantsOption(participant, props.personalDetails); - }), + _.chain(props.iou.participants) + .map((participant) => { + const isPolicyExpenseChat = lodashGet(participant, 'isPolicyExpenseChat', false); + return isPolicyExpenseChat ? OptionsListUtils.getPolicyExpenseReportOption(participant) : OptionsListUtils.getParticipantsOption(participant, props.personalDetails); + }) + .filter((participant) => !!participant.login || !!participant.text) + .value(), [props.iou.participants, props.personalDetails], ); const isPolicyExpenseChat = useMemo(() => ReportUtils.isPolicyExpenseChat(ReportUtils.getRootParentReport(props.report)), [props.report]);