Repository navigation
Warn about blocked reports when bulk submitting a mixed selection - #99995
NikkiWines merged 14 commits into
Conversation
Evaluate hasOnlyPendingCardTransactions and hasOnlyHeldExpenses per selected report instead of on the flattened cross-report transaction list. When every selected report is blocked, keep the existing block modals. When only some are, show a confirm modal explaining how many reports can't be submitted and, on confirm, submit only the submittable ones.
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running: npx bun ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
The generateTranslations workflow does not run for fork PRs, so add the new iou.error keys to de, el, fr, it, ja, nl, pl, pt-BR, and zh-hans manually.
|
This seems like it’s starting to get a little complicated. @joekaufmanexpensify I see you’re on the parent issue. What would you think about:
|
|
Yep, that's fair. I'm good with that simpler approach. 👍 |
|
Cool, @c3024 what do you think? |
Mixed selections no longer stop at a confirm prompt. The submittable reports are submitted right away and one informational modal lists the reports that were skipped because all of their expenses are on hold or pending, matching the export-to-accounting modal. A fully blocked selection keeps the existing reason-specific modal.
… the reason-specific one
|
@huult, the PR is ready for your review. |
|
Thanks! I’ll take a look soon. |
| // The Submit option only appears for a submit-type workspace when exactly one report is selected, and that | ||
| // report picks its manager in a popover. Skip the popover when the report is blocked so it falls through to | ||
| // the modal below showing that the report could not be submitted. |
There was a problem hiding this comment.
@c3024 Could we remove or shorten the comments added in this PR?
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-09-11.at.09.22.38.movAndroid: mWeb ChromeScreen.Recording.2026-09-11.at.09.20.09.moviOS: HybridAppScreen.Recording.2026-09-11.at.09.33.06.moviOS: mWeb SafariScreen.Recording.2026-09-11.at.09.36.54.movMacOS: Chrome / SafariScreen.Recording.2026-09-11.at.09.16.02.mov |
@c3024 what do you think? |
|
@trjExpensify #99995 (comment) Does this look good to you? |
|
Yeah, definitely better than no bullets. Thanks! |
Screen.Recording.2026-09-11.at.09.30.24.movScreen.Recording.2026-09-11.at.09.26.08.mov@c3024 I was able to reproduce the crash issue on iOS. Could you take a look? To reproduce the iOS crash issue, you can log out and sign in again, then go to a report, select 4–5 items, and submit them. If you’re still unable to reproduce it on your side, I can share my account with you for testing. Crash Log``` ------------------------------------- Translated Report (Full Report Below) ------------------------------------- Process: Expensify [55186] Path: /Users/USER/Library/Developer/CoreSimulator/Devices/83B762CE-06C9-43BF-A705-F57944F6116D/data/Containers/Bundle/Application/DC9F439B-A535-4F28-A283-B3DDC5F73CC9/Expensify.app/Expensify Identifier: com.expensify.expensifylite Version: 9.4.53 (9.4.53.8) Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd_sim [55032] Coalition: com.apple.CoreSimulator.SimDevice.83B762CE-06C9-43BF-A705-F57944F6116D [2268] Responsible Process: SimulatorTrampoline [55023] User ID: 501Date/Time: 2026-09-11 09:26:24.9471 +0700 Crash Reporter Key: 7ABC40A6-094E-A8D3-9519-34715EB34936 Time Awake Since Boot: 3600 seconds System Integrity Protection: enabled Triggered by Thread: 0, Dispatch Queue: com.apple.main-thread Exception Type: EXC_CRASH (SIGABRT) Termination Reason: Namespace SIGNAL, Code 6, Abort trap: 6 Last Exception Backtrace: Thread 0 Crashed:: Dispatch queue: com.apple.main-thread Thread 1:: com.apple.uikit.eventfetch-thread Thread 2:: fs-default-0 Thread 3:: fs-default-1 Thread 4:: fs-default-2 Thread 5:: fs-default-3 Thread 6:: com.facebook.react.runtime.JavaScript Thread 7:: hades Thread 8:: com.apple.NSURLConnectionLoader Thread 9:: com.apple.CFStream.LegacyThread Thread 10:: com.facebook.SocketRocket.NetworkThread Thread 11:: com.apple.CFSocket.private Thread 12:: hades Thread 13:: caulk.messenger.shared:17 Thread 14:: caulk.messenger.shared:high Thread 15:: nitro-thread-1 Thread 16:: nitro-thread-2 Thread 17:: nitro-thread-3 Thread 18:: com.apple.CoreMotion.MotionThread Thread 19:: LiveMarkdownRuntime_queue Thread 20:: hades Thread 21:: LiveMarkdownRuntime(timeout) Thread 22:: nitro-thread-4 Thread 23:: nitro-thread-5 Thread 24:: nitro-thread-6 Thread 25:: nitro-thread-7 Thread 26:: nitro-thread-8 Thread 27:: nitro-thread-9 Thread 28:: nitro-thread-10 Thread 29: Thread 30: Thread 31: Thread 32: Thread 33: Thread 34: Thread 35: Thread 0 crashed with ARM Thread State (64-bit): Binary Images: External Modification Summary: VM Region Summary: REGION TYPE SIZE COUNT (non-coalesced) Full Report{"app_name":"Expensify","timestamp":"2026-09-11 09:26:31.00 +0700","app_version":"9.4.53","slice_uuid":"9e150bf8-7de3-3276-8c71-3ffaec837357","build_version":"9.4.53.8","platform":7,"bundleID":"com.expensify.expensifylite","share_with_app_devs":0,"is_first_party":0,"bug_type":"309","os_version":"macOS 26.5.2 (25F84)","roots_installed":0,"name":"Expensify","incident_id":"C4A8984F-A6C6-4917-8212-004BAA15B54C"} ], ] Model: Mac15,6, BootROM 18000.121.3, proc 11:5:6:0 processors, 18 GB, SMC |
|
@huult this could be related to RNMarkdown on iOS and a special-character case. Could you check the export modal on both this branch and the main branch using these same report names? If it crashes on main as well, then this isn’t related to our PR changes, and we can investigate it separately without holding up this PR. |
NikkiWines
left a comment
There was a problem hiding this comment.
one thing, otherwise looks good!
|
I could not review this diff, so I did not approve the workflow runs. An Expensify employee will review it and approve them manually. |
|
I could not review this diff, so I did not approve the workflow runs. An Expensify employee will review it and approve them manually. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚧 NikkiWines has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/NikkiWines in version: 9.4.80-0 🚀
|
|
Yes — help site changes are required. Draft PR: Docs updates for E/A#99995 bulk submit skips blocked reports WhyThis PR changed a user-visible outcome: a mixed selection on the Reports tab now submits what it can, skips the blocked reports, and opens a Submit reports window listing what was skipped. The help site only covered the single-report case and never documented submitting several reports at once, so a member who hits the new window has nothing to search for. The gap is in docs/articles/new-expensify/reports-and-expenses/Create-and-Submit-Reports.md:192-194 — "Why can't I submit a report when all expenses are on hold?" describes only the single-report Unable to submit report message. What the docs PR addsAll in
How the labels were verifiedChecked against the live web app: the navigation tab is Spend, the section is Expense reports, the list tab is Reports, and the bulk-actions button reads the selected count (for example, Window copy taken verbatim from src/languages/en.ts:1688-1691 ( The mobile long-press selection steps mirror the already-published steps in Duplicate a Report and were not re-verified on a device — worth a glance during review. Applied One inconsistency I did not change, since it is outside this PR's scope: Duplicate-a-Report.md tells members to click Selected, but the button actually shows the count ( @c3024, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR |
|
Deploy Blocker #101278 was identified to be related to this PR. |
|
🚀 Deployed to production by https://github.com/luacmartins in version: 9.4.80-0 🚀
Bundle Size Analysis (Sentry): |






Explanation of Change
Evaluates the held and pending-card submit guards per selected report instead of on the flattened cross-report transaction list. Blocked reports are skipped, the rest are submitted, and one modal lists the reports that weren't submitted.
Fixed Issues
$ #99028
PROPOSAL: #99028 (comment)
Tests
Screen.Recording.2026-09-03.at.11.27.51.AM.mov
Offline tests
The bulk Submit option is not shown while offline, so this flow is not reachable offline.
QA Steps
Same as tests.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.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: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari