Repository navigation
[$175] Expensify card - Sorting/display options are missing on Expensify card page #103578
Description
Activity
- addedDailyKSv2KSv2BugSomething is broken. Auto assigns a BugZero manager.Something is broken. Auto assigns a BugZero manager.
on Oct 9, 2026 While Applause doesn't embed attachments for this bug, here are the links for quick view:
https://platform.applause.com/services/links/v1/external/112a031584392603f8ca6488d8a161c94ee10f555e30c5706a9c472d2ea6743aProposal
What is the root cause of that problem?
The Expensify Card table locks its narrow-layout sort to cardholder name with
narrowLayoutSortColumn="name"(WorkspaceExpensifyCardsTable/index.tsx:332). When a table locks its sort, the shared Table component ignores user sorting on narrow layouts and hides the Display button on purpose (TableDisplaySettingsTrigger.tsx:32-37).This isn't Android-specific and isn't a recent regression. The lock came from Update the policy expensify card table to the new style (merged 2026-06-29). The hide rule came from [Payment due @ChavdaSachin] Add bulk actions for company cards (merged 2026-07-29).
What changes do you think we should make in order to solve the problem?
Remove
narrowLayoutSortColumn="name"fromWorkspaceExpensifyCardsTableand keepinitialSortColumn="name". This matches the Company Cards table. The Display (eye) button then shows on narrow layouts, user sorting works there, and the default order stays cardholder name ascending.What alternative solutions did you explore? (Optional)
Close as expected behavior.
TABLE.md:45documents hiding the button for tables with a locked narrow sort. Six other tables also lock it: Taxes, Distance rates, Per diem, Spend rules, Expense defaults, and Category rules. If the button should show on every table, change those six tables too.Investigation details
- The Display button comes from
Table.FilterBar, which the Expensify Card table mounts atWorkspaceExpensifyCardsTable/index.tsx:321. It doesn't come from the page's header buttons inWorkspaceExpensifyCardListPage.tsx. - On narrow layouts,
sorting.ts:107-111forces{narrowLayoutSortColumn, ASC}, so a sort control would do nothing. That's why the button is hidden. - Here "narrow" includes medium-width screens, so mWeb and narrow desktop windows behave the same way.
- The Filters button never shows for this table on any layout because the table has no
filterConfig. That part is expected. - I couldn't reproduce this live. Issuing an Expensify Card needs a verified bank account, which the web test account doesn't have. The page stayed on the "Get the Expensify Card" intro screen in both wide and narrow layouts.
Next Steps for Contributor+ team:
To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/103578)to create a draft PR.
To refine:@MelvinBot <your feedback>
To reject: Explain why you are rejecting Melvin's proposal.
- The Display button comes from
- addedExternalAdded to denote the issue can be worked on by a contributorAdded to denote the issue can be worked on by a contributor
on Oct 9, 2026 Triggered auto assignment to Contributor-plus team member for initial proposal review - @abzokhattab (
External)- changed the title
[-]Expensify card - Sorting/display options are missing on Expensify card page[/-][+][$175] Expensify card - Sorting/display options are missing on Expensify card page[/+]on Oct 9, 2026 Job added to Upwork: https://www.upwork.com/jobs/~022108511548304281222
Proposal
Edit (Oct 10): TABLE.md documents this behavior. The Display button is hidden on narrow layouts for tables that lock their sort:
App/contributingGuides/TABLE.md
Line 45 in 09f662a
`<Table.FilterBar>` renders a `Filters` button when the table has a filter config, and automatically renders a `Display` button (sort by column and order) for any table with at least one `sortable: true` column. The `Display` button is hidden on narrow layouts for tables that lock their sorting via `narrowLayoutSortColumn`, since user sorting is ignored there.
Removing the lock would change the Expensify Card table's narrow-layout behavior and needs confirmation that user-selected sorting is intended here. The same diagnosis and remove-lock change were already proposed by MelvinBot.Re-state problem
On the Workspace > Expensify Card page on a phone (Android app), the search row has no sort/display (eye) button. Company Cards shows the control; tables with a fixed narrow-layout sort hide it by design.
Root cause
The cards table passes
narrowLayoutSortColumn="name"toTable:
App/src/components/Tables/WorkspaceExpensifyCardsTable/index.tsx
Lines 331 to 332 in 6a1b74c
initialSortColumn="name" narrowLayoutSortColumn="name" shouldShowTableDisplaySettingsTriggertreats any table with anarrowLayoutSortColumnas "sorting locked on narrow layouts" and returns false:
// On narrow layouts, tables with a narrowLayoutSortColumn ignore user sorting entirely, so a sort control would be a no-op. function shouldShowTableDisplaySettingsTrigger({columns, shouldUseNarrowTableLayout, narrowLayoutSortColumn}: ShouldShowTableDisplaySettingsTriggerParams): boolean { const hasSortableColumns = columns.some((column) => column.sortable); const isSortingLockedByLayout = shouldUseNarrowTableLayout && !!narrowLayoutSortColumn; return hasSortableColumns && !isSortingLockedByLayout; } TableDisplaySettingsTriggerreturnsnullon that check, andTableFilterBaralso uses it to computeactionColumnVisible:
App/src/components/Table/TableFilterBar/index.tsx
Lines 32 to 33 in 6a1b74c
const showsDisplaySettingsTrigger = shouldShowTableDisplaySettingsTrigger({columns, shouldUseNarrowTableLayout, narrowLayoutSortColumn}); const actionColumnVisible = hasFiltersAvailable || showsDisplaySettingsTrigger || !!children; The cards table has no filters and passes no children, so the whole action column disappears on narrow screens. That is what the screenshot shows. The table has sortable columns (
sortable: trueon name, type, limit and so on), andcompareItemsalready handles all of them, so on narrow screens the lock removes sorting that would otherwise work.Changes to make
- In
src/components/Tables/WorkspaceExpensifyCardsTable/index.tsx, removenarrowLayoutSortColumn="name"from<Table>. KeepinitialSortColumn="name", so the default order is the same. - Then
shouldShowTableDisplaySettingsTriggerreturns true on narrow layouts, and the eye button opens the existing display/sort popover. No change to the shared Table code. - Before sending the PR I'll check that the narrow row (
WorkspaceExpensifyCardsTableRow) still renders fine with a user-chosen sort column.
Tests:
- Add a case to the existing Table tests (or a small one for
WorkspaceExpensifyCardsTable). With a narrow layout, the display settings button is rendered. Sorting by the selected column reorders the rows.
Alternatives
- Change
shouldShowTableDisplaySettingsTriggerto ignorenarrowLayoutSortColumn. That is a shared change, and it would show a no-op button on other tables that really are locked, so I'd rather fix the one table. - Leave the lock and add a separate sort control in the cards header. That duplicates the Table display popover.
- In
Proposal
Please re-state the problem that we are trying to solve in this issue.
On a narrow/mobile layout, the Workspace Expensify Cards table does not show the display/sorting control even though its columns support sorting.
What is the root cause of that problem?
WorkspaceExpensifyCardsTablesuppliesnarrowLayoutSortColumn="name", which locks the narrow-layout sort. The sharedTableDisplaySettingsTriggerintentionally hides the control when such a lock is present; with no other filter actions, the action area disappears.What changes do you think we should make in order to solve the problem?
Remove the narrow-layout sorting lock specifically from
WorkspaceExpensifyCardsTable, while keepinginitialSortColumn="name"to preserve the default order. This lets the existing table display/sort control render and avoids changing shared sorting behavior for unrelated tables.I'll add or update a narrow-layout regression test covering the control's visibility and user-selected sorting, and verify that desktop and default card ordering remain unchanged.
Contributor details
Your Expensify account email: gahoiraj01@gmail.com
Upwork Profile Link: https://www.upwork.com/freelancers/~01b77415f16d156068Proposal
Please re-state the problem that we are trying to solve in this issue.
On narrow/mobile screens (mWeb and mobile apps), the Workspace Expensify Cards page table does not display the display options / sorting button (the eye icon trigger) in the search filter bar, preventing users from selecting sort preferences on mobile.
What is the root cause of that problem?
In
src/components/Tables/WorkspaceExpensifyCardsTable/index.tsx(line 332):<Table data={cards} columns={columns} renderItem={renderCardItem} compareItems={compareItems} isItemInSearch={isItemInSearch} shouldUseDynamicColumns initialSortColumn="name" narrowLayoutSortColumn="name" ...
WorkspaceExpensifyCardsTablepassesnarrowLayoutSortColumn="name"to the shared<Table>component.- In
src/components/Table/TableFilterBar/TableDisplaySettingsTrigger.tsx(lines 32–37):if (isSortLockedOnNarrowLayout) { return null; }
isSortLockedOnNarrowLayoutis true whenevernarrowLayoutSortColumnis defined. This intentionally suppresses theTableDisplaySettingsTriggerpopover trigger on narrow viewports. - Because
WorkspaceExpensifyCardsTabledefines no custom filter actions or child controls inTableFilterBar,actionColumnVisibleevaluates tofalsewhen the display trigger returnsnull, causing the entire right-hand action column to vanish on narrow viewports. - However, the cards table has multiple sortable columns (e.g.
name,cardholder,limit, etc.) andcompareItemshandles dynamic ordering across all of them. Locking narrow layouts to"name"is unnecessary and improperly removes sorting capabilities that work seamlessly on wide viewports.
What changes do you think we should make in order to solve the problem?
In
src/components/Tables/WorkspaceExpensifyCardsTable/index.tsx:
RemovenarrowLayoutSortColumn="name"while retaininginitialSortColumn="name":<Table data={cards} columns={columns} renderItem={renderCardItem} compareItems={compareItems} isItemInSearch={isItemInSearch} shouldUseDynamicColumns initialSortColumn="name" - narrowLayoutSortColumn="name" title={translate('workspace.common.expensifyCard')}Verification & Blast Radius:
- Defaults remain unchanged: on first load across both wide and narrow viewports, cards sort by cardholder name ascending (
initialSortColumn="name"). - On narrow viewports,
isSortLockedOnNarrowLayoutevaluates tofalse, allowingTableDisplaySettingsTriggerto render the display options (eye icon) button. - Tapping the trigger opens the existing sort options popover, and selecting any sort column reorders the card list as expected via
compareItems. - The change is isolated strictly to
WorkspaceExpensifyCardsTableand does not affect other tables with intentional narrow layout locks (Taxes, Distance Rates, etc.).
What alternative solutions did you explore? (Optional)
- Modifying
shouldShowTableDisplaySettingsTriggerin the shared Table component: Undesirable blast radius because other workspace tables that deliberately fix narrow sorting to a single attribute would render an ineffectual display settings trigger. Removing the property directly fromWorkspaceExpensifyCardsTableis localized, clean, and follows the Company Cards table design pattern.
What specific scenarios should we cover in automated tests?
In
tests/unit/components/Tables/WorkspaceExpensifyCardsTableTest.tsx:- Verify that on narrow layouts (
shouldUseNarrowLayout: true), the display settings / sorting trigger button is visible inTable.FilterBar. - Verify that sorting by a selected column (e.g., limit, status) updates the order of rendered card rows.
- Verify that on wide viewports, initial sort order remains cardholder name ascending.
⚠️ Unable to store contributor detailsDetails
Auth SetContributorDetails returned an error 401 Contributor details already exist
Testing access
I reviewed the current card-table source and the existing proposals. The table still sets both initialSortColumn and narrowLayoutSortColumn to name. I have not reproduced the stated behavior in an authorized issued-card test fixture.
The contribution guide requires reproduction and Help Wanted before a proposal. Could a reviewer confirm whether this issue is available to new external contributors, and point to the approved sandbox setup or access process for a staging fixture with an issued card? No real card information, credentials or private access links are needed in this public thread.
This is an access clarification, not a proposal or an assignment claim. I would submit a materially distinct technical proposal only after satisfying those conditions, then begin implementation after acceptance and a funded contract.
📣 @theluckystrike! 📣
Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork.
Please follow these steps:- Make sure you've read and understood the contributing guidelines.
- Get the email address used to login to your Expensify account. If you don't already have an Expensify account, create one here. If you have multiple accounts (e.g. one for testing), please use your main account email.
- Get the link to your Upwork profile. It's necessary because we only pay via Upwork. You can access it by logging in, and then clicking on your name. It'll look like this. If you don't already have an account, sign up for one here.
- Copy the format below and paste it in a comment on this issue. Replace the placeholder text with your actual details.

Format:
Contributor details Your Expensify account email: <REPLACE EMAIL HERE> Upwork Profile Link: <REPLACE LINK HERE>This is documented, intentional behavior, not a regression. The Display button is hidden on narrow layouts for tables that lock their sort via
narrowLayoutSortColumn(TABLE.md).That said, only 7 out of 23 sortable tables in the app use this lock. The other 16 (including
WorkspaceCompanyCardsTable,WorkspaceCategoriesTable,WorkspaceTagsTable,WorkspaceMembersTable) show the Display button on narrow layouts and let users sort freely.@JS00001 you reviewed both the Expensify Cards table migration that added the lock and the shared Table PR that hides the button when the lock is set. Was this an intentional product choice for these specific tables, or should we remove the lock to match the majority behavior and be consistent? And if we remove it, should we do it for just this table or all 7 locked tables?
@yuvrajangadsingh @krsnak @RajGahoi Hey, just a heads up ... per the contributing guidelines, proposals posted before the
Help Wantedlabel is added won't be considered https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md#propose-a-solution-for-the-job .Proposals must only be posted after the Help Wanted label is added. Any proposals submitted beforehand will be ignored and not reviewed.
Please wait for the label before proposing.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
If you haven’t already, check out our contributing guidelines for onboarding. To join our Slack channel, fill out this form.
Version Number: 9.5.6-0
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from BrowserStack: https://test-management.browserstack.com/projects/2219752/test-runs/77775825/folder/13176890/143478625/1840292955
Email or phone of affected tester (no customers): applausetester+bm883847611@applause.expensifail.com
Issue reported by: Applause Internal Team
Bug source: Regression TC Execution
Device used: android
App Component: Workspace Settings
Action Performed:
Preconditions:
Expensify card issued
Expected Result:
Sorting/display buttons should be visible on the Expensify card page.
Actual Result:
Sorting/display buttons are missing on the Expensify card page.
Workaround:
Unknown
Platforms:
Screenshots/Videos
View all open jobs on GitHub
Upwork Automation - Do Not Edit