Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HOLD] Revert "[TS migration] Migrate 'PersonalDetailsUtils.js' lib to TypeScript" #33438

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ type OnyxValues = {
[ONYXKEYS.NETWORK]: OnyxTypes.Network;
[ONYXKEYS.CUSTOM_STATUS_DRAFT]: OnyxTypes.CustomStatusDraft;
[ONYXKEYS.INPUT_FOCUSED]: boolean;
[ONYXKEYS.PERSONAL_DETAILS_LIST]: OnyxTypes.PersonalDetailsList;
[ONYXKEYS.PERSONAL_DETAILS_LIST]: Record<string, OnyxTypes.PersonalDetails>;
[ONYXKEYS.PRIVATE_PERSONAL_DETAILS]: OnyxTypes.PrivatePersonalDetails;
[ONYXKEYS.TASK]: OnyxTypes.Task;
[ONYXKEYS.CURRENCY_LIST]: Record<string, OnyxTypes.Currency>;
Expand Down
6 changes: 3 additions & 3 deletions src/components/ArchivedReportFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ function ArchivedReportFooter({report, reportClosedAction, personalDetails = {}}

const originalMessage = reportClosedAction?.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED ? reportClosedAction.originalMessage : null;
const archiveReason = originalMessage?.reason ?? CONST.REPORT.ARCHIVE_REASON.DEFAULT;
let displayName = PersonalDetailsUtils.getDisplayNameOrDefault(personalDetails?.[report?.ownerAccountID ?? 0]?.displayName);
let displayName = PersonalDetailsUtils.getDisplayNameOrDefault(personalDetails, [report.ownerAccountID, 'displayName']);

let oldDisplayName: string | undefined;
if (archiveReason === CONST.REPORT.ARCHIVE_REASON.ACCOUNT_MERGED) {
const newAccountID = originalMessage?.newAccountID;
const oldAccountID = originalMessage?.oldAccountID;
displayName = PersonalDetailsUtils.getDisplayNameOrDefault(personalDetails?.[newAccountID ?? 0]?.displayName);
oldDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(personalDetails?.[oldAccountID ?? 0]?.displayName);
displayName = PersonalDetailsUtils.getDisplayNameOrDefault(personalDetails, [newAccountID, 'displayName']);
oldDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(personalDetails, [oldAccountID, 'displayName']);
}

const shouldRenderHTML = archiveReason !== CONST.REPORT.ARCHIVE_REASON.DEFAULT;
Expand Down
2 changes: 1 addition & 1 deletion src/components/withCurrentUserPersonalDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function <TProps extends WithCurrentUserPersonalDetailsProps, TRe
const accountID = props.session?.accountID ?? 0;
const accountPersonalDetails = personalDetails?.[accountID];
const currentUserPersonalDetails: CurrentUserPersonalDetails = useMemo(
() => (accountPersonalDetails ? {...accountPersonalDetails, accountID} : {}) as CurrentUserPersonalDetails,
() => (accountPersonalDetails ? {...accountPersonalDetails, accountID} : {}),
[accountPersonalDetails, accountID],
);
return (
Expand Down
2 changes: 1 addition & 1 deletion src/libs/OptionsListUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ function createOption(accountIDs, personalDetails, report, reportActions = {}, {
(lastReportActions[report.reportID] && lastReportActions[report.reportID].originalMessage && lastReportActions[report.reportID].originalMessage.reason) ||
CONST.REPORT.ARCHIVE_REASON.DEFAULT;
lastMessageText = Localize.translate(preferredLocale, `reportArchiveReasons.${archiveReason}`, {
displayName: archiveReason.displayName || PersonalDetailsUtils.getDisplayNameOrDefault(lodashGet(lastActorDetails, 'displayName')),
displayName: archiveReason.displayName || PersonalDetailsUtils.getDisplayNameOrDefault(lastActorDetails, 'displayName'),
policyName: ReportUtils.getPolicyName(report),
});
}
Expand Down
222 changes: 222 additions & 0 deletions src/libs/PersonalDetailsUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
import lodashGet from 'lodash/get';
import Onyx from 'react-native-onyx';
import _ from 'underscore';
import ONYXKEYS from '@src/ONYXKEYS';
import * as LocalePhoneNumber from './LocalePhoneNumber';
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);
allPersonalDetails = val;
},
});

/**
* @param {Object | Null} passedPersonalDetails
* @param {Array | String} pathToDisplayName
* @param {String} [defaultValue] optional default display name value
* @returns {String}
*/
function getDisplayNameOrDefault(passedPersonalDetails, pathToDisplayName, defaultValue = '') {
const displayName = lodashGet(passedPersonalDetails, pathToDisplayName);

return displayName || defaultValue || Localize.translateLocal('common.hidden');
}

/**
* Given a list of account IDs (as number) it will return an array of personal details objects.
* @param {Array<number>} accountIDs - Array of accountIDs
* @param {Number} currentUserAccountID
* @param {Boolean} shouldChangeUserDisplayName - It will replace the current user's personal detail object's displayName with 'You'.
* @returns {Array} - Array of personal detail objects
*/
function getPersonalDetailsByIDs(accountIDs, currentUserAccountID, shouldChangeUserDisplayName = false) {
return _.chain(accountIDs)
.filter((accountID) => !!allPersonalDetails[accountID])
.map((accountID) => {
const detail = allPersonalDetails[accountID];

if (shouldChangeUserDisplayName && currentUserAccountID === detail.accountID) {
return {
...detail,
displayName: Localize.translateLocal('common.you'),
};
}

return detail;
})
.value();
}

/**
* Given a list of logins, find the associated personal detail and return related accountIDs.
*
* @param {Array<string>} logins Array of user logins
* @returns {Array} - Array of accountIDs according to passed logins
*/
function getAccountIDsByLogins(logins) {
return _.reduce(
logins,
(foundAccountIDs, login) => {
const currentDetail = _.find(personalDetails, (detail) => detail.login === login);
if (!currentDetail) {
// generate an account ID because in this case the detail is probably new, so we don't have a real accountID yet
foundAccountIDs.push(UserUtils.generateAccountID(login));
} else {
foundAccountIDs.push(Number(currentDetail.accountID));
}
return foundAccountIDs;
},
[],
);
}

/**
* Given a list of accountIDs, find the associated personal detail and return related logins.
*
* @param {Array<number>} accountIDs Array of user accountIDs
* @returns {Array<string>} - Array of logins according to passed accountIDs
*/
function getLoginsByAccountIDs(accountIDs) {
return _.reduce(
accountIDs,
(foundLogins, accountID) => {
const currentDetail = _.find(personalDetails, (detail) => Number(detail.accountID) === Number(accountID)) || {};
if (currentDetail.login) {
foundLogins.push(currentDetail.login);
}
return foundLogins;
},
[],
);
}

/**
* Given a list of logins and accountIDs, return Onyx data for users with no existing personal details stored
*
* @param {Array<string>} logins Array of user logins
* @param {Array<number>} 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: LocalePhoneNumber.formatPhoneNumber(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;
}
});

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,
},
],
};
}

/**
* Applies common formatting to each piece of an address
*
* @param {String} piece - address piece to format
* @returns {String} - formatted piece
*/
function formatPiece(piece) {
return piece ? `${piece}, ` : '';
}

/**
*
* @param {String} street1 - street line 1
* @param {String} street2 - street line 2
* @returns {String} formatted street
*/
function getFormattedStreet(street1 = '', street2 = '') {
return `${street1}\n${street2}`;
}

/**
*
* @param {*} street - formatted address
* @returns {[string, string]} [street1, street2]
*/
function getStreetLines(street = '') {
const streets = street.split('\n');
return [streets[0], streets[1]];
}

/**
* Formats an address object into an easily readable string
*
* @param {OnyxTypes.PrivatePersonalDetails} privatePersonalDetails - details object
* @returns {String} - formatted address
*/
function getFormattedAddress(privatePersonalDetails) {
const {address} = privatePersonalDetails;
const [street1, street2] = getStreetLines(address.street);
const formattedAddress = formatPiece(street1) + formatPiece(street2) + formatPiece(address.city) + formatPiece(address.state) + formatPiece(address.zip) + formatPiece(address.country);

// Remove the last comma of the address
return formattedAddress.trim().replace(/,$/, '');
}

/**
* @param {Object} personalDetail - details object
* @returns {String | undefined} - The effective display name
*/
function getEffectiveDisplayName(personalDetail) {
if (personalDetail) {
return LocalePhoneNumber.formatPhoneNumber(personalDetail.login) || personalDetail.displayName;
}

return undefined;
}

export {
getDisplayNameOrDefault,
getPersonalDetailsByIDs,
getAccountIDsByLogins,
getLoginsByAccountIDs,
getNewPersonalDetailsOnyxData,
getFormattedAddress,
getFormattedStreet,
getStreetLines,
getEffectiveDisplayName,
};
Loading
Loading