Skip to content

[Due for payment 2026-11-05] Reorganize the Search Filters page into clearer sections and add a filter search #104330

Open

Description

@JmillsExpensify

Background

The Filters page in Search lists the available filters in four sections, split by dividers. The first section holds the most common filters, the second expense/report details, the third dates of expense/report actions, and the fourth is a set of reimbursement filters. The second section is one very long list: 26 filters for the Expense type, 15 for Expense report, and 13 each for Invoice and Trip.

That middle section doesn't group related filters together, which makes the page hard to scan:

  • Keyword, the filter we set when someone types a quick search above a table, is the last row of the middle section for each of these types.
  • For Expense, Amount sits below Expense type and Date, and the card filters sit between Billable and Purchase amount.
  • Posted is a card transaction date, but it sits with the report action dates.
  • For Expense report, Exported to, Paid status, and Paid by sit in the middle section, apart from Exported and Paid.
  • For Invoice and Trip, Total, Title, and Report ID sit in the report action dates section, after Posted.

Better grouping helps, but the lists stay long. Expense alone has 42 filters, which takes several screens to scroll through.

This issue reorders the filters for the Expense, Expense report, Invoice, and Trip types into the same set of sections, so related filters sit together and each section is in the same place across those four types. It also adds a search input at the top of Filters, so people can jump straight to the filter they want.

Product and design details

[Mock: Filter search, with results and with no results] cc @dubielzyk-expensify

Sections

For the expense, expense-report, invoice and trip types, the page uses seven sections, always in this order. Each is separated by the existing divider. The section names are for this issue only; we don't add section headers to the page.

  1. Core
  2. Details
  3. Card transactions (new)
  4. Report fields (new)
  5. Report actions
  6. Exports (new)
  7. Withdrawals

Expense order

  1. Core: Type, Status, From, To, Workspace, Keyword
  2. Details: Amount, Currency, Date, Merchant, Description, Category, Tag, Reimbursable, Billable, Attendees, Tax rate, Expense type, Receipt type, Has, Purchase amount, Purchase currency
  3. Card transactions: Card, Bank account, Feed, Transaction status, Posted
  4. Report fields: Report ID, Report field, Custom field 1, Custom field 2
  5. Report actions: Submitted, Rejected, Held, Approved, Paid, Paid by
  6. Exports: Exported, Exported to
  7. Withdrawals: Withdrawal ID, Withdrawal type, Withdrawal status, Withdrawn, International reimbursement IDs

Expense report order

  1. Core: Type, Status, From, To, Workspace, Keyword
  2. Details: Total, Currency, Created date, Title, Amount debited, Amount reimbursed
  3. Card transactions: not shown for this type.
  4. Report fields: Report ID, Report field, Custom field 1, Custom field 2
  5. Report actions: Submitted, Rejected, Held, Approved, Paid, Paid by, Paid status
  6. Exports: Exported, Exported to
  7. Withdrawals: Withdrawal ID, Withdrawal type, Withdrawal status, Withdrawn, International reimbursement IDs

The details section mirrors the Expense order: amount and currency first, then date, then the descriptive field, with the secondary amounts (Amount debited, Amount reimbursed) last, like Purchase amount and Purchase currency.

Invoice order

  1. Core: Type, Status, From, To, Workspace, Keyword
  2. Details: Total, Amount, Currency, Created date, Title, Merchant, Description, Category, Tag, Tax rate, Purchase amount, Purchase currency
  3. Card transactions: Card, Feed, Posted
  4. Report fields: Report ID
  5. Report actions: Submitted, Rejected, Held, Approved, Paid, Paid by
  6. Exports: Exported
  7. Withdrawals: Withdrawal ID, Withdrawal type, Withdrawal status, Withdrawn

Created date is today's Date filter with a new label; what it filters on doesn't change. An invoice has both invoice-level fields (Total, Title) and line-level fields (Amount, Merchant), so the details section puts the amounts and Currency first, then Created date, then the descriptive fields.

Trip order

  1. Core: Type, Status, From, To, Workspace, Keyword
  2. Details: Total, Amount, Currency, Date, Title, Merchant, Description, Category, Tag, Tax rate, Purchase amount, Purchase currency
  3. Card transactions: Card, Feed, Posted
  4. Report fields: Report ID
  5. Report actions: Submitted, Rejected, Held, Approved, Paid, Paid by
  6. Exports: Exported, Exported to
  7. Withdrawals: Withdrawal ID, Withdrawal type, Withdrawn

The details section uses the same order as Invoice, but keeps the Date label, since trips behave like expenses.

Conditional filters

Some filters only appear when the user has the relevant setup, for example Custom field 1 and Custom field 2.

  • When a filter doesn't apply, we hide it, and the rest of its section keeps the order above.
  • When no filter in a section applies, we hide the whole section, including its divider. The page never shows two dividers in a row, or a divider at the top or bottom of the list.
  • Each filter's own visibility rules don't change.

Filter search

We add a search input at the top of Filters, above Type. It shows on web, where Filters opens as a popover, and on mobile, where it opens full screen. It shows for every type, including Chat and Task.

  • Placeholder: Search filters.
  • Reuse: we reuse the existing search input from our selection lists, like the one in the Category picker. No new component.
  • Matching: as the user types, we show only the filters whose name contains the text, ignoring case. For example, paid matches Paid, Paid by, and Paid status. We match filter names only, not the values set on them.
  • Sections: matching filters keep their section and order. Sections with no matches are hidden.
  • No matches: we show No results found in place of the list, matching our other selection lists.
  • Clearing: clearing the input brings back the full list. The search text stays when the user opens a filter and comes back, and resets when Filters closes.
  • Focus: on web, the input is focused when the popover opens, so the user can type right away. On mobile it isn't, so the keyboard doesn't cover the list.
  • Apply filters stays at the bottom and works the same during a search.
Issue OwnerCurrent Issue Owner: @Krishna2323

Activity

  1. added
    ImprovementItem broken or needs improvement.
    InternalRequires API changes or must be handled by Expensify staff
    on Oct 19, 2026
  2. dubielzyk-expensify commented on Oct 20, 2026

    @dubielzyk-expensify
    Contributor

    I'll look into the list itself, but I know one idea was to add a search field to filter the list of filters:

    CleanShot.2026-10-20.at.2.01.12.PM.mp4

    Test out the adhoc build on the PR over here

  3. JmillsExpensify commented on Oct 20, 2026

    @JmillsExpensify
    ContributorAuthor

    That looks great. Also @Krishna2323 one thing I realized testing another PR is that we have recently added a Rejected filter and we are also adding a Held filter. I've added them to the "report actions" sections above.

  4. JS00001 commented on Oct 20, 2026

    @JS00001
    Contributor

    Ooh yeah I really like that idea @dubielzyk-expensify

  5. dubielzyk-expensify commented on Oct 21, 2026

    @dubielzyk-expensify
    Contributor

    Forgot to cc @Expensify/design for thoughts

  6. shawnborton commented on Oct 21, 2026

    @shawnborton
    Contributor

    Yup, nice and clean - I like it!

  7. shawnborton commented on Oct 21, 2026

    @shawnborton
    Contributor

    In this case, should we also clear out the right pane though? Otherwise it can feel a bit odd and disconnected.

    Image
  8. JmillsExpensify commented on Oct 21, 2026

    @JmillsExpensify
    ContributorAuthor

    Good point. I agree with that.

  9. 12 remaining items

  10. self-assigned this
    on Oct 26, 2026
  11. daledah commented on Oct 26, 2026

    @daledah
    Contributor

    I assigned my self since i was the C+ on this PR

  12. melvin-bot commented on Oct 27, 2026

    @melvin-bot

    ⚠️ Looks like this issue was linked to a Deploy Blocker here

    If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

    If a regression has occurred and you are the assigned CM follow the instructions here.

    If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

  13. mitarachim commented on Oct 27, 2026

    @mitarachim

    Deploy Blocker #105197 was identified to be related to the PR #104668 that attempted to fix this issue.

  14. melvin-bot commented on Oct 28, 2026

    @melvin-bot

    ⚠️ Looks like this issue was linked to a Deploy Blocker here

    If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

    If a regression has occurred and you are the assigned CM follow the instructions here.

    If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

  15. changed the title [-]Reorganize the Search `Filters` page into clearer sections and add a filter search[/-] [+][Due for payment 2026-11-05] Reorganize the Search `Filters` page into clearer sections and add a filter search[/+] on Oct 29, 2026
  16. melvin-bot commented on Oct 29, 2026

    @melvin-bot

    @Krishna2323 / @daledah

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.24-8 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

    If no regressions arise, payment will be issued on 2026-11-05. 🎊

    The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]

  17. daledah commented on Oct 29, 2026

    @daledah
    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.

      Link to the comment on the PR: N/A, improvement

    • [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.

    Regression Test Proposal

    Precondition:

    Test:

    1. Go to Spend > Expenses and click Filters.

    2. Verify Keyword is the last row in the Core section, right after Workspace if it is shown.

    3. Verify the filters appear in this order:

      • Core: Core filters, including Workspace and Keyword
      • Details: Amount, Currency, Date, etc.
      • Card transactions: Card, Feed, Posted, etc.
      • Report fields: Report ID, Report field, Custom field 1, Custom field 2
      • Report actions: Submitted, Rejected, Held, Approved, Any approval, Paid, Paid by
      • Exports: Exported, Exported to
      • Withdrawals
    4. Use an account with no cards. Verify the Card transactions section is hidden and there are no consecutive dividers.

    5. Change Type to Invoice. Verify:

      • The date filter is labelled Created date.
      • Total, Title, and Report ID no longer appear with the report action dates.
    6. Type paid in the search input. Verify only Paid and Paid by appear, each in its own section.

    7. Type xyz. Verify No results found appears and the right pane is empty (web only).

    8. Clear the search input. Verify the full filter list returns.

    9. On a narrow layout, open Filters, type paid, open Paid, then go back. Verify paid remains in the search input.

    10. Verify that no errors appear in the JS console.

    Do we agree 👍 or 👎

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

Metadata

Metadata

Labels

ImprovementItem broken or needs improvement.InternalRequires API changes or must be handled by Expensify staffWeeklyKSv2

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions