Fix expense carousel position jump when creating expense without category - #91467
Conversation
…gory Two changes to prevent newly created expenses from jumping positions in the expense carousel: 1. Initialize category to 'Uncategorized' in buildOptimisticTransaction instead of empty string, preventing a transient missing-category RBR violation that disappears on backend sync. 2. Add date-based tiebreaker to carousel sort so expenses with equal RBR status maintain stable positions (oldest first). Co-authored-by: Kevin Brian Bader <ikevin127@users.noreply.github.com>
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
This comment was marked as resolved.
This comment was marked as resolved.
|
All PR Author Checklist checkboxes have been checked and the PR has been marked as ready for review. |
|
@ikevin127 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] |
|
@MelvinBot Fill out the Tests section with same tests as QA Steps and for the Offline tests just add N/A. |
Reviewer Checklist
Screenshots/VideosScreen.Recording.2026-05-21.at.19.17.22.mov |
ikevin127
left a comment
There was a problem hiding this comment.
🟢 LGTM
Everything checks out and tests pass as expected, context on this PR creation:
- suggestion and confirmation on using MelvinBot
- solution breakdown w/ MelvinBot (response)
- final solution confirmation (tested 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. |
|
🚧 @grgia 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/grgia in version: 9.3.81-0 🚀
|
|
No help site changes are required for this PR. This PR fixes an internal UI behavior bug (expense carousel position jumping when creating an expense without a category). The changes are:
These are purely internal code fixes with no impact on user-facing documentation — no new features, renamed settings, or workflow changes that would need to be reflected in help site articles. |
|
🚀 Deployed to production by https://github.com/luacmartins in version: 9.3.81-2 🚀
|
Explanation of Change
When creating a new expense without a category in a workspace chat, the expense would briefly appear at the first position in the expense carousel and then jump to the last position. This happened because:
Transient RBR violation:
buildOptimisticTransactiondefaultedcategoryto''(empty string), which triggered a missing-category RBR violation optimistically. When the backend synced and returned the real transaction data, the violation was removed — causing the expense to lose its RBR-priority sort position and jump.Unstable sort: When two transactions had the same RBR status, their relative order was undefined, so any RBR state change could shuffle positions.
Fix:
categorytoCONST.SEARCH.CATEGORY_DEFAULT_VALUE('Uncategorized') inbuildOptimisticTransactionso the optimistic transaction doesn't get a spurious missing-category violation.Fixed Issues
$ #90063
Tests
Offline tests
N/A
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, 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.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: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
AI Tests
origin/ref)