diff --git a/src/components/UserDetailsTooltip/index.js b/src/components/UserDetailsTooltip/index.js index 786531801837..16fdacd8964a 100644 --- a/src/components/UserDetailsTooltip/index.js +++ b/src/components/UserDetailsTooltip/index.js @@ -9,33 +9,49 @@ import Tooltip from '../Tooltip'; import {propTypes, defaultProps} from './userDetailsTooltipPropTypes'; import styles from '../../styles/styles'; import ONYXKEYS from '../../ONYXKEYS'; +import withLocalize from '../withLocalize'; +import compose from '../../libs/compose'; import * as UserUtils from '../../libs/UserUtils'; function UserDetailsTooltip(props) { const userDetails = lodashGet(props.personalDetailsList, props.accountID, props.fallbackUserDetails); + let userDisplayName = userDetails.displayName ? userDetails.displayName.trim() : ''; + let userLogin = (userDetails.login || '').trim() && !_.isEqual(userDetails.login, userDetails.displayName) ? Str.removeSMSDomain(userDetails.login) : ''; + let userAvatar = userDetails.avatar; + let userAccountID = props.accountID; + + // We replace the actor's email, name, and avatar with the Copilot manually for now. This will be improved upon when + // the Copilot feature is implemented. + if (props.delegateAccountID) { + const delegateUserDetails = lodashGet(props.personalDetailsList, props.delegateAccountID, {}); + const delegateUserDisplayName = delegateUserDetails.displayName ? delegateUserDetails.displayName.trim() : ''; + userDisplayName = `${delegateUserDisplayName} (${props.translate('reportAction.asCopilot')} ${userDisplayName})`; + userLogin = delegateUserDetails.login; + userAvatar = delegateUserDetails.avatar; + userAccountID = props.delegateAccountID; + } + const renderTooltipContent = useCallback( () => ( - - {String(userDetails.displayName).trim() ? userDetails.displayName : ''} - + {userDisplayName} - {String(userDetails.login || '').trim() && !_.isEqual(userDetails.login, userDetails.displayName) ? Str.removeSMSDomain(userDetails.login) : ''} + {(userLogin || '').trim() && !_.isEqual(userLogin, userDisplayName) ? Str.removeSMSDomain(userLogin) : ''} ), - [userDetails.avatar, userDetails.displayName, userDetails.login, userDetails.accountID], + [userAvatar, userDisplayName, userLogin, userAccountID], ); - if (!userDetails.displayName && !userDetails.login) { + if (!userDisplayName && !userLogin) { return props.children; } @@ -46,8 +62,11 @@ UserDetailsTooltip.propTypes = propTypes; UserDetailsTooltip.defaultProps = defaultProps; UserDetailsTooltip.displayName = 'UserDetailsTooltip'; -export default withOnyx({ - personalDetailsList: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, -})(UserDetailsTooltip); +export default compose( + withLocalize, + withOnyx({ + personalDetailsList: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + }), +)(UserDetailsTooltip); diff --git a/src/components/UserDetailsTooltip/userDetailsTooltipPropTypes.js b/src/components/UserDetailsTooltip/userDetailsTooltipPropTypes.js index 4d34c73ef1ba..0bf0f5f9b7cb 100644 --- a/src/components/UserDetailsTooltip/userDetailsTooltipPropTypes.js +++ b/src/components/UserDetailsTooltip/userDetailsTooltipPropTypes.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import personalDetailsPropType from '../../pages/personalDetailsPropType'; +import {withLocalizePropTypes} from '../withLocalize'; const propTypes = { /** User's Account ID */ @@ -17,12 +18,19 @@ const propTypes = { children: PropTypes.node.isRequired, /** List of personalDetails (keyed by accountID) */ personalDetailsList: PropTypes.objectOf(personalDetailsPropType), + + /** The accountID of the copilot who took this action on behalf of the user */ + delegateAccountID: PropTypes.number, + + /** Localization props */ + ...withLocalizePropTypes, }; const defaultProps = { accountID: '', fallbackUserDetails: {displayName: '', login: '', avatar: ''}, personalDetailsList: {}, + delegateAccountID: 0, }; export {propTypes, defaultProps}; diff --git a/src/languages/en.js b/src/languages/en.js index 0dca451b0701..36532923a59b 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -297,6 +297,9 @@ export default { sayHello: 'Say hello!', usePlusButton: '\n\nYou can also use the + button below to send or request money!', }, + reportAction: { + asCopilot: 'as copilot for', + }, mentionSuggestions: { hereAlternateText: 'Notify everyone online in this room', }, diff --git a/src/languages/es.js b/src/languages/es.js index 10e31f7225e1..70645d8632b7 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -296,6 +296,9 @@ export default { sayHello: '¡Saluda!', usePlusButton: '\n\n¡También puedes usar el botón + de abajo para enviar o pedir dinero!', }, + reportAction: { + asCopilot: 'como copiloto de', + }, mentionSuggestions: { hereAlternateText: 'Notificar a todos los que estén en linea de esta sala', }, diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 65558110ba45..010295c0b0d3 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -57,6 +57,9 @@ const propTypes = { // Additional styles to add after local styles style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), + /** The accountID of the copilot who took this action on behalf of the user */ + delegateAccountID: PropTypes.number, + ...windowDimensionsPropTypes, /** localization props */ @@ -75,6 +78,7 @@ const defaultProps = { isSingleLine: false, source: '', style: [], + delegateAccountID: 0, }; function ReportActionItemFragment(props) { @@ -145,7 +149,10 @@ function ReportActionItemFragment(props) { } case 'TEXT': return ( - + { function ReportActionItemSingle(props) { const actorAccountID = props.action.actorAccountID; + let {displayName} = props.personalDetailsList[actorAccountID] || {}; + const {avatar, pendingFields} = props.personalDetailsList[actorAccountID] || {}; + let actorHint = lodashGet(props.action, 'actorEmail', '').replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''); const isWorkspaceActor = ReportUtils.isPolicyExpenseChat(props.report) && !actorAccountID; - const actorDetails = props.personalDetailsList[actorAccountID] || {}; - const displayName = isWorkspaceActor ? ReportUtils.getPolicyName(props.report) : actorDetails.displayName; - const actorHint = isWorkspaceActor ? displayName : lodashGet(props.action, 'actorEmail', '').replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''); - const pendingFields = isWorkspaceActor ? {} : actorDetails.pendingFields; - const avatarSource = isWorkspaceActor ? ReportUtils.getWorkspaceAvatar(props.report) : UserUtils.getAvatar(actorDetails.avatar, actorAccountID); + let avatarSource = UserUtils.getAvatar(avatar, actorAccountID); + + if (isWorkspaceActor) { + displayName = ReportUtils.getPolicyName(props.report); + actorHint = displayName; + avatarSource = ReportUtils.getWorkspaceAvatar(props.report); + } else if (props.action.delegateAccountID) { + // We replace the actor's email, name, and avatar with the Copilot manually for now. This will be improved upon when + // the Copilot feature is implemented. + const delegateDetails = props.personalDetailsList[props.action.delegateAccountID]; + const delegateDisplayName = delegateDetails.displayName; + actorHint = `${delegateDisplayName} (${props.translate('reportAction.asCopilot')} ${displayName})`; + displayName = actorHint; + avatarSource = UserUtils.getAvatar(delegateDetails.avatar, props.action.delegateAccountID); + } // Since the display name for a report action message is delivered with the report history as an array of fragments // we'll need to take the displayName from personal details and have it be in the same format for now. Eventually, @@ -95,9 +108,9 @@ function ReportActionItemSingle(props) { if (isWorkspaceActor) { showWorkspaceDetails(props.report.reportID); } else { - showUserDetails(actorAccountID); + showUserDetails(props.action.delegateAccountID ? props.action.delegateAccountID : actorAccountID); } - }, [isWorkspaceActor, props.report.reportID, actorAccountID]); + }, [isWorkspaceActor, props.report.reportID, actorAccountID, props.action.delegateAccountID]); return ( @@ -119,7 +132,10 @@ function ReportActionItemSingle(props) { noMargin /> ) : ( - + ))}