From 35efc11784c2cef325170a45b72b8e1bab9a4cdd Mon Sep 17 00:00:00 2001 From: Jakub Korytko Date: Tue, 5 Aug 2025 14:55:58 +0200 Subject: [PATCH 1/4] Fix Members are displayed with a fallback avatar in Add Approval Workflow --- src/components/SelectionList/InviteMemberListItem.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/SelectionList/InviteMemberListItem.tsx b/src/components/SelectionList/InviteMemberListItem.tsx index bf863ec29fd7a..bd9ae8ea5c985 100644 --- a/src/components/SelectionList/InviteMemberListItem.tsx +++ b/src/components/SelectionList/InviteMemberListItem.tsx @@ -63,6 +63,11 @@ function InviteMemberListItem({ } }, [item, onCheckboxPress, onSelectRow]); + const firstItemIconID = Number(item?.icons?.at(0)?.id); + + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const accountID = !item.reportID ? item.accountID || firstItemIconID : undefined; + return ( ({ wrapperStyle={styles.productTrainingTooltipWrapper} > - {!!item.icons && ( + {(!!item.reportID || !!accountID) && ( ({ ]} singleAvatarContainerStyle={[styles.actionAvatar, styles.mr3]} reportID={item.reportID} - accountIDs={!item.reportID && item.accountID ? [item.accountID] : undefined} + accountIDs={accountID ? [accountID] : undefined} /> )} From 18a61e86d8ad8e8f18d9a0dbe6b9c0fc9e6fe6b8 Mon Sep 17 00:00:00 2001 From: Jakub Korytko Date: Tue, 5 Aug 2025 18:09:05 +0200 Subject: [PATCH 2/4] Fix Message sent by sender & receiver show the same invoice room avatar --- .../ReportActionAvatars/useReportActionAvatars.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/ReportActionAvatars/useReportActionAvatars.ts b/src/components/ReportActionAvatars/useReportActionAvatars.ts index 0a11e857e2dfc..6ed81623fe8f2 100644 --- a/src/components/ReportActionAvatars/useReportActionAvatars.ts +++ b/src/components/ReportActionAvatars/useReportActionAvatars.ts @@ -167,15 +167,20 @@ function useReportActionAvatars({ fallbackIcon, }; - const avatarsForAccountIDs: IconType[] = accountIDs.map((id) => ({ + const shouldUseActorAccountID = isAInvoiceReport && !isAReportPreviewAction; + const accountIDsToMap = shouldUseActorAccountID && actorAccountID ? [actorAccountID] : accountIDs; + + const avatarsForAccountIDs: IconType[] = accountIDsToMap.map((id) => ({ id, type: CONST.ICON_TYPE_AVATAR, source: personalDetails?.[id]?.avatar ?? FallbackAvatar, - name: personalDetails?.[id]?.login ?? '', + name: personalDetails?.[id]?.[shouldUseActorAccountID ? 'displayName' : 'login'] ?? '', })); + const shouldUseMappedAccountIDs = avatarsForAccountIDs.length > 0 && (avatarType === CONST.REPORT_ACTION_AVATARS.TYPE.MULTIPLE || shouldUseActorAccountID); + return { - avatars: avatarsForAccountIDs.length > 0 && avatarType === CONST.REPORT_ACTION_AVATARS.TYPE.MULTIPLE ? avatarsForAccountIDs : [primaryAvatar, secondaryAvatar], + avatars: shouldUseMappedAccountIDs ? avatarsForAccountIDs : [primaryAvatar, secondaryAvatar], avatarType, details: { ...(personalDetails?.[accountID] ?? {}), From 51a4eee73be471eeb39f2e08324ec70891544bc5 Mon Sep 17 00:00:00 2001 From: Jakub Korytko Date: Tue, 5 Aug 2025 18:52:36 +0200 Subject: [PATCH 3/4] Fix Chat - Tooltip of non-existing account does not show email --- .../ReportActionAvatar.tsx | 23 +++++++++++++++---- src/components/ReportActionAvatars/index.tsx | 8 +++++++ .../useReportActionAvatars.ts | 3 ++- src/components/SelectionList/UserListItem.tsx | 1 + 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/components/ReportActionAvatars/ReportActionAvatar.tsx b/src/components/ReportActionAvatars/ReportActionAvatar.tsx index fececbe28857e..104791927ba83 100644 --- a/src/components/ReportActionAvatars/ReportActionAvatar.tsx +++ b/src/components/ReportActionAvatars/ReportActionAvatar.tsx @@ -70,6 +70,7 @@ function ReportActionAvatarSingle({ accountID, fallbackIcon, isInReportAction, + fallbackUsername, }: { avatar: IconType | undefined; size: ValueOf; @@ -79,6 +80,7 @@ function ReportActionAvatarSingle({ delegateAccountID?: number; fallbackIcon?: AvatarSource; isInReportAction?: boolean; + fallbackUsername?: string; }) { const StyleUtils = useStyleUtils(); const avatarContainerStyles = StyleUtils.getContainerStyles(size, isInReportAction); @@ -89,7 +91,8 @@ function ReportActionAvatarSingle({ delegateAccountID={delegateAccountID} icon={avatar} fallbackUserDetails={{ - displayName: avatar?.name, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + displayName: fallbackUsername || avatar?.name, }} shouldRender={shouldShowTooltip} > @@ -118,6 +121,7 @@ function ReportActionAvatarSubscript({ noRightMarginOnContainer, subscriptAvatarBorderColor, subscriptCardFeed, + fallbackUsername, }: { primaryAvatar: IconType; secondaryAvatar: IconType; @@ -126,6 +130,7 @@ function ReportActionAvatarSubscript({ noRightMarginOnContainer?: boolean; subscriptAvatarBorderColor?: ColorValue; subscriptCardFeed?: CompanyCardFeed | typeof CONST.EXPENSIFY_CARD.BANK; + fallbackUsername?: string; }) { const theme = useTheme(); const styles = useThemeStyles(); @@ -163,7 +168,8 @@ function ReportActionAvatarSubscript({ accountID={Number(primaryAvatar.id ?? CONST.DEFAULT_NUMBER_ID)} icon={primaryAvatar} fallbackUserDetails={{ - displayName: primaryAvatar.name, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + displayName: fallbackUsername || primaryAvatar.name, }} > @@ -266,11 +272,13 @@ function ReportActionAvatarMultipleHorizontal({ icons: unsortedIcons, isInReportAction, sort: sortAvatars, + fallbackUsername, }: HorizontalStacking & { size: ValueOf; shouldShowTooltip: boolean; icons: IconType[]; isInReportAction: boolean; + fallbackUsername?: string; }) { const theme = useTheme(); const styles = useThemeStyles(); @@ -330,7 +338,8 @@ function ReportActionAvatarMultipleHorizontal({ accountID={Number(icon.id)} icon={icon} fallbackUserDetails={{ - displayName: icon.name, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + displayName: fallbackUsername || icon.name, }} shouldRender={shouldShowTooltip} > @@ -404,6 +413,7 @@ function ReportActionAvatarMultipleDiagonal({ useMidSubscriptSize, secondaryAvatarContainerStyle, isHovered = false, + fallbackUsername, }: { size: ValueOf; shouldShowTooltip: boolean; @@ -412,6 +422,7 @@ function ReportActionAvatarMultipleDiagonal({ useMidSubscriptSize: boolean; secondaryAvatarContainerStyle?: StyleProp; isHovered?: boolean; + fallbackUsername?: string; }) { const theme = useTheme(); const styles = useThemeStyles(); @@ -472,7 +483,8 @@ function ReportActionAvatarMultipleDiagonal({ accountID={Number(icons.at(0)?.id)} icon={icons.at(0)} fallbackUserDetails={{ - displayName: icons.at(0)?.name, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + displayName: fallbackUsername || icons.at(0)?.name, }} shouldRender={shouldShowTooltip} > @@ -502,7 +514,8 @@ function ReportActionAvatarMultipleDiagonal({ accountID={Number(icons.at(1)?.id)} icon={icons.at(1)} fallbackUserDetails={{ - displayName: icons.at(1)?.name, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + displayName: fallbackUsername || icons.at(1)?.name, }} shouldRender={shouldShowTooltip} > diff --git a/src/components/ReportActionAvatars/index.tsx b/src/components/ReportActionAvatars/index.tsx index 1d886378fbca0..001fcd4ccecae 100644 --- a/src/components/ReportActionAvatars/index.tsx +++ b/src/components/ReportActionAvatars/index.tsx @@ -48,6 +48,9 @@ type ReportActionAvatarsProps = { /** Subscript card feed to display instead of the second avatar */ subscriptCardFeed?: CompanyCardFeed | typeof CONST.EXPENSIFY_CARD.BANK; + + /** Username used as a fallback for avatar tooltip */ + fallbackUsername?: string; }; /** @@ -72,6 +75,7 @@ function ReportActionAvatars({ secondaryAvatarContainerStyle, useMidSubscriptSizeForMultipleAvatars = false, isInReportAction = false, + fallbackUsername, }: ReportActionAvatarsProps) { const accountIDs = passedAccountIDs.filter((accountID) => accountID !== CONST.DEFAULT_NUMBER_ID); @@ -120,6 +124,7 @@ function ReportActionAvatars({ noRightMarginOnContainer={noRightMarginOnSubscriptContainer} subscriptAvatarBorderColor={subscriptAvatarBorderColor} subscriptCardFeed={subscriptCardFeed} + fallbackUsername={fallbackUsername} /> ); } @@ -133,6 +138,7 @@ function ReportActionAvatars({ icons={icons} isInReportAction={isInReportAction} shouldShowTooltip={shouldShowTooltip} + fallbackUsername={fallbackUsername} /> ); } @@ -147,6 +153,7 @@ function ReportActionAvatars({ useMidSubscriptSize={useMidSubscriptSizeForMultipleAvatars} secondaryAvatarContainerStyle={secondaryAvatarContainerStyle} isHovered={isHovered} + fallbackUsername={fallbackUsername} /> ); } @@ -160,6 +167,7 @@ function ReportActionAvatars({ accountID={Number(delegateAccountID ?? primaryAvatar.id ?? CONST.DEFAULT_NUMBER_ID)} delegateAccountID={source.action?.delegateAccountID} fallbackIcon={primaryAvatar.fallbackIcon} + fallbackUsername={fallbackUsername} /> ); } diff --git a/src/components/ReportActionAvatars/useReportActionAvatars.ts b/src/components/ReportActionAvatars/useReportActionAvatars.ts index 6ed81623fe8f2..eb49dfeb2aff8 100644 --- a/src/components/ReportActionAvatars/useReportActionAvatars.ts +++ b/src/components/ReportActionAvatars/useReportActionAvatars.ts @@ -178,6 +178,7 @@ function useReportActionAvatars({ })); const shouldUseMappedAccountIDs = avatarsForAccountIDs.length > 0 && (avatarType === CONST.REPORT_ACTION_AVATARS.TYPE.MULTIPLE || shouldUseActorAccountID); + const shouldUsePrimaryAvatarID = isWorkspaceActor && !!primaryAvatar.id; return { avatars: shouldUseMappedAccountIDs ? avatarsForAccountIDs : [primaryAvatar, secondaryAvatar], @@ -187,7 +188,7 @@ function useReportActionAvatars({ shouldDisplayAllActors: displayAllActors, isWorkspaceActor, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - actorHint: String(isWorkspaceActor ? primaryAvatar.id : login || (defaultDisplayName ?? '')).replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''), + actorHint: String(shouldUsePrimaryAvatarID ? primaryAvatar.id : login || defaultDisplayName || 'Unknown user').replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''), accountID, delegateAccountID: !isWorkspaceActor && delegatePersonalDetails ? actorAccountID : undefined, }, diff --git a/src/components/SelectionList/UserListItem.tsx b/src/components/SelectionList/UserListItem.tsx index 37d92295de3d2..b2c9ba59b52c7 100644 --- a/src/components/SelectionList/UserListItem.tsx +++ b/src/components/SelectionList/UserListItem.tsx @@ -111,6 +111,7 @@ function UserListItem({ reportID={item.reportID} accountIDs={[Number(item.accountID)]} singleAvatarContainerStyle={[styles.actionAvatar, styles.mr3]} + fallbackUsername={item.text ?? item.alternateText ?? undefined} /> )} From dd47eff7aec4a44d682d02989092b6c9706e81bb Mon Sep 17 00:00:00 2001 From: Jakub Korytko Date: Tue, 5 Aug 2025 19:13:37 +0200 Subject: [PATCH 4/4] Rename fallbackUsername to fallbackDisplayName --- .../ReportActionAvatar.tsx | 26 +++++++++---------- src/components/ReportActionAvatars/index.tsx | 14 +++++----- src/components/SelectionList/UserListItem.tsx | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/components/ReportActionAvatars/ReportActionAvatar.tsx b/src/components/ReportActionAvatars/ReportActionAvatar.tsx index 8eb461501ef04..b7369d806e67a 100644 --- a/src/components/ReportActionAvatars/ReportActionAvatar.tsx +++ b/src/components/ReportActionAvatars/ReportActionAvatar.tsx @@ -107,7 +107,7 @@ function ReportActionAvatarSingle({ fallbackIcon, isInReportAction, useProfileNavigationWrapper, - fallbackUsername, + fallbackDisplayName, }: { avatar: IconType | undefined; size: ValueOf; @@ -118,7 +118,7 @@ function ReportActionAvatarSingle({ fallbackIcon?: AvatarSource; isInReportAction?: boolean; useProfileNavigationWrapper?: boolean; - fallbackUsername?: string; + fallbackDisplayName?: string; }) { const StyleUtils = useStyleUtils(); const avatarContainerStyles = StyleUtils.getContainerStyles(size, isInReportAction); @@ -130,7 +130,7 @@ function ReportActionAvatarSingle({ icon={avatar} fallbackUserDetails={{ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - displayName: fallbackUsername || avatar?.name, + displayName: fallbackDisplayName || avatar?.name, }} shouldRender={shouldShowTooltip} > @@ -160,7 +160,7 @@ function ReportActionAvatarSubscript({ noRightMarginOnContainer, subscriptAvatarBorderColor, subscriptCardFeed, - fallbackUsername, + fallbackDisplayName, useProfileNavigationWrapper, }: { primaryAvatar: IconType; @@ -170,7 +170,7 @@ function ReportActionAvatarSubscript({ noRightMarginOnContainer?: boolean; subscriptAvatarBorderColor?: ColorValue; subscriptCardFeed?: CompanyCardFeed | typeof CONST.EXPENSIFY_CARD.BANK; - fallbackUsername?: string; + fallbackDisplayName?: string; useProfileNavigationWrapper?: boolean; }) { const theme = useTheme(); @@ -210,7 +210,7 @@ function ReportActionAvatarSubscript({ icon={primaryAvatar} fallbackUserDetails={{ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - displayName: fallbackUsername || primaryAvatar.name, + displayName: fallbackDisplayName || primaryAvatar.name, }} > @@ -316,13 +316,13 @@ function ReportActionAvatarMultipleHorizontal({ isInReportAction, sort: sortAvatars, useProfileNavigationWrapper, - fallbackUsername, + fallbackDisplayName, }: HorizontalStacking & { size: ValueOf; shouldShowTooltip: boolean; icons: IconType[]; isInReportAction: boolean; - fallbackUsername?: string; + fallbackDisplayName?: string; useProfileNavigationWrapper?: boolean; }) { const theme = useTheme(); @@ -384,7 +384,7 @@ function ReportActionAvatarMultipleHorizontal({ icon={icon} fallbackUserDetails={{ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - displayName: fallbackUsername || icon.name, + displayName: fallbackDisplayName || icon.name, }} shouldRender={shouldShowTooltip} > @@ -460,7 +460,7 @@ function ReportActionAvatarMultipleDiagonal({ secondaryAvatarContainerStyle, isHovered = false, useProfileNavigationWrapper, - fallbackUsername, + fallbackDisplayName, }: { size: ValueOf; shouldShowTooltip: boolean; @@ -470,7 +470,7 @@ function ReportActionAvatarMultipleDiagonal({ secondaryAvatarContainerStyle?: StyleProp; isHovered?: boolean; useProfileNavigationWrapper?: boolean; - fallbackUsername?: string; + fallbackDisplayName?: string; }) { const theme = useTheme(); const styles = useThemeStyles(); @@ -532,7 +532,7 @@ function ReportActionAvatarMultipleDiagonal({ icon={icons.at(0)} fallbackUserDetails={{ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - displayName: fallbackUsername || icons.at(0)?.name, + displayName: fallbackDisplayName || icons.at(0)?.name, }} shouldRender={shouldShowTooltip} > @@ -564,7 +564,7 @@ function ReportActionAvatarMultipleDiagonal({ icon={icons.at(1)} fallbackUserDetails={{ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - displayName: fallbackUsername || icons.at(1)?.name, + displayName: fallbackDisplayName || icons.at(1)?.name, }} shouldRender={shouldShowTooltip} > diff --git a/src/components/ReportActionAvatars/index.tsx b/src/components/ReportActionAvatars/index.tsx index a8d11c34e34e9..f3ec5b24563b5 100644 --- a/src/components/ReportActionAvatars/index.tsx +++ b/src/components/ReportActionAvatars/index.tsx @@ -55,8 +55,8 @@ type ReportActionAvatarsProps = { /** Whether we want to be redirected to profile on avatars click */ useProfileNavigationWrapper?: boolean; - /** Username used as a fallback for avatar tooltip */ - fallbackUsername?: string; + /** Display name used as a fallback for avatar tooltip */ + fallbackDisplayName?: string; }; /** @@ -84,7 +84,7 @@ function ReportActionAvatars({ useMidSubscriptSizeForMultipleAvatars = false, isInReportAction = false, useProfileNavigationWrapper, - fallbackUsername, + fallbackDisplayName, }: ReportActionAvatarsProps) { const accountIDs = passedAccountIDs.filter((accountID) => accountID !== CONST.DEFAULT_NUMBER_ID); @@ -135,7 +135,7 @@ function ReportActionAvatars({ subscriptAvatarBorderColor={subscriptAvatarBorderColor} subscriptCardFeed={subscriptCardFeed} useProfileNavigationWrapper={useProfileNavigationWrapper} - fallbackUsername={fallbackUsername} + fallbackDisplayName={fallbackDisplayName} /> ); } @@ -150,7 +150,7 @@ function ReportActionAvatars({ isInReportAction={isInReportAction} shouldShowTooltip={shouldShowTooltip} useProfileNavigationWrapper={useProfileNavigationWrapper} - fallbackUsername={fallbackUsername} + fallbackDisplayName={fallbackDisplayName} /> ); } @@ -165,7 +165,7 @@ function ReportActionAvatars({ useMidSubscriptSize={useMidSubscriptSizeForMultipleAvatars} secondaryAvatarContainerStyle={secondaryAvatarContainerStyle} isHovered={isHovered} - fallbackUsername={fallbackUsername} + fallbackDisplayName={fallbackDisplayName} useProfileNavigationWrapper={useProfileNavigationWrapper} /> ); @@ -180,7 +180,7 @@ function ReportActionAvatars({ accountID={Number(delegateAccountID ?? primaryAvatar.id ?? CONST.DEFAULT_NUMBER_ID)} delegateAccountID={source.action?.delegateAccountID} fallbackIcon={primaryAvatar.fallbackIcon} - fallbackUsername={fallbackUsername} + fallbackDisplayName={fallbackDisplayName} useProfileNavigationWrapper={useProfileNavigationWrapper} /> ); diff --git a/src/components/SelectionList/UserListItem.tsx b/src/components/SelectionList/UserListItem.tsx index 0777b3ff4974b..a26b55286f02b 100644 --- a/src/components/SelectionList/UserListItem.tsx +++ b/src/components/SelectionList/UserListItem.tsx @@ -112,7 +112,7 @@ function UserListItem({ accountIDs={[Number(item.accountID)]} policyID={!item.reportID && !item.accountID ? item.policyID : undefined} singleAvatarContainerStyle={[styles.actionAvatar, styles.mr3]} - fallbackUsername={item.text ?? item.alternateText ?? undefined} + fallbackDisplayName={item.text ?? item.alternateText ?? undefined} /> )}