Skip to content

Standardize Expense Report and Expense header with predictable button placement and carousel counter - #90403

Merged
JS00001 merged 31 commits into
Expensify:mainfrom
thelullabyy:fix-lullabyy/90366
Jul 17, 2026
Merged

JS00001 merged 31 commits into
Expensify:mainfrom
thelullabyy:fix-lullabyy/90366

Conversation

@thelullabyy

@thelullabyy thelullabyy commented May 13, 2026 •

Copy link
Copy Markdown
Contributor

Explanation of Change

Fixed Issues

$ #90366
PROPOSAL: N/A

Tests

  • Setup
    Log in with a test account that has access to a paid workspace with multiple expense reports and expenses
    Have these in your test workspace:
  • At least 3 expense reports (mix of submitted/approved/paid states)
  • At least one expense report containing 3+ expenses
  1. Go to Spend --> Report/Expenses
  2. Verify that the expense/report header looks like this figure below for scenarios
  3. Verify that navigate using the carousel and ensure that all the expenses/reports from the list are available
image
  • Verify that no errors appear in the JS console

Offline tests

QA Steps

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
      • If any non-english text was added/modified, I used JaimeGPT to get English > Spanish translation. I then posted it in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Screen.Recording.2026-05-17.at.23.29.29.mov
Android: mWeb Chrome
Screen.Recording.2026-05-17.at.23.25.25.mov
iOS: Native
iOS: mWeb Safari
Screen.Recording.2026-05-17.at.23.21.16.mov
MacOS: Chrome / Safari
Screen.Recording.2026-05-17.at.23.15.10.mov

@codecov

codecov Bot commented May 13, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.

Files with missing lines Coverage Δ
src/ONYXKEYS.ts 100.00% <ø> (ø)
src/components/MoneyReportHeaderMoreContent.tsx 100.00% <100.00%> (ø)
...tView/MoneyRequestReportTransactionsNavigation.tsx 95.93% <100.00%> (+94.84%) ⬆️
...archList/ListItem/TransactionGroupListExpanded.tsx 66.15% <ø> (ø)
src/libs/ExportOnyxState/common.ts 80.35% <ø> (ø)
src/pages/home/RecentlyAddedSection/index.tsx 100.00% <ø> (ø)
src/pages/inbox/ReportNavigateAwayHandler.tsx 68.35% <100.00%> (+0.40%) ⬆️
src/libs/actions/TransactionThreadNavigation.ts 71.42% <77.77%> (+0.46%) ⬆️
src/components/MoneyRequestHeader.tsx 0.00% <0.00%> (ø)
...RequestReportView/MoneyRequestReportNavigation.tsx 6.12% <0.00%> (-0.13%) ⬇️
... and 3 more
... and 11 files with indirect coverage changes

@melvin-bot

melvin-bot Bot commented May 17, 2026

Copy link
Copy Markdown

@ShridharGoel 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]

@melvin-bot
melvin-bot Bot requested review from trjExpensify and removed request for a team May 17, 2026 16:32

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ea131bb78

ℹ️ 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".

Comment thread src/components/Search/index.tsx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🚧 @shawnborton has triggered a test Expensify/App build. You can view the workflow run here.

@github-actions

This comment has been minimized.

@shawnborton

Copy link
Copy Markdown
Contributor

When I open an expense from the expenses list, I noticed it doesn't have the carousel in the top right:
CleanShot 2026-05-18 at 10 05 02@2x

Part of this issue is implementing that feature as well.

@shawnborton

Copy link
Copy Markdown
Contributor

Let's give the "X of X" box some kind of min-width so that we prevent the slight jumping when we change numbers:
CleanShot 2026-05-18 at 10 05 02@2x

Like a min-width of 32px and text-align: right or something?

@shawnborton

Copy link
Copy Markdown
Contributor

Curious what @Expensify/design thinks but I do feel like the top row and bottom row in the header could be closer together:
CleanShot 2026-05-18 at 10 08 36@2x

From Figma:
CleanShot 2026-05-18 at 10 09 51@2x

BUT the main thing is that in Figma, we're doing it like this:
CleanShot 2026-05-18 at 10 10 07@2x

