Label Reports tab "Select all" with matching-report count - #99689
Conversation
For expense-report searches the Search snapshot's count is the number of expenses, so Select all on the Reports tab showed the expense total instead of the report total. Consume the server-provided reportCount for the expense-report all-matching label, hold the button loading until it arrives (falling back to the loaded-page report count offline), and clear reportCount alongside the other totals when a non-totals search starts so a stale value is not shown.
|
@codex review |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@ZhenjaHorbach 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] |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c30329474e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…ct-all The bulk-actions button now waits for the server reportCount on an expense-report 'select all matching'. The totals retry/skip predicates keyed off the always-present expense count, so a snapshot with count but no reportCount (persisted before the field shipped, or a colliding non-totals response) never triggered a totals request and the button could stay loading forever. Treat a missing reportCount as the missing total for expense-report select-all so the totals retry fires.
|
@dilshodmackbook-sketch |
|
@ZhenjaHorbach could you share a test account with 50+ reports in a single month? My account doesn't have that data, and I need it to record the Select all flow. Thanks! |
You can use splits flow to create 30 transactions |
|
@ZhenjaHorbach I re-recorded all the videos myself on a real account with 50+ reports - web, mWeb, iOS and Android. CI is green now too. Ready on my end, let me know if anything else is needed. |
Reviewer Checklist
Screenshots/VideosAndroid: HybridApp2026-09-03.10.33.17.movAndroid: mWeb Chrome2026-09-03.10.33.17.moviOS: HybridApp2026-09-03.10.27.01.moviOS: mWeb Safari2026-09-03.10.21.36.movMacOS: Chrome / Safari2026-09-03.10.17.14.mov |
|
I have an infinite loading when I have a custom date range and try to select all reports
So we can add these changes |
|
I tested this PR and @ZhenjaHorbach comment is valid and need to be addressed for that case, it fixes #99502 as well |
@BartekObudzinski |
|
No I did not create a PR, waiting for this one to be shipped, and yes you should add it here |
…nd calc totals during active select-all
|
@ZhenjaHorbach added both changes and updated the expense-report totals test to match the new behavior. Since the totals request no longer gets dropped, this should cover #99502 as well. Thanks for the detailed diagnosis. |
|
@dilshodmackbook-sketch |
…7-reports-select-all-report-count
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
Done - updated the branch to the latest main, and all jest/tests are green now. Ready for another look. |
|
🚧 JS00001 has triggered a test Expensify/App build. You can view the workflow run here. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/JS00001 in version: 9.4.70-0 🚀
|
|
Yes — a help site change is needed. Draft PR: #100338 This PR changes what a number on screen means. Before it, choosing Select all on the Reports tab of the Spend page labelled the button with the matching expense count. Now it shows the matching report count — so the button and the footer legitimately disagree (your own recording: 110 selected above Expenses: 93). The help site described neither count, so a member who sees two different numbers has nothing to check against. That is the confusion the linked issues were filed as. What the docs PR changes —
Articles reviewed and label verificationReviewed, no change needed:
Label verification — Spend, Reports, and Filters were confirmed against the live web UI. Select all, Select all on this page, Note the docs say Filters (plural), not Filter as written in your test steps. The live UI is Filters, so the article is already correct. One thing I couldn't do: GitHub rejected the assignment — @dilshodmackbook-sketch, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR |
|
🚀 Deployed to staging by https://github.com/JS00001 in version: 9.4.72-0 🚀
|

Explanation of Change
On Spend → Reports, using Select all (the cross-page "Select all matching" affordance) labelled the header with the wrong number: it showed the count of expenses instead of the count of reports.
For a
type: expense-reportsearch,currentSearchResults.search.countis the number of expenses, not reports. WhenareAllMatchingItemsSelectedis on,selectedAllMatchingItemsCountonly reconciled the count for the Expenses tab (isExpenseType); the Reports tab fell through theelseand renderedcountverbatim — the expense total. Re-toggling bulk select looked correct only because it dropped out of all-matching mode and used the locally-selected report count.The genuinely correct value — how many reports match across all pages — is not derivable on the client (
selectAllMatchingItemsnever loads the un-selected rows, soselectedItemsCountis only the loaded page). The server now returns it as a newreportCountfield on the Search response.This change:
reportCountfield to theSearchResultsInfotype.expense-reportall-matching selections, labels the button with the serverreportCount(matching reports) instead ofcount(expenses), holding the button in its loading state until the report count arrives, and falling back to the loaded-page report count when offline / on error.reportCountalongsidecount/total/currencywhen a non-totals search starts, so a stale report count is not shown on the next "Select all".The
isExpenseTypebranch and its exclusion arithmetic are untouched, so the Expenses tab and theinvoice/trip/chat/tasktypes are unaffected. The footer keeps readingsearch.count, soExpenses: Nis unchanged.Fixed Issues
$ #99067
$ #99502
PROPOSAL: #99067 (comment)
Tests
Offline tests
QA Steps
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
Screen.Recording.2026-09-01.at.18.37.50.mov
Android: mWeb Chrome
Screen.Recording.2026-09-01.at.18.33.26.mov
iOS: Native
Screen.Recording.2026-09-01.at.18.56.56.mp4
iOS: mWeb Safari
Screen.Recording.2026-09-01.at.18.43.28.mp4
MacOS: Chrome / Safari
Screen.Recording.2026-09-01.at.17.41.29.mp4
Recorded on my own account with 50+ reports. On the Reports tab, Select all now shows 110 (the number of reports) while the footer shows 93 expenses - before the fix the button showed the expense count. Reports outnumber expenses here only because many are empty duplicates I created to get past 50 reports and surface the cross-page Select all.