-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Subscribe transactions in report preview #32469
Conversation
@hoangzinh Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
const unsubscribeOnyxTransaction = onyxSubscribe({ | ||
key: ONYXKEYS.COLLECTION.TRANSACTION, | ||
waitForCollectionCallback: true, | ||
callback: (transactionAgrs) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we just call ReportUtils.hasMissingSmartscanFields
to update hasErrors
state when there is a change from ONYXKEYS.COLLECTION.TRANSACTION
? Therefore, each ReportPreview component doesn't need to carry all transaction data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hoangzinh How can we not carry all transaction data? Because ReportPreview
has many transactions
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our purpose of subscribe to Onyx change is if there is any update related to ONYXKEYS.COLLECTION.TRANSACTION
we will check again ReportUtils.hasMissingSmartscanFields
, won't we? So I have an idea something like this:
const [isError, setIsError] = useState(false);
const hasErrors = hasReceipts && isError;
useEffect(() => {
onyxSubscribe({
key: ONYXKEYS.COLLECTION.TRANSACTION,
....
callback: () => {
setIsError(ReportUtils.hasMissingSmartscanFields(props.iouReportID));
}
}
})
Therefore, we don't need to load all transactions for each ReportPreview component. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Therefore, we don't need to load all transactions for each ReportPreview component. What do you think?
I know that but I can't find a way to only subscribe the necessary transaction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't really need @dukenv0307. We subscribe to all keys change ONYXKEYS.COLLECTION.TRANSACTION
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hoangzinh Actually hasOnlyDistanceRequestTransactions
, areAllRequestsBeingSmartScanned
and hasMissingSmartscanFields
functions are getting all transactions of ReportPreview
in these functions, so when we subscribe transactions in ReportPreview
, we can get all transactions with iouReportID
and pass this to these function. That can make sure other functions will not have the same bug and we don't need to getAllReportTransactions
again in these functions if we already pass transactions
param.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks better than previous one. Btw, have you tested all the places that are using modified methods in this PR? We have some regression bugs recently because missing params or incorrect params
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hoangzinh I added default value for transactions param so other places which use this function will call getAllTransaction function to get data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we go this way, why don't we do something like my suggestion here? https://github.com/Expensify/App/pull/32469/files#r1417094685 (both your current implementation and this suggestion are based on the assumption that transactions in TransactionUtils.getAllReportTransactions
is up-to-date
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hoangzinh Updated.
return; | ||
} | ||
|
||
const allTransaction = _.filter(transactionAgrs, (transaction) => `${transaction.reportID}` === `${props.iouReportID}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking that is there any way that we can use share logic with the existing function here
App/src/libs/TransactionUtils.ts
Lines 450 to 456 in a16df0d
function getAllReportTransactions(reportID?: string): Transaction[] { | |
// `reportID` from the `/CreateDistanceRequest` endpoint return's number instead of string for created `transaction`. | |
// For reference, https://github.com/Expensify/App/pull/26536#issuecomment-1703573277. | |
// We will update this in a follow-up Issue. According to this comment: https://github.com/Expensify/App/pull/26536#issuecomment-1703591019. | |
const transactions: Transaction[] = Object.values(allTransactions ?? {}).filter((transaction): transaction is Transaction => transaction !== null); | |
return transactions.filter((transaction) => `${transaction.reportID}` === `${reportID}`); | |
} |
It covers the null case of transaction and centralizes the logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hoangzinh Updated.
return; | ||
} | ||
|
||
const allTransactions = TransactionUtils.getAllReportTransactions(props.iouReportID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the transactions
cached in TransactionUtils
is not updated yet? I think we will get outdated transaction data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hoangzinh When we subscribe transactions here, the transactions
in TransactionUtils
will not be outdated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both component and util TransactionUtils are subscribed to transactions, we can't control which place is updated first or same time. How can you ensure "the transactions in TransactionUtils will not be outdated."?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hoangzinh You can try to only subscribe transactions from Onyx in ReportPreview
and do nothing. You can see that the issue is resolved.
src/libs/ReportUtils.ts
Outdated
@@ -938,8 +938,8 @@ function hasSingleParticipant(report: OnyxEntry<Report>): boolean { | |||
* | |||
*/ | |||
function hasOnlyDistanceRequestTransactions(iouReportID: string | undefined): boolean { | |||
const transactions = TransactionUtils.getAllReportTransactions(iouReportID); | |||
return transactions.every((transaction) => TransactionUtils.isDistanceRequest(transaction)); | |||
const allTransactionsOfPreview = TransactionUtils.getAllReportTransactions(iouReportID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we revert those changes @dukenv0307 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hoangzinh Yes, reverted.
Reviewer Checklist
Screenshots/VideosAndroid: NativeScreen.Recording.2023-12-20.at.23.06.51.android.mp4Android: mWeb ChromeScreen.Recording.2023-12-20.at.22.56.03.android.chrome.moviOS: NativeScreen.Recording.2023-12-20.at.22.58.53.-.ios.mp4iOS: mWeb SafariScreen.Recording.2023-12-20.at.22.58.01.-.ios.safari.movMacOS: Chrome / SafariScreen.Recording.2023-12-20.at.22.45.35.-.web.movMacOS: DesktopScreen.Recording.2023-12-20.at.22.49.32.-.desktop.mov |
key: ONYXKEYS.COLLECTION.TRANSACTION, | ||
waitForCollectionCallback: true, | ||
callback: (transactionAgrs) => { | ||
if (_.isEmpty(transactionAgrs)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is transactionAgrs
? Can we use a more descriptive name here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also add a comment explaining why this can be empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is transactionAgrs? Can we use a more descriptive name here?
Updated.
Let's also add a comment explaining why this can be empty
Not sure why but in other places which use onyxSubscribe
also have this check and I tried to remove this check, it makes perf fail as the ReportScreen
re-render many times
🚀 Deployed to production by https://github.com/mountiny in version: 1.4.16-5 🚀
|
Details
Subscribe transactions from Onyx in report preview by using
onyxSubscribe
Fixed Issues
$ #32256
PROPOSAL: #32256 (comment)
Tests
Offline tests
Pre-condition: Do the step 1-4 in online mode
Do the step 5 - 10 same as above
QA Steps
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodWaiting for Copy
label for a copy review on the original GH to get the correct copy.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
Screen.Recording.2023-12-05.at.13.03.38.mov
Android: mWeb Chrome
Screen.Recording.2023-12-05.at.12.40.07.mov
iOS: Native
Screen.Recording.2023-12-05.at.12.44.53.mov
iOS: mWeb Safari
Screen.Recording.2023-12-05.at.12.24.48.mov
MacOS: Chrome / Safari
Screen.Recording.2023-12-05.at.12.16.25.mov
MacOS: Desktop
Screen.Recording.2023-12-05.at.13.08.33.mov