use derived values for report-specific transaction violations#67154
Conversation
992fb13 to
64c6b33
Compare
64c6b33 to
558409d
Compare
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2025-08-12.at.03.52.30.movAndroid: mWeb ChromeScreen.Recording.2025-08-12.at.03.44.40.moviOS: HybridAppScreen.Recording.2025-08-12.at.03.47.44.moviOS: mWeb SafariScreen.Recording.2025-08-12.at.03.45.33.movMacOS: Chrome / SafariScreen.Recording.2025-08-12.at.03.38.30.movMacOS: DesktopScreen.Recording.2025-08-12.at.03.47.00.mov |
src/components/MoneyReportHeader.tsx
Outdated
| const {transactions: reportTransactions, violations} = useTransactionsAndViolationsForReport(moneyRequestReport?.reportID); | ||
|
|
||
| const transactions = useMemo(() => { | ||
| return reportTransactionsSelector(reportTransactions, moneyRequestReport?.reportID); |
There was a problem hiding this comment.
Why do we need to use the reportTransactionsSelector here? It seems redundant, since reportTransactions from useTransactionsAndViolationsForReport is already filtered to include only the transactions relevant to the report.
There was a problem hiding this comment.
@truph01 yeah in this case we don't need additional filtering, we already have the correct values. However we need to get the array version of it, I added the necessary changes, please have another look
| const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {canBeMissing: true}); | ||
| const [transactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {canBeMissing: true}); | ||
| const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); | ||
| const {violations: transactionViolations} = useTransactionsAndViolationsForReport(reportID); |
There was a problem hiding this comment.
Let's consider the case where the report is a policy expense chat that contains a few transactions with violations:
The transactionViolations object is used here:
- Before our change:
shouldDisplayViolationsreturnstruebecausetransactionViolationsincludes data for all transactions, regardless of report ID. - After our change:
shouldDisplayViolationsreturnsfalsebecausetransactionViolationsis now scoped and becomes an empty object for this report.
We should ensure that the value of shouldDisplayViolations remains unchanged before and after the change. If it does change, it may indicate a regression.
There was a problem hiding this comment.
I agree, reverted this change
|
@zirgulis could you merge main and check my two comments above? |
|
@truph01 yes will do that on Friday since I'm currently OOO. Will ping you. |
…to perf/report-transactions-derived-value-all-instances
|
@zirgulis is this ready for another review and testing? |
| const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: false}); | ||
| const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true}); | ||
| const [transactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {canBeMissing: true}); | ||
| const {transactions} = useTransactionsAndViolationsForReport(report.reportID); |
There was a problem hiding this comment.
@zirgulis If the report is a self DM, the transactions object will be {}. As a result, the transaction at this line:
will be
undefined when the action is a track expense. This is a regression, because on the latest main branch, the transaction data is not undefined in the same scenario.
…to perf/report-transactions-derived-value-all-instances
|
@truph01 ready again |
@truph01 can you specify which cases? |
|
@truph01 for your interest, please leave full testing and reviews on PRs https://expensify.slack.com/archives/C02NK2DQWUX/p1752590021746689 |
@zirgulis Here are the reproduction steps to demonstrate the issue:
Behavior differences:
What I’m pointing out is that there may be additional edge cases—similar to the if we're confident that it correctly handles all possible cases. Otherwise, I recommend sticking with the current approach of subscribing to all transaction data. The key priority is ensuring the logic is reliable before we focus on performance improvements. |
…to perf/report-transactions-derived-value-all-instances
|
@truph01 I had chat with @TMisiukiewicz regarding the derived values and we agreed that covering all the edge cases for |
…to perf/report-transactions-derived-value-all-instances
|
Thanks @zirgulis! Could you address the failed just unit tests? |
|
@truph01 CI checks are 🟢 |
|
I will finish checklist soon |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/mountiny in version: 9.1.94-0 🚀
|
|
🚀 Deployed to production by https://github.com/marcaaron in version: 9.1.94-4 🚀
|
Explanation of Change
This PR optimizes performance by replacing direct Onyx collection queries for transaction violations with the existing
useTransactionsAndViolationsForReportderived value hook in two components:MoneyReportHeader: Previously fetched all transaction violations and manually filtered them for the specific report. Now uses the hook's violations directly, eliminating unnecessary data fetching and filtering logic.
DebugReportPage: Previously fetched all transaction violations for debugging purposes. Now uses report-specific violations since it has access to a specific
reportID.The changes maintain identical user-facing behavior while improving performance by leveraging the existing derived value system that was introduced in PR #65247.
Fixed Issues
$ #67166
Tests
Offline tests
QA Steps
Same as above
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssection(e.g. long loading states that impact usability).
canBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translationmethod
and it was approved by an internal Expensify engineer. Link to Slack message:
methods
coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
for the platform the code supports as outlined in the README.
STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))and italic.
Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Screen.Recording.2025-07-25.at.16.28.11.mov
Android: mWeb Chrome
iOS: Native
Screen.Recording.2025-07-25.at.16.23.16.mov
iOS: mWeb Safari
MacOS: Chrome / Safari
Screen.Recording.2025-07-25.at.16.34.55.mov
MacOS: Desktop