Skip to content

[Due for payment 2026-09-10] Export: when only one option is available, open directly into it instead of showing an intermediate menu #98779

Closed

Description

@melvin-bot

Problem

On the Spend page (and other pages with an export flow), selecting the export entry point typically opens a menu of available export options. However, when Export is the only option in the More menu and there is only one export option available, we skip both menus and open that option directly. This can be confusing because the user loses the context that they’re entering an export flow and may not understand what the option they’ve landed on represents.

Image

Proposed solution
When only one option is available, open the flow one level deeper instead of two. In this example, that means opening the Export menu directly and displaying the single available option, rather than navigating straight to that option.

Image

Context

Related, already-shipped work: #94056 (standardized the export filename and renamed the export option).

Reported in Slack.

Issue OwnerCurrent Issue Owner: @mallenexpensify

Activity

  1. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Aug 21, 2026
  2. melvin-bot commented on Aug 21, 2026

    @melvin-bot
    Author

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @ZhenjaHorbach (External)

  3. melvin-bot commented on Aug 21, 2026

    @melvin-bot
    Author

    Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.

  4. flaviadefaria commented on Aug 21, 2026

    @flaviadefaria
    Contributor

    @ZhenjaHorbach, I think Melvin might be able to implement this. What do you think?

  5. ZhenjaHorbach commented on Aug 21, 2026

    @ZhenjaHorbach
    Contributor

    Sounds good!

  6. ZhenjaHorbach commented on Aug 21, 2026

    @ZhenjaHorbach
    Contributor

    @MelvinBot
    Can you prepare a proposal?

  7. MelvinBot commented on Aug 21, 2026

    @MelvinBot
    Contributor

    Proposal

    What is the root cause of that problem?

    The Search/Spend "More" menu deliberately collapses the Export flow whenever exactly one export option is available. In useSearchBulkActions.ts:2085-2108, when getExportOptions() returns a single item, the code builds the Export entry as a flat button that runs that option's onSelected directly (no subMenuItems) instead of the normal entry that opens the Export submenu:

    Root-cause code
    const subMenuItems = getExportOptions();
    const singleExportSubMenuItem = subMenuItems.length === 1 ? subMenuItems.at(0) : undefined;
    
    const exportButtonOption = singleExportSubMenuItem
        ? {   // collapsed: flat button, no subMenuItems -> runs the single option directly
              icon: expensifyIcons.Export,
              text: singleExportSubMenuItem.text,
              onSelected: () => singleExportSubMenuItem.onSelected?.(),
              ...
          }
        : {   // normal: opens the Export submenu
              icon: expensifyIcons.Export,
              rightIcon: expensifyIcons.ArrowRight,
              text: translate('common.export'),
              subMenuItems,
          };

    So when Export is the only "More" option and there's only one export option, the user is taken straight into that option, losing the "you're exporting" context — exactly the confusing two-menus-skipped behavior in the issue. This collapse only exists on the Search/Spend path; the report-header and selected-transactions paths (useExportActions.ts:268, useSelectedTransactionsActions.ts:449-456) already keep subMenuItems, so they behave correctly today.

    What changes do you think we should make in order to solve the problem?

    Remove the single-option collapse in useSearchBulkActions.ts so the Export entry always uses the submenu form (the else branch above). Concretely, delete singleExportSubMenuItem and always build exportButtonOption with text: translate('common.export'), rightIcon: expensifyIcons.ArrowRight, and subMenuItems.

    With subMenuItems present, PopoverMenu.selectItem navigates one level deeper into the Export submenu (showing the single option with a back button) instead of executing it — which is the desired "open the flow one level deeper instead of two" behavior. No change is needed in the report-header/transaction paths since they never collapsed.

    What alternative solutions did you explore? (Optional)

    Keeping the collapse but only when it also collapses the top-level "More" menu (i.e. only skip a level when Export truly is the only action) — rejected because the issue explicitly wants the intermediate Export menu shown even in the single-option case, and it adds a special case rather than making the three export paths consistent.


    Next Steps for Contributor+ team:
    To accept: @MelvinBot implement [this](https://github.com/Expensify/App/issues/98779) to create a draft PR.
    To refine: @MelvinBot <your feedback>
    To reject: Explain why you are rejecting Melvin's proposal.


    view run

  8. ZhenjaHorbach commented on Aug 21, 2026

    @ZhenjaHorbach
    Contributor

    @MelvinBot
    Implement your proposal

  9. MelvinBot commented on Aug 21, 2026

    @MelvinBot
    Contributor

    🤖 Draft PR created: #99217
    Please mark it as "Ready for review" when it is ready for review.

    What changed: Removed the single-option collapse in useSearchBulkActions.ts so the Search/Spend "More" menu's Export entry always opens the Export submenu — showing the single available option one level deeper instead of navigating straight into it. The report-header and selected-transactions export paths already behaved this way and are untouched.

    Tests: Added a regression test in useSearchBulkActionsExportTest.ts that fails on the old collapsing code and passes with the fix. Ran locally: lint-changed ✅, typecheck-tsgo ✅, react-compiler compliance (no regression) ✅, spell-changed ✅, and the export/bulk-actions Jest suites ✅ (27 + button tests passing).

    One note for QA: this only affects the Search/Spend flow. Reproducing the single-option case requires a selection whose export list resolves to exactly one option (e.g. a grouped/full-group selection that offers only "Current view") — with the fix, tapping Export should now show that option inside the Export submenu rather than jumping straight into it.


    view run

  10. melvin-bot commented on Aug 24, 2026

    @melvin-bot
    Author

    @ZhenjaHorbach Whoops! This issue is 2 days overdue. Let's get this updated quick!

  11. 12 remaining items

  12. melvin-bot commented on Sep 8, 2026

    @melvin-bot
    Author

    @ZhenjaHorbach Huh... This is 4 days overdue. Who can take care of this?

  13. melvin-bot commented on Sep 9, 2026

    @melvin-bot
    Author

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  14. melvin-bot commented on Sep 9, 2026

    @melvin-bot
    Author

    Payment Summary

    Resolving PRs:

    BugZero Checklist (@mallenexpensify)

    • I have confirmed assignees, roles, and Upwork contracts look correct
    • I have paid out Upwork contracts / manual NewDot requests
    • [BugZero Assignee] I have created a GH issue for creating/updating the regression test once above steps have been agreed upon
  15. ZhenjaHorbach commented on Sep 10, 2026

    @ZhenjaHorbach
    Contributor

    Contributor+ Checklist:

    • [Contributor] The offending PR and associated issue have been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.

    It's a new feature

    • [Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.

      Link to discussion:

    • [Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.

    Precondition:

    Test:

    1. Open App
    2. Sign in to an account that has expenses/reports.
    3. Go to a Search page (e.g. Reports or Expenses) and select one or more rows so the bulk-action toolbar appears.
    4. With other bulk actions present in the More (⋮) dropdown, click Export and verify it opens the Export submenu with a generic "Export" label, a back button, and the export options listed one level deeper — it does NOT jump straight into a single option.
    5. Verify the back button returns you to the More menu.
    6. Use Select all matching so Export is the only bulk action, open the More (⋮) dropdown, and verify it opens directly onto the export options, headed by a plain "Export" title with no back arrow and no "Export" row to click through.

    Do we agree 👍 or 👎

  16. melvin-bot commented on Sep 14, 2026

    @melvin-bot
    Author

    @mallenexpensify Huh... This is 4 days overdue. Who can take care of this?

  17. mallenexpensify commented on Sep 14, 2026

    @mallenexpensify
    Contributor

    Claude posting on behalf of Matt:

    $250 to @ZhenjaHorbach (Contributor+).

    Contributor Nothing due, Melvin wrote the PR
    Contributor+ @ZhenjaHorbach due $250 via NewDot, 100%
    Job price $250, standard, no price in title
    Reduction None
    Increase None
    Blockers None linked
    Precedent None needed, this is the standard path
    Needs a ruling No

    To pay, copy this block and paste it into the comment box:

    ### Payment Summary
    Contributor+: @ZhenjaHorbach due $250 via NewDot
    
    How the amount is reached
    PR #99217, author MelvinBot
    Size 4 files, +155 / -57
    C+ checklist on this issue Posted by @ZhenjaHorbach
    Reviewer checklist on the PR Posted by @ZhenjaHorbach, all boxes checked
    Platform evidence Reviewer checklist 5 of 5 with a video. Author checklist 0 of 5 boxes checked
    • Job price $250. No price in the title.
    • Contributor: nothing due. Melvin wrote the PR.
    • Contributor+: 100%. The reviewer checklist is complete and carries a video on all five platforms.
    • No regression cut. No blocker linked.
    • No increase. Below the 25 file and 1000 line thresholds.

    Reported, not deducted: Melvin's own author checklist has 0 of 5 boxes checked and no evidence. The author here is Melvin, so no payment turns on it, but the same gap on a human-authored PR would be worth seeing.


    Claude posting on behalf of Matt. PAYRUBRICTEST v2

  18. mallenexpensify commented on Sep 15, 2026

    @mallenexpensify
    Contributor

    Payment Summary

    Contributor+: @ZhenjaHorbach due $250 via NewDot

    @ZhenjaHorbach please use the exact template here when posting the C+ Checklist (partially cuz I have automation build and need the exact format). The button to auto-post the checklist should be fixed soon. Thx

  19. garrettmknight commented on Oct 7, 2026

    @garrettmknight
    Contributor

    $250 approved for @ZhenjaHorbach

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

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionDailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions