Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9f35346
avoid userBillingFundID prop drilling
LukasMod May 6, 2026
0927cac
avoid isTryNewDotNVPDismissed nad personalDetails prop drilling
LukasMod May 6, 2026
066fe9b
add actionReport and actionReportID calc in ActionContentRouter
LukasMod May 12, 2026
05d256a
clean up, reuse const and isHarvestCreatedExpenseReport
LukasMod May 12, 2026
ae146ba
pass only id instead of report to getReimbursedMessage
LukasMod May 12, 2026
7d8bc16
remove report prop from SimpleMessageContent
LukasMod May 12, 2026
d7bbd31
Merge branch 'perf/decompose-and-context-menu-anchor-ref' of github.c…
LukasMod May 18, 2026
1f274d2
Merge branch 'perf/decompose-and-context-menu-anchor-ref' of github.c…
LukasMod May 19, 2026
0d50771
Merge branch 'perf/decompose-and-context-menu-anchor-ref' of github.c…
LukasMod May 20, 2026
06457c0
Merge branch 'main' of github.com:Expensify/App into perf/leaf-level-…
LukasMod May 20, 2026
4a1637b
remove isOffline change
LukasMod May 20, 2026
f3892bc
prettier fix
LukasMod May 20, 2026
febb20f
clean up displayName based on current guideline
LukasMod May 20, 2026
2a3af7d
Revert personalDetails leaf subscription from ReimbursementQueuedContent
LukasMod May 20, 2026
f438dd0
rename actionReport to actionOwnerReport
LukasMod May 20, 2026
b17c66f
fix unit tests
LukasMod May 20, 2026
f33d705
clean up ChatMessageContent
LukasMod May 20, 2026
5c74fb2
add unit test for ChatActionableButtons
LukasMod May 20, 2026
7822f9c
prettier fix
LukasMod May 20, 2026
80a7e30
fix PureReportActionItem test
LukasMod May 20, 2026
c9fdcd4
fix selector perf issue with ReceiptScanFailedContent
LukasMod May 21, 2026
121d01a
refactor to not use deprecated wasActionTakenByCurrentUser
LukasMod May 21, 2026
5db1919
Merge branch 'main' of github.com:Expensify/App into perf/leaf-level-…
LukasMod May 22, 2026
1822fbe
fix ts
LukasMod May 22, 2026
7eb6ca5
fix unit tests set up
LukasMod May 22, 2026
6b1ddb0
Merge branch 'main' of github.com:Expensify/App into perf/leaf-level-…
LukasMod May 25, 2026
22421f7
fix type IOU
LukasMod May 25, 2026
61707c4
fix type IOU
LukasMod May 25, 2026
f845447
fix ts after revert
LukasMod May 25, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,7 @@ function MoneyRequestReportActionsList({onLayout}: MoneyRequestReportListProps)

const parentReportAction = useParentReportAction(report);

const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID);
const personalDetails = usePersonalDetails();
const [tryNewDot] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT);
const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed;
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
const [betas] = useOnyx(ONYXKEYS.BETAS);

Expand Down Expand Up @@ -568,11 +565,7 @@ function MoneyRequestReportActionsList({onLayout}: MoneyRequestReportListProps)
shouldHideThreadDividerLine
linkedReportActionID={linkedReportActionID}
personalDetails={personalDetails}
userBillingFundID={userBillingFundID}
isReportArchived={isReportArchived}
isTryNewDotNVPDismissed={isTryNewDotNVPDismissed}
Comment thread
LukasMod marked this conversation as resolved.
reportNameValuePairsOrigin={reportNameValuePairs?.origin}
reportNameValuePairsOriginalID={reportNameValuePairs?.originalID}
isHarvestCreatedExpenseReport={shouldShowHarvestCreatedAction}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why is isHarvestCreatedExpenseReport computed at the list level instead of inside the child?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We can skip drilling reportNameValuePairs?.origin and reportNameValuePairs?.originalID and avoid calculating the same thing repeatedly in each item with single bool prop. It is also used for shouldShowCreatedAction, so all items need to have this information anyway. There is no nested "leaf" where we could place reportNameValuePairs, subscribe directly

/>
);
},
Expand All @@ -586,11 +579,7 @@ function MoneyRequestReportActionsList({onLayout}: MoneyRequestReportListProps)
firstVisibleReportActionID,
linkedReportActionID,
personalDetails,
userBillingFundID,
isTryNewDotNVPDismissed,
isReportArchived,
reportNameValuePairs?.origin,
reportNameValuePairs?.originalID,
shouldShowHarvestCreatedAction,
],
);

Expand Down
11 changes: 6 additions & 5 deletions src/components/ReportActionItem/CreateHarvestReportAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ import ReportActionItemBasicMessage from '@pages/inbox/report/ReportActionItemBa
import ONYXKEYS from '@src/ONYXKEYS';

type CreateHarvestReportActionProps = {
/** The original ID of the report */
reportNameValuePairsOriginalID: string | undefined;
/** ID of the chat report the harvest "Created" action belongs to */
reportID: string | undefined;
};

function CreateHarvestReportAction({reportNameValuePairsOriginalID}: CreateHarvestReportActionProps) {
function CreateHarvestReportAction({reportID}: CreateHarvestReportActionProps) {
const {translate} = useLocalize();
const [harvestReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportNameValuePairsOriginalID}`);
const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportID}`);
const [harvestReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportNameValuePairs?.originalID}`);
const harvestReportName = getReportName(harvestReport);
const htmlContent = `<comment><muted-text>${getHarvestCreatedExpenseReportMessage(reportNameValuePairsOriginalID, harvestReportName, translate)}</muted-text></comment>`;
const htmlContent = `<comment><muted-text>${getHarvestCreatedExpenseReportMessage(reportNameValuePairs?.originalID, harvestReportName, translate)}</muted-text></comment>`;

return (
<ReportActionItemBasicMessage>
Expand Down
2 changes: 0 additions & 2 deletions src/components/Search/SearchList/ListItem/ChatListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ function ChatListItem<TItem extends ListItem>({
const reportActionItem = item as unknown as ReportActionListItemType;
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportActionItem?.reportID}`);
const personalDetails = usePersonalDetails();
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID);
const styles = useThemeStyles();
const theme = useTheme();
const animatedHighlightStyle = useAnimatedHighlightStyle({
Expand Down Expand Up @@ -86,7 +85,6 @@ function ChatListItem<TItem extends ListItem>({
shouldDisplayContextMenu={false}
shouldShowBorder
personalDetails={personalDetails}
userBillingFundID={userBillingFundID}
/>
</BaseListItem>
);
Expand Down
4 changes: 2 additions & 2 deletions src/libs/OptionsListUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -774,15 +774,15 @@ function getLastMessageTextForReport({
} else if (isReimbursementQueuedAction(lastReportAction)) {
lastMessageTextFromReport = getReimbursementQueuedActionMessage({reportAction: lastReportAction, translate, formatPhoneNumber: formatPhoneNumberPhoneUtils, report});
} else if (isReimbursementDeQueuedOrCanceledAction(lastReportAction)) {
lastMessageTextFromReport = getReimbursementDeQueuedOrCanceledActionMessage(translate, lastReportAction, report);
lastMessageTextFromReport = getReimbursementDeQueuedOrCanceledActionMessage(translate, lastReportAction, report?.ownerAccountID);
} else if (isDeletedParentAction(lastReportAction) && reportUtilsIsChatReport(report)) {
lastMessageTextFromReport = getDeletedParentActionMessageForChatReport(lastReportAction);
} else if (isPendingRemove(lastReportAction) && report?.reportID && isThreadParentMessage(lastReportAction, report.reportID)) {
lastMessageTextFromReport = translate('parentReportAction.hiddenMessage');
} else if (isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED)) {
lastMessageTextFromReport = getMarkedReimbursedMessage(translate, lastReportAction);
} else if (isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.REIMBURSED)) {
lastMessageTextFromReport = getReimbursedMessage(translate, lastReportAction, report);
lastMessageTextFromReport = getReimbursedMessage(translate, lastReportAction, report?.ownerAccountID);
} else if (isReportMessageAttachment({text: report?.lastMessageText ?? '', html: report?.lastMessageHtml, type: ''})) {
lastMessageTextFromReport = `[${translate('common.attachment')}]`;
} else if (isModifiedExpenseAction(lastReportAction)) {
Expand Down
4 changes: 2 additions & 2 deletions src/libs/ReportActionsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ function getMarkedReimbursedMessage(translate: LocalizedTranslate, reportAction:
return translate('iou.paidElsewhere', {comment: originalMessage?.message?.trim()});
}

function getReimbursedMessage(translate: LocalizedTranslate, reportAction: OnyxInputOrEntry<ReportAction>, report: OnyxEntry<Report>, currentUserAccountID?: number): string {
function getReimbursedMessage(translate: LocalizedTranslate, reportAction: OnyxInputOrEntry<ReportAction>, reportOwnerAccountID: number | undefined, currentUserAccountID?: number): string {
const effectiveCurrentUserAccountID = currentUserAccountID ?? deprecatedCurrentUserAccountID ?? CONST.DEFAULT_NUMBER_ID;
const originalMessage = getOriginalMessage(reportAction) as OriginalMessageReimbursed | undefined;

Expand Down Expand Up @@ -492,7 +492,7 @@ function getReimbursedMessage(translate: LocalizedTranslate, reportAction: OnyxI
const {debitBankAccountLast4, creditBankAccountLast4, expectedDate, isInvoiceOrBill, isSubmitterAddingBankAccount, stripePaymentType} = originalMessage;

// Resolve submitter from report owner
const submitterAccountID = report?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID;
const submitterAccountID = reportOwnerAccountID ?? CONST.DEFAULT_NUMBER_ID;
const submitterLogin = getPersonalDetailsByIDs({accountIDs: [submitterAccountID], currentUserAccountID: effectiveCurrentUserAccountID}).at(0)?.login ?? '';
const isCurrentUser = submitterAccountID === effectiveCurrentUserAccountID;

Expand Down
2 changes: 1 addition & 1 deletion src/libs/ReportNameUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ function computeReportNameBasedOnReportAction(
}

if (isReimbursementDeQueuedOrCanceledAction(parentReportAction)) {
return getReimbursementDeQueuedOrCanceledActionMessage(translate, parentReportAction, parentReport);
return getReimbursementDeQueuedOrCanceledActionMessage(translate, parentReportAction, parentReport?.ownerAccountID);
}
if (isRejectedAction(parentReportAction)) {
return translate('iou.rejectedThisReport');
Expand Down
4 changes: 2 additions & 2 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3991,7 +3991,7 @@ function getReimbursementQueuedActionMessage({
function getReimbursementDeQueuedOrCanceledActionMessage(
translate: LocalizedTranslate,
reportAction: OnyxEntry<ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_DEQUEUED | typeof CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_ACH_CANCELED>>,
report: OnyxEntry<Report>,
reportOwnerAccountID: number | undefined,
): string {
const originalMessage = getOriginalMessage(reportAction);
const amount = originalMessage?.amount;
Expand All @@ -4000,7 +4000,7 @@ function getReimbursementDeQueuedOrCanceledActionMessage(
if (originalMessage?.cancellationReason === CONST.REPORT.CANCEL_PAYMENT_REASONS.ADMIN || originalMessage?.cancellationReason === CONST.REPORT.CANCEL_PAYMENT_REASONS.USER) {
return translate('iou.adminCanceledRequest');
}
const submitterDisplayName = getDisplayNameForParticipant({accountID: report?.ownerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils}) ?? '';
const submitterDisplayName = getDisplayNameForParticipant({accountID: reportOwnerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils}) ?? '';
return translate('iou.canceledRequest', formattedAmount, submitterDisplayName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ function DebugReportActionCreatePage({
const [session] = useOnyx(ONYXKEYS.SESSION);
const [personalDetailsList] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST);
const [draftReportAction, setDraftReportAction] = useState<string>(() => getInitialReportAction(reportID, session, personalDetailsList));
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID);
const [tryNewDot] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT);
const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed;

const [error, setError] = useState<string>();

Expand Down Expand Up @@ -119,8 +116,6 @@ function DebugReportActionCreatePage({
isFirstVisibleReportAction={false}
shouldDisplayContextMenu={false}
personalDetails={personalDetailsList}
userBillingFundID={userBillingFundID}
isTryNewDotNVPDismissed={isTryNewDotNVPDismissed}
/>
) : (
<Text>{translate('debug.nothingToPreview')}</Text>
Expand Down
5 changes: 0 additions & 5 deletions src/pages/Debug/ReportAction/DebugReportActionPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ type DebugReportActionPreviewProps = {

function DebugReportActionPreview({reportAction, reportID}: DebugReportActionPreviewProps) {
const personalDetails = usePersonalDetails();
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID);
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
const [tryNewDot] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT);
const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed;

return (
<ScrollView>
Expand All @@ -34,8 +31,6 @@ function DebugReportActionPreview({reportAction, reportID}: DebugReportActionPre
isFirstVisibleReportAction={false}
shouldDisplayContextMenu={false}
personalDetails={personalDetails}
userBillingFundID={userBillingFundID}
isTryNewDotNVPDismissed={isTryNewDotNVPDismissed}
/>
</ScrollView>
);
Expand Down
5 changes: 0 additions & 5 deletions src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@ function DuplicateTransactionItem({transaction, index, onPreviewPressed}: Duplic
const styles = useThemeStyles();
const personalDetails = usePersonalDetails();

const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID);
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`);
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`);
const [tryNewDot] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT);
const isTryNewDotNVPDismissed = !!tryNewDot?.classicRedirect?.dismissed;

const action = Object.values(reportActions ?? {})?.find((reportAction) => {
const IOUTransactionID = isMoneyRequestAction(reportAction) ? getOriginalMessage(reportAction)?.IOUTransactionID : CONST.DEFAULT_NUMBER_ID;
Expand Down Expand Up @@ -73,8 +70,6 @@ function DuplicateTransactionItem({transaction, index, onPreviewPressed}: Duplic
personalDetails={personalDetails}
draftMessage={matchingDraftMessage}
linkedTransactionRouteError={linkedTransactionRouteError}
userBillingFundID={userBillingFundID}
isTryNewDotNVPDismissed={isTryNewDotNVPDismissed}
/>
</ReportActionItemActionsContext.Provider>
</ReportActionItemStateContext.Provider>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ const ContextMenuActions: ContextMenuAction[] = [
const modifyExpenseMessage = Parser.htmlToMarkdown(modifyExpenseMessageWithHTML);
Clipboard.setString(modifyExpenseMessage);
} else if (isReimbursementDeQueuedOrCanceledAction(reportAction)) {
const displayMessage = getReimbursementDeQueuedOrCanceledActionMessage(translate, reportAction, report);
const displayMessage = getReimbursementDeQueuedOrCanceledActionMessage(translate, reportAction, report?.ownerAccountID);
Clipboard.setString(displayMessage);
} else if (isMoneyRequestAction(reportAction)) {
const displayMessage = getIOUReportActionDisplayMessage(translate, reportAction, transaction, report, bankAccountList);
Expand Down Expand Up @@ -1003,7 +1003,7 @@ const ContextMenuActions: ContextMenuAction[] = [
} else if (isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED)) {
Clipboard.setString(getMarkedReimbursedMessage(translate, reportAction));
} else if (isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.REIMBURSED)) {
Clipboard.setString(getReimbursedMessage(translate, reportAction, report, currentUserPersonalDetails.accountID));
Clipboard.setString(getReimbursedMessage(translate, reportAction, report?.ownerAccountID, currentUserPersonalDetails.accountID));
} else if (isReimbursementQueuedAction(reportAction)) {
Clipboard.setString(
getReimbursementQueuedActionMessage({reportAction, translate, formatPhoneNumber: formatPhoneNumberPhoneUtils, report, shouldUseShortDisplayName: false}),
Expand Down
Loading
Loading