diff --git a/src/libs/PersonalDetailsUtils.js b/src/libs/PersonalDetailsUtils.js index 26c0a67aae48..d3d7d6b84af7 100644 --- a/src/libs/PersonalDetailsUtils.js +++ b/src/libs/PersonalDetailsUtils.js @@ -6,9 +6,13 @@ import * as Localize from './Localize'; import * as UserUtils from './UserUtils'; let personalDetails = []; +let allPersonalDetails = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, - callback: (val) => (personalDetails = _.values(val)), + callback: (val) => { + personalDetails = _.values(val); + allPersonalDetails = val; + }, }); /** @@ -91,4 +95,61 @@ function getLoginsByAccountIDs(accountIDs) { ); } -export {getDisplayNameOrDefault, getPersonalDetailsByIDs, getAccountIDsByLogins, getLoginsByAccountIDs}; +/** + * Given a list of logins and accountIDs, return Onyx data for users with no existing personal details stored + * + * @param {Array} logins Array of user logins + * @param {Array} accountIDs Array of user accountIDs + * @returns {Object} - Object with optimisticData, successData and failureData (object of personal details objects) + */ +function getNewPersonalDetailsOnyxData(logins, accountIDs) { + const optimisticData = {}; + const successData = {}; + const failureData = {}; + + _.each(logins, (login, index) => { + const accountID = accountIDs[index]; + + if (_.isEmpty(allPersonalDetails[accountID])) { + optimisticData[accountID] = { + login, + accountID, + avatar: UserUtils.getDefaultAvatarURL(accountID), + displayName: login, + }; + + /** + * Cleanup the optimistic user to ensure it does not permanently persist. + * This is done to prevent duplicate entries (upon success) since the BE will return other personal details with the correct account IDs. + */ + successData[accountID] = null; + failureData[accountID] = null; + } + }); + + return { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: optimisticData, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: successData, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: failureData, + }, + ], + }; +} + +export {getDisplayNameOrDefault, getPersonalDetailsByIDs, getAccountIDsByLogins, getLoginsByAccountIDs, getNewPersonalDetailsOnyxData}; diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 5b0afa1caf69..0548b6c10ddb 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -12,6 +12,7 @@ import ROUTES from '../../ROUTES'; import * as OptionsListUtils from '../OptionsListUtils'; import * as ErrorUtils from '../ErrorUtils'; import * as ReportUtils from '../ReportUtils'; +import * as PersonalDetailsUtils from '../PersonalDetailsUtils'; import Log from '../Log'; import Permissions from '../Permissions'; @@ -354,7 +355,9 @@ function createPolicyExpenseChats(policyID, invitedEmailsToAccountIDs, betas) { */ function addMembersToWorkspace(invitedEmailsToAccountIDs, welcomeNote, policyID, betas) { const membersListKey = `${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${policyID}`; + const logins = _.map(_.keys(invitedEmailsToAccountIDs), (memberLogin) => OptionsListUtils.addSMSDomainIfPhoneNumber(memberLogin)); const accountIDs = _.values(invitedEmailsToAccountIDs); + const newPersonalDetailsOnyxData = PersonalDetailsUtils.getNewPersonalDetailsOnyxData(logins, accountIDs); // create onyx data for policy expense chats for each new member const membersChats = createPolicyExpenseChats(policyID, invitedEmailsToAccountIDs, betas); @@ -367,6 +370,7 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs, welcomeNote, policyID, // Convert to object with each key containing {pendingAction: ‘add’} value: _.object(accountIDs, Array(accountIDs.length).fill({pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD})), }, + ...newPersonalDetailsOnyxData.optimisticData, ...membersChats.onyxOptimisticData, ]; @@ -379,6 +383,7 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs, welcomeNote, policyID, // need to remove the members since that will be handled by onClose of OfflineWithFeedback. value: _.object(accountIDs, Array(accountIDs.length).fill({pendingAction: null, errors: null})), }, + ...newPersonalDetailsOnyxData.successData, ...membersChats.onyxSuccessData, ]; @@ -396,10 +401,10 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs, welcomeNote, policyID, }), ), }, + ...newPersonalDetailsOnyxData.failureData, ...membersChats.onyxFailureData, ]; - const logins = _.map(_.keys(invitedEmailsToAccountIDs), (memberLogin) => OptionsListUtils.addSMSDomainIfPhoneNumber(memberLogin)); const params = { employees: JSON.stringify(_.map(logins, (login) => ({email: login}))),