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

[TS migration] Migrate 'PersonalDetailsUtils.js' lib to TypeScript #30169

Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
894f232
[TS migration] Migrate 'PersonalDetailsUtils.js' lib to TypeScript
BartoszGrajdek Sep 21, 2023
9510a4e
Migrate personal details utils to TS
BartoszGrajdek Sep 26, 2023
12832ed
Merge changes
BartoszGrajdek Oct 23, 2023
1caa40d
Rename personal details
BartoszGrajdek Oct 23, 2023
ed764e4
[TS migration] Migrate 'PersonalDetailsUtils.js' lib to TypeScript
BartoszGrajdek Oct 23, 2023
209f33c
Tweak getDisplayNameOrDefault usages
BartoszGrajdek Oct 23, 2023
9e97b7e
Resolve merge conflicts & fixes
BartoszGrajdek Oct 24, 2023
7d00e4b
Fix: review of personalDetailsUtils.ts
BartoszGrajdek Oct 26, 2023
729e718
Resolve merge conflicts
BartoszGrajdek Oct 30, 2023
ada39cf
Fix typecheck errors PersonalDetailsUtils
BartoszGrajdek Oct 30, 2023
d0f7046
Resolve merge conflicts
BartoszGrajdek Nov 15, 2023
5e717fe
fix: typecheck errors
BartoszGrajdek Nov 15, 2023
c0ef729
fix: resolve merge conflicts
BartoszGrajdek Nov 23, 2023
9ddcc2f
fix: lint
BartoszGrajdek Nov 23, 2023
0309f32
Resolve merge conflicts
BartoszGrajdek Dec 3, 2023
df26c75
fix: merge conflicts
BartoszGrajdek Dec 7, 2023
1e4eaaf
fix: handle PersonalDetailsUtils.getDisplayNameOrDefault properly
BartoszGrajdek Dec 7, 2023
e98aece
Merge main
BartoszGrajdek Dec 15, 2023
866ef5c
change default value for owner account
BartoszGrajdek Dec 15, 2023
d63f975
Resolve merge conflict
BartoszGrajdek Dec 15, 2023
65dda0d
Fix: typecheck
BartoszGrajdek Dec 18, 2023
24f5eb2
Merge remote-tracking branch 'origin/main' into ts-migration/personal…
BartoszGrajdek Dec 18, 2023
40d8204
fix: types in util files
BartoszGrajdek Dec 18, 2023
d2dfec6
fix: unit test
BartoszGrajdek Dec 18, 2023
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
6 changes: 3 additions & 3 deletions src/components/ArchivedReportFooter.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ const defaultProps = {

function ArchivedReportFooter(props) {
const archiveReason = lodashGet(props.reportClosedAction, 'originalMessage.reason', CONST.REPORT.ARCHIVE_REASON.DEFAULT);
let displayName = PersonalDetailsUtils.getDisplayNameOrDefault(props.personalDetails, [props.report.ownerAccountID, 'displayName']);
let displayName = PersonalDetailsUtils.getDisplayNameOrDefault(lodashGet(props.personalDetails, [props.report.ownerAccountID, 'displayName']));

let oldDisplayName;
if (archiveReason === CONST.REPORT.ARCHIVE_REASON.ACCOUNT_MERGED) {
const newAccountID = props.reportClosedAction.originalMessage.newAccountID;
const oldAccountID = props.reportClosedAction.originalMessage.oldAccountID;
displayName = PersonalDetailsUtils.getDisplayNameOrDefault(props.personalDetails, [newAccountID, 'displayName']);
oldDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(props.personalDetails, [oldAccountID, 'displayName']);
displayName = PersonalDetailsUtils.getDisplayNameOrDefault(lodashGet(props.personalDetails, [newAccountID, 'displayName']));
oldDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(lodashGet(props.personalDetails, [oldAccountID, 'displayName']));
}

const shouldRenderHTML = archiveReason !== CONST.REPORT.ARCHIVE_REASON.DEFAULT;
Expand Down
2 changes: 1 addition & 1 deletion src/libs/OptionsListUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,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(lastActorDetails, 'displayName'),
displayName: archiveReason.displayName || PersonalDetailsUtils.getDisplayNameOrDefault(lodashGet(lastActorDetails, 'displayName')),
policyName: ReportUtils.getPolicyName(report),
});
}
Expand Down
180 changes: 0 additions & 180 deletions src/libs/PersonalDetailsUtils.js

This file was deleted.

170 changes: 170 additions & 0 deletions src/libs/PersonalDetailsUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import Onyx, {OnyxEntry} from 'react-native-onyx';
import ONYXKEYS from '../ONYXKEYS';
import * as Localize from './Localize';
import * as UserUtils from './UserUtils';
import * as LocalePhoneNumber from './LocalePhoneNumber';
import * as OnyxTypes from '../types/onyx';

type PersonalDetailsList = Record<string, OnyxTypes.PersonalDetails | null>;
BartoszGrajdek marked this conversation as resolved.
Show resolved Hide resolved

let personalDetails: OnyxTypes.PersonalDetails[] = [];
let allPersonalDetails: OnyxEntry<Record<string, OnyxTypes.PersonalDetails>> = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let allPersonalDetails: OnyxEntry<Record<string, OnyxTypes.PersonalDetails>> = {};
let allPersonalDetails: OnyxEntry<PersonalDetailsList> = {};

Onyx.connect({
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (val) => {
personalDetails = Object.values(val ?? {});
allPersonalDetails = val;
},
});

/**
* @param [defaultValue] optional default display name value
*/
function getDisplayNameOrDefault(displayName: string, defaultValue?: string): string {
return displayName ?? defaultValue ?? Localize.translateLocal('common.hidden');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you test this function to ever actually fall back to Localize.translateLocal('common.hidden')?

?? only checks for undefined and null, so '' ?? will always be true.
Therefore, since you pass defaultValue = '', the defaultValue ?? check will always be true, and we'll return the defaultValue even if it's empty, won't we?

}

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

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

return detail;
});

return result;
}

/**
* Given a list of logins, find the associated personal detail and return related accountIDs.
*
* @param logins Array of user logins
* @returns Array of accountIDs according to passed logins
*/
function getAccountIDsByLogins(logins: string[]): number[] {
return logins.reduce((foundAccountIDs: number[], login) => {
BartoszGrajdek marked this conversation as resolved.
Show resolved Hide resolved
const currentDetail = personalDetails.find((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 accountIDs Array of user accountIDs
* @returns Array of logins according to passed accountIDs
*/
function getLoginsByAccountIDs(accountIDs: number[]): string[] {
return accountIDs.reduce((foundLogins: string[], accountID) => {
const currentDetail: Partial<OnyxTypes.PersonalDetails> = personalDetails.find((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 logins Array of user logins
* @param accountIDs Array of user accountIDs
* @returns Object with optimisticData, successData and failureData (object of personal details objects)
*/
function getNewPersonalDetailsOnyxData(logins: string[], accountIDs: number[]) {
const optimisticData: PersonalDetailsList = {};
const successData: PersonalDetailsList = {};
const failureData: PersonalDetailsList = {};

logins.forEach((login, index) => {
const accountID = accountIDs[index];

if (allPersonalDetails && Object.keys(allPersonalDetails[accountID]).length === 0) {
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 piece - address piece to format
* @returns - formatted piece
*/
function formatPiece(piece?: string): string {
return piece ? `${piece}, ` : '';
}

/**
* Formats an address object into an easily readable string
*
* @param privatePersonalDetails - details object
* @returns - formatted address
*/
function getFormattedAddress(privatePersonalDetails: OnyxTypes.PrivatePersonalDetails): string {
const {address} = privatePersonalDetails;
const [street1, street2] = (address?.street ?? '').split('\n');
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(/,$/, '');
}

export {getDisplayNameOrDefault, getPersonalDetailsByIDs, getAccountIDsByLogins, getLoginsByAccountIDs, getNewPersonalDetailsOnyxData, getFormattedAddress};
2 changes: 1 addition & 1 deletion src/libs/SidebarUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ function getOptionData(report, reportActions, personalDetails, preferredLocale,
(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(lastActorDetails, 'displayName'),
displayName: archiveReason.displayName || PersonalDetailsUtils.getDisplayNameOrDefault(lodashGet(lastActorDetails, 'displayName')),
policyName: ReportUtils.getPolicyName(report, false, policy),
});
}
Expand Down
5 changes: 4 additions & 1 deletion src/pages/home/report/ReportActionItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,10 @@ function ReportActionItem(props) {
/>
);
} else if (props.action.actionName === CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENTQUEUED) {
const submitterDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(props.personalDetailsList, [props.report.ownerAccountID, 'displayName'], props.report.ownerEmail);
const submitterDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(
lodashGet(props.personalDetailsList, [props.report.ownerAccountID, 'displayName']),
props.report.ownerEmail,
);
const paymentType = lodashGet(props.action, 'originalMessage.paymentType', '');

const isSubmitterOfUnsettledReport = ReportUtils.isCurrentUserSubmitter(props.report.reportID) && !ReportUtils.isSettled(props.report.reportID);
Expand Down
Loading