However in the product, we are doing this:

CleanShot 2026-05-18 at 10 12 05@2x

So if we wanted to avoid a huge refactor of the top bar, the easiest thing might be to give the secondary bar a negative top margin of -4px?
CleanShot 2026-05-18 at 10 12 54@2x

@dannymcclain

Copy link
Copy Markdown
Contributor

@shawnborton yeah that sounds good to me 👍

@dubielzyk-expensify

Copy link
Copy Markdown
Contributor

Big fan. I think we're maybe a bit too generous with spacing in the header so that makes sense to me 👍

@thelullabyy

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback, I will address them today

@thelullabyy
thelullabyy requested a review from a team as a code owner May 20, 2026 12:13
@thelullabyy

Copy link
Copy Markdown
Contributor Author

Hi all, I have fixed this point and this point

But... for this point, I couldn't reproduce it anymore. Can you please re-test it @shawnborton

Screen.Recording.2026-05-20.at.19.12.28.mov

@github-actions

Copy link
Copy Markdown
Contributor

🚧 @shawnborton has triggered a test Expensify/App build. You can view the workflow run here.

@github-actions

This comment has been minimized.

@shawnborton

Copy link
Copy Markdown
Contributor

Still missing when I go to Spend > Expenses and open an expense:
CleanShot 2026-05-20 at 14 28 14@2x

@shawnborton

Copy link
Copy Markdown
Contributor

Try getting some "one expense reports" in your account, where a report only has a single expense attached to it.

return (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.gap2]}>
{!shouldDisplayNarrowVersion && <Text style={styles.mutedTextLabel}>{`${currentIndex + 1} of ${allReportsCount}`}</Text>}
{!shouldDisplayNarrowVersion && <Text style={[styles.mutedTextLabel, styles.textAlignRight, styles.mnw8]}>{`${currentIndex + 1} of ${allReportsCount}`}</Text>}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we missed the i18n for this copy? Is it intentional? If not, I can fix it @shawnborton

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update that to be internationalized, yes!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnborton It is fixed. Could you please run the translation script?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to do that, maybe @trjExpensify or @ShridharGoel can help?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can follow this comment @shawnborton #90403 (comment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see you did already. Lol, never mind.. translations twice!

@thelullabyy

Copy link
Copy Markdown
Contributor Author

@shawnborton I need to confirm about carousel behavior when opening a one-transaction report from the Expenses list

When clicking an expense from the flat Spend > Expenses list, the destination view depends on the parent report's transaction count:

  1. Multi-transaction parent report → opens the transaction thread (uses MoneyRequestHeader)
  2. One-transaction parent report → opens the parent report directly (uses MoneyReportHeader)

This means two different view types are reachable from the same list, which makes a single carousel behavior tricky.

Current behavior in this PR

  1. Multi-tx case: transaction carousel renders in the header and ◄/► navigates between the siblings I clicked from. ✅
  2. One-tx case: no carousel renders at the top right. If we want to carousel renders here, what should we navigate to when pressing ◄/► in the combined cases?

@melvin-bot

melvin-bot Bot commented May 20, 2026

Copy link
Copy Markdown

Hey, I noticed you changed src/languages/en.ts in a PR from a fork. For security reasons, translations are not generated automatically for PRs from forks.

If you want to automatically generate translations for other locales, an Expensify employee will have to:

  1. Look at the code and make sure there are no malicious changes.
  2. Run the Generate static translations GitHub workflow. If you have write access and the K2 extension, you can simply click: [this button]

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 ts-node ./scripts/generateTranslations.ts --help

Typically, you'd want to translate only what you changed by running npx ts-node ./scripts/generateTranslations.ts --compare-ref main

@shawnborton

Copy link
Copy Markdown
Contributor

I would think the carousel is just going to take you through the available expenses you see from Spend > Expenses. Does that make sense? It shouldn't have anything to do with if the expense is on a report or not. It's really just a carousel for whatever list you are in when you view the expense. In this case, the list is Spend > Expenses.

@OSBotify

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/JS00001 in version: 9.4.41-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@MelvinBot

Copy link
Copy Markdown
Contributor

🤖 Help site review: no changes required.

This PR standardizes the Expense Report and Expense header UI — predictable button placement (report actions moved down by the next steps, carousel arrows pinned top-right), a consistent X of X carousel counter, and always showing the carousel when you open an expense from the Spend page. These are presentation/behavior refinements to existing navigation, not a new or changed feature that the help site documents.

I reviewed App/docs/articles against the changes:

  • The only match for "carousel" is in Getting Started with the Spend Page under Report Previews → "Carousel navigation" — that refers to the report-preview card in the Inbox, a different surface this PR does not touch.
  • No article documents the header-level prev/next carousel, its counter label, or the placement of the report/expense action buttons, so nothing becomes inaccurate.

Because the help site describes what you can do (view, filter, navigate reports and expenses) rather than the exact header layout, this UI standardization doesn't require any article edits. I did not open a draft docs PR.

If you'd like a short note added to the Spend page article calling out that a navigation carousel now appears when opening an expense from the Spend page, reply and I'll draft one.

@mitarachim

Copy link
Copy Markdown

Deploy Blocker #96545 was identified to be related to this PR.

@mitarachim

Copy link
Copy Markdown

Deploy Blocker #96548 was identified to be related to this PR.

@mitarachim

Copy link
Copy Markdown

Deploy Blocker #96563 was identified to be related to this PR.

@jponikarchuk

Copy link
Copy Markdown

Deploy Blocker #96566 was identified to be related to this PR.

@mitarachim

Copy link
Copy Markdown

Deploy Blocker #96575 was identified to be related to this PR.

JS00001 added a commit that referenced this pull request Jul 21, 2026
Revert "Merge pull request #90403 from thelullabyy/fix-lullabyy/90366"
mukhrr pushed a commit to mukhrr/App that referenced this pull request Jul 21, 2026
…byy/90366"

This reverts commit 4c9698b, reversing
changes made to acedb02.
OSBotify pushed a commit that referenced this pull request Jul 21, 2026
Revert "Merge pull request #90403 from thelullabyy/fix-lullabyy/90366"

(cherry picked from commit 0c9248d)

(cherry-picked to staging by Beamanator)
@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/yuwenmemon in version: 9.4.41-4 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/JS00001 in version: 9.4.42-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@MelvinBot

Copy link
Copy Markdown
Contributor

Help site review — no changes required

I reviewed the changes in this PR against Expensify's help site files under docs/articles, and no documentation updates are needed.

Why: This PR is a UI layout/standardization change to the expense report and expense headers. It:

  • Standardizes action-button placement (report buttons move down next to the report next steps)
  • Always shows the carousel navigation buttons in the top right with a consistent X of Y counter
  • Always shows the carousel for expenses opened from the Spend page

None of this adds, removes, or changes a documented feature, workflow, setting, or button label. The carousel and header action buttons already existed — this only makes their placement and the counter consistent across the two header types.

The only help article that references a "carousel" is Getting-Started-with-the-Spend-Page.md, where "Carousel navigation" is listed under Report Previews → Preview Details (the in-chat report preview card). That's a different UI surface from the report/expense header this PR touches, and that mention remains accurate — so it needs no edit.

The new currentOfTotal (X of Y) string added to the language files is internal microcopy consistency and isn't referenced in any help article.

Since no changes are required, I did not create a draft help site PR.

@thelullabyy — flagging you in case you disagree with this assessment. If you believe a help article should be updated for this behavior, reply with @MelvinBot and point me at the article and I'll draft the PR.

lorretheboy added a commit to lorretheboy/App that referenced this pull request Jul 22, 2026
The merge of main re-introduced changes from PR Expensify#90403 (fix-lullabyy/90366),
which had been reverted on main. This restores MoneyRequestReportTransactionsNavigation.tsx
to the genuine PR Expensify#96355 change (thread personalDetails through) and removes the
redundant MoneyRequestReportTransactionsNavigation.test.tsx that belonged to the
reverted PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01964hgbhMgCovsXubPWdcEv
@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/yuwenmemon in version: 9.4.42-1 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.