Repository navigation
Fetch policy categories and tags on the Search Edit multiple page - #102812
Conversation
The Category and Tag rows depend on policy categories/tags, which are not in the search snapshot. After a cache clear, opening Edit multiple straight from Search left them unloaded, so the rows were hidden. Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
I created this PR from an upstream branch since I don't have push access to your fork. To take ownership of this branch and be able to push updates, run: Then you can close this PR and open a new one from your fork. |
|
🤖 Web test steps verification results: ✅ pass After Clear cache and restart, I went straight to Search → Drafts without opening any expense. Edit multiple on 2 selected drafts showed the Category and Reimbursable rows right away, and they were still there after I opened an expense and reselected. The PR's Tests section is empty, so I used the reproduction steps from the linked issue.
|
|
@MelvinBot Mark this PR as ready |
|
@MelvinBot Merge main and open this PR for review |
…aOnSearchEditMultiple Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
🤖 I merged
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31dfd6f858
ℹ️ 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".
| if (policy?.areCategoriesEnabled && !policyCategories) { | ||
| openPolicyCategoriesPage(policyID); | ||
| } | ||
| if (policy?.areTagsEnabled && !policyTags) { | ||
| openPolicyTagsPage(policyID); |
There was a problem hiding this comment.
Fetch until the policy data is confirmed complete
For lazy-loaded accounts, these Onyx entries can contain only the category or tag already present on an expense, so their existence does not mean the full policy data was loaded (the existing useLoadPolicyCategories and useLoadPolicyTags hooks explicitly track hasOnceLoaded for this reason). In particular, when such a partial tag entry omits other tag lists, this guard skips the request and the page never renders rows for those lists, leaving them impossible to bulk-edit until another screen hydrates the policy. Gate this on the RAM-only completion/loading state and use the established loaders rather than !policyCategories/!policyTags.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🤖 Codex is right, so I fixed it in f8fcf9b.
Checking !policyCategories / !policyTags skips the fetch when a lazy-loaded account has only a partial collection, such as just the tag already on its expenses. The other categories and tag lists then never load.
The page now calls the shared useLoadPolicyCategories and useLoadPolicyTags hooks, the same ones CategoryPicker and TagPicker use. It passes policyID only when the feature is enabled. The hooks check the RAM-only hasOnceLoaded state and retry on reconnect, so I removed the custom useEffect and useNetwork logic.
- Tests: I added a fetch-when-partial case to
tests/ui/SearchEditMultiplePageTest.tsx. The no-refetch case now seedshasOnceLoaded: true. - Checks: Type check and lint pass locally. Jest won't start in my environment for a reason unrelated to this change, so CI will be the first run of these tests.
- PR description: I updated the explanation to match.
|
The failing Analysis: Evidence:
Once |
|
Nothing has changed since my last comment, so I didn't push anything.
Once |
Reuse useLoadPolicyCategories and useLoadPolicyTags so a partial collection on a lazy-loaded account still triggers a full read. Co-authored-by: truph01 <truph01@users.noreply.github.com>
| // Policy categories and tags are not part of the search snapshot, and this page can be opened straight from Search | ||
| // before any screen has fully loaded them (e.g. after a cache clear, or on a lazy-loaded account that only holds the | ||
| // values already on its expenses), so load them here or their rows stay hidden or incomplete. |
|
Both failing checks are unrelated to this PR, so I didn't push a fix. This PR only changes
Once |
Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
The failing checks are still unrelated to this PR, so I didn't push a fix. This PR only changes
The fix belongs in |
|
The failing checks are still unrelated to this PR, so I didn't push a fix. This PR only changes
After |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-10-13.at.16.43.30.movAndroid: mWeb ChromeScreen.Recording.2026-10-13.at.16.45.06.moviOS: HybridAppScreen.Recording.2026-10-13.at.16.51.44.moviOS: mWeb SafariScreen.Recording.2026-10-13.at.16.52.31.movMacOS: Chrome / SafariScreen.Recording.2026-10-13.at.16.38.27.mov |
|
@MelvinBot Update QA steps in your checklist to: |
|
MelvinBot has made 5 consecutive commits trying to fix CI failures. Automatic CI fix dispatches are now paused for this PR. Next steps: A human should review the recent commits and resolve the conflicting CI errors manually. |
|
🤖 I updated the QA Steps section of the PR description with your steps. I kept the "Verify that no errors appear in the JS console" checkbox below them. |
|
Fixed the failing checks by merging the latest
|
joekaufmanexpensify
left a comment
There was a problem hiding this comment.
good for product
|
@MelvinBot Please fix conflicts |
…aOnSearchEditMultiple Co-authored-by: truph01 <truph01@users.noreply.github.com> # Conflicts: # tests/ui/SearchEditMultiplePageTest.tsx
859926d
|
I fixed the merge conflict by merging The only conflict was in
No source files conflicted. I couldn't run Jest in my environment, so CI will confirm the tests pass. |
|
🚧 amyevans 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! 🧪🧪
|
|
✋ 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/amyevans in version: 9.5.10-0 🚀
|
|
No help site update is needed. This bug fix makes the Category and Tag rows load as users already expect in Edit multiple, and no sentence in Edit Expenses becomes incorrect. |
|
🚀 Deployed to staging by https://github.com/amyevans in version: 9.5.12-0 🚀
|
|
No help site update is needed. This bug fix makes the Category and Tag fields appear in Edit multiple as users already expect, and Edit Expenses already describes them that way. |
|
🚀 Deployed to production by https://github.com/cristipaval in version: 9.5.12-1 🚀
Bundle Size Analysis (Sentry): |










Explanation of Change
SearchEditMultiplePageshows the Category and Tag rows only when the workspace's categories/tags are in Onyx. Those keys are not part of the search snapshot, and no Search screen fetches them. So after a cache clear, opening Edit multiple straight from Search left them unloaded, and the rows were silently hidden until opening an expense ranOpenReportand hydrated them.This PR makes the page load them itself with the shared
useLoadPolicyCategories/useLoadPolicyTagshooks (the same onesCategoryPickerandTagPickeruse), passingpolicyIDonly when the workspace has the feature enabled:hasOnceLoadedstate, not on the Onyx value existing. So a lazy-loaded account that only holds the category or tag already on its expenses still triggers a full read, instead of hiding the other categories or tag lists.Added UI tests in
tests/ui/SearchEditMultiplePageTest.tsxcovering the fetch-when-missing, fetch-when-partial, and no-refetch-when-loaded cases.Fixed Issues
$ #101733
PROPOSAL: #101733 (comment)
Tests
#102812 (comment)
#102812 (comment)
Offline tests
QA Steps
Preconditions: A workspace with at least two draft expenses that have no category.
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