Support one transaction thread report creation if it wasn't created optimistically#68290
Conversation
|
@hungvu193 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] |
|
I'll review today! |
|
I'm still testing, will let you know if I find any issues |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppandroid.movAndroid: mWeb ChromeScreen.Recording.2025-08-13.at.23.41.18.moviOS: HybridAppScreen.Recording.2025-08-13.at.23.37.00.moviOS: mWeb SafariScreen.Recording.2025-08-13.at.22.46.04.movScreen.Recording.2025-08-13.at.22.46.04.movMacOS: Chrome / SafariScreen.Recording.2025-08-13.at.22.37.25.movScreen.Recording.2025-08-13.at.22.39.14.movMacOS: DesktopScreen.Recording.2025-08-13.at.22.40.54.mov |
|
@roryabraham can you check this one please? Also, I'm going to be OOO tomorrow! |
roryabraham
left a comment
There was a problem hiding this comment.
Please add automated tests covering the actions you updated
src/libs/actions/IOU.ts
Outdated
| onyxMethod: Onyx.METHOD.MERGE, | ||
| key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, | ||
| value: { | ||
| ...report, |
There was a problem hiding this comment.
Why spread the report here? Onyx.merge should be able to update pendingFields without needing to modify the whole report. In the case where it's just created optimistically, we should probably use Onyx.set as it's more idiomatic for a plain insert.
There was a problem hiding this comment.
@VickyStash you're still doing an avoidable shallow copy here:
diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts
index 3ff022a5f49..b80bd2c02f1 100644
--- a/src/libs/actions/IOU.ts
+++ b/src/libs/actions/IOU.ts
@@ -10934,6 +10934,8 @@ function putOnHold(transactionID: string, comment: string, initialReportID: stri
const moneyRequestReport = getReportOrDraftReport(transaction?.reportID);
report = buildTransactionThread(iouAction, moneyRequestReport, undefined, reportID);
}
+ // at this point, report should be defined, cast it as such
+ report ??= {} as OnyxTypes.Report;
const optimisticCreatedAction = buildOptimisticCreatedReportAction(currentUserEmail);
const parentReportActionOptimistic = getOptimisticDataForParentReportAction(report, createdReportActionComment.created, CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
@@ -11026,23 +11028,21 @@ function putOnHold(transactionID: string, comment: string, initialReportID: stri
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
- lastVisibleActionCreated: report?.lastVisibleActionCreated,
+ lastVisibleActionCreated: report.lastVisibleActionCreated,
},
},
];
// If the transaction thread report wasn't created before, we create it optimistically
if (!initialReportID) {
+ report.pendingFields = {
+ createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
+ };
optimisticData.push(
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
- value: {
- ...report,
- pendingFields: {
- createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
- },
- },
+ value: report,
},
{
onyxMethod: Onyx.METHOD.MERGE,
@@ -11062,13 +11062,13 @@ function putOnHold(transactionID: string, comment: string, initialReportID: stri
// We link the IOU action to the new transaction thread by setting childReportID optimistically
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`,
value: {[iouAction?.reportActionID]: {childReportID: reportID, childType: CONST.REPORT.TYPE.CHAT}},
});
// We reset the childReportID if the request fails
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`,
value: {[iouAction?.reportActionID]: {childReportID: null, childType: null}},
});
}There was a problem hiding this comment.
Also, can we give report a more specific name? we've got iouReport, is this a chatReport? workspaceChatReport? something else?
iwiznia
left a comment
There was a problem hiding this comment.
Agree on set/vs merge comment from Rory, but other than that looks good, so approving
src/libs/actions/IOU.ts
Outdated
| onyxMethod: Onyx.METHOD.MERGE, | ||
| key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, | ||
| value: { | ||
| ...report, |
There was a problem hiding this comment.
@VickyStash you're still doing an avoidable shallow copy here:
diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts
index 3ff022a5f49..b80bd2c02f1 100644
--- a/src/libs/actions/IOU.ts
+++ b/src/libs/actions/IOU.ts
@@ -10934,6 +10934,8 @@ function putOnHold(transactionID: string, comment: string, initialReportID: stri
const moneyRequestReport = getReportOrDraftReport(transaction?.reportID);
report = buildTransactionThread(iouAction, moneyRequestReport, undefined, reportID);
}
+ // at this point, report should be defined, cast it as such
+ report ??= {} as OnyxTypes.Report;
const optimisticCreatedAction = buildOptimisticCreatedReportAction(currentUserEmail);
const parentReportActionOptimistic = getOptimisticDataForParentReportAction(report, createdReportActionComment.created, CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
@@ -11026,23 +11028,21 @@ function putOnHold(transactionID: string, comment: string, initialReportID: stri
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
- lastVisibleActionCreated: report?.lastVisibleActionCreated,
+ lastVisibleActionCreated: report.lastVisibleActionCreated,
},
},
];
// If the transaction thread report wasn't created before, we create it optimistically
if (!initialReportID) {
+ report.pendingFields = {
+ createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
+ };
optimisticData.push(
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
- value: {
- ...report,
- pendingFields: {
- createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
- },
- },
+ value: report,
},
{
onyxMethod: Onyx.METHOD.MERGE,
@@ -11062,13 +11062,13 @@ function putOnHold(transactionID: string, comment: string, initialReportID: stri
// We link the IOU action to the new transaction thread by setting childReportID optimistically
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`,
value: {[iouAction?.reportActionID]: {childReportID: reportID, childType: CONST.REPORT.TYPE.CHAT}},
});
// We reset the childReportID if the request fails
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`,
value: {[iouAction?.reportActionID]: {childReportID: null, childType: null}},
});
}
src/libs/actions/IOU.ts
Outdated
| onyxMethod: Onyx.METHOD.MERGE, | ||
| key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, | ||
| value: { | ||
| ...report, |
There was a problem hiding this comment.
Also, can we give report a more specific name? we've got iouReport, is this a chatReport? workspaceChatReport? something else?
|
Reassure test is failing on other PRs as well, probably related to this PR. |
|
Merging through failed Reassure, as discussed here: https://expensify.slack.com/archives/C07J32337/p1755536660501719?thread_ts=1755531412.317049&cid=C07J32337 |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
@VickyStash thanks for noting that my PR caused reassure failng jobs. Here is PR that resolves that #68726 |
|
🚀 Deployed to staging by https://github.com/roryabraham in version: 9.1.97-0 🚀
|
|
🚀 Deployed to production by https://github.com/AndrewGable in version: 9.1.97-5 🚀
|
| const requestParentReportAction = useMemo(() => { | ||
| if (isMoneyRequestReport || isInvoiceReport) { | ||
| if (transactionThreadReportID === CONST.FAKE_REPORT_ID) { | ||
| return Object.values(childReportActions ?? {}).find((action) => action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); |
There was a problem hiding this comment.
Came from this issue
We need to filter deleted reportActions to fix this issue
More context here
Explanation of Change
This PR implements:
Fixed Issues
$ #67885
PROPOSAL: N/A
Tests
noOptimisticTransactionThreadsbeta.Block transaction thread report creationtoggle (you can also turn it on in the troubleshoot modal CMD + D)Offline tests
Same, as in the Tests steps
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
Same, as in the Tests steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))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
android.mp4
Android: mWeb Chrome
android_web.mp4
iOS: Native
ios.mp4
iOS: mWeb Safari
ios_web.mp4
MacOS: Chrome / Safari
web.mp4
MacOS: Desktop
desktop.mp4