You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[$175] Improvement: Reorder "Bank address" and "Bank city" inputs #104561
Version Number: 9.5.15-1 Reproducible in staging?: Y Reproducible in production?: Y If this was caught during regression testing, add the test name, ID and link from BrowserStack: Email or phone of affected tester (no customers): Logs:https://stackoverflow.com/c/expensify/questions/4856 Expensify/Expensify Issue URL: Issue reported by:@Eskalifer1 Slack conversation (hyperlinked to channel name): #Expensify Bugs
Action Performed:
Create a workspace with EUR as its currency.
Go to Workflows > Payments > Add bank account > Connect manually.
Select any country (e.g., Croatia) and click Confirm.
Observe the order of the inputs in the second step.
Expected Result:
Bank address field first. Reorder the Bank address and Bank city inputs so that Bank address appears first.
Actual Result:
Bank city field first, This creates unnecessary work because, in most cases, users wouldn't need to enter the city separately if they selected the bank address first. Additionally, the automatically populated value may overwrite a city they have already entered, forcing them to review or correct it.
Workaround:
Unknown
Platforms:
Select the officially supported platforms where the issue was reproduced:
BankAccountDetails renders corpayFields.formFields in the order the GetCorpayBankAccountFields API returns them. It never sorts them. For this country/currency, the backend lists bankCity before bankAddressLine1. Picking an address in the Bank address search fills in bankCity automatically, so a city the user already typed gets overwritten.
The personal wallet version of this page already sorts the fields by CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS, where bankAddressLine1 comes before bankCity. The workspace flow is missing that sort.
What changes do you think we should make in order to solve the problem?
In BankAccountDetails.tsx, reorder the fields that appear in CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS into that list's order. Leave every other field (account number, SWIFT, and so on) in its original slot. Put the sorted bank-info fields back into the slots those fields held before. This puts Bank address before Bank city for every country, whatever order the backend sends.
Don't copy the personal page's comparator as-is. On this page, fields outside the list get indexOf = -1, so that comparator would move them to the top.
Optional: put the logic in a small util under NonUSD/utils/. Reuse it in Confirmation.tsx:34 so the summary uses the same order.
Add a unit test for the util.
What alternative solutions did you explore? (Optional)
Change the field order on the backend. That fixes every client, but the fix is outside the App repo. Your App-side sort fixes the issue on its own.
Stop the address search from overwriting a city the user already entered. This fixes the overwrite but leaves the odd order in place.
I found the root cause in the code. I didn't reproduce it in the app.
Next Steps for Contributor+ team: To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/104561) to create a draft PR. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
VERDICT: POST
ROOT_CAUSE_ONELINER: The BankAccountDetails component renders corpayFields.formFields in the raw API-returned order, and for countries like Croatia the API places bankCity before bankAddressLine1, despite CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS defining the correct order (address before city).
PROPOSAL_TYPE: FIRST
AUTOPOST_SAFE: YES
changed the title [-]Improvement: Reorder "Bank address" and "Bank city" inputs[/-][+][$175] Improvement: Reorder "Bank address" and "Bank city" inputs[/+]on Oct 21, 2026
Please re-state the problem that we are trying to solve in this issue.
In the workspace "Add bank account" manual setup flow for certain country/currency combinations (e.g., EUR and Croatia), "Bank city" renders above "Bank address". Selecting an address in the address search overwrites an already filled city field. "Bank address" must render before "Bank city".
What is the root cause of that problem?
BankAccountDetails renders corpayFields.formFields directly in the array order returned by the GetCorpayBankAccountFields API without applying deterministic UI field sorting.
What changes do you think we should make in order to solve the problem?
Sort corpayFields.formFields prior to rendering in src/pages/workspace/expensifyCard/BankAccountDetails.tsx using the pre-defined priority array in CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.
Create a shallow copy of the form fields array before sorting to prevent mutating props/state directly:
// src/pages/workspace/expensifyCard/BankAccountDetails.tsximportCONSTfrom'@src/CONST';// Within the component render logic prior to rendering inputs:constsortedFormFields=useMemo(()=>{if(!corpayFields?.formFields){return[];}return[...corpayFields.formFields].sort((a,b)=>{constindexA=CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.indexOf(a.name);constindexB=CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.indexOf(b.name);if(indexA!==-1&&indexB!==-1){returnindexA-indexB;}if(indexA!==-1){return-1;}if(indexB!==-1){return1;}return0;});},[corpayFields?.formFields]);
Replace iteration over corpayFields.formFields with sortedFormFields in the JSX output.
What alternative solutions did you explore? (Optional)
None. Sorting on the client side using existing application constants mirrors the established behavior of the personal bank account flow.
In src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx, bankAccountDetailsFields is corpayFields?.formFields?.filter(...) and inputs is a plain .map over it, so the inputs follow the order the Corpay API returns. For Croatia that order lists bankCity before bankAddressLine1. The Bank address input is an AddressSearch with renamedInputKeys={{city: 'bankCity'}}, so picking an address overwrites a city the user already typed. The personal-wallet page (InternationalDepositAccount/subPages/BankInformation.tsx) avoids this by sorting with CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.indexOf(...). The workspace flow has no sort.
What changes do you think we should make in order to solve the problem?
Add a small helper putAddressBeforeCity(fields) (for example in NonUSD/utils/). It finds the indexes of bankAddressLine1 and bankCity. If bankCity comes first, it returns a copy with those two entries swapped. Otherwise it returns the fields unchanged. Every other field keeps its slot, and it is a no-op for countries that don't return both fields.
In BankAccountDetails.tsx, wrap the filter result: const bankAccountDetailsFields = putAddressBeforeCity(corpayFields?.formFields?.filter(...) ?? []). fieldIds and subStepKeys derive from it, so nothing else changes.
Apply the same helper to formFields in Confirmation.tsx (summaryItems) so the summary matches the form order.
Unit test for the helper: [bankCity, bankAddressLine1, swift] gives [bankAddressLine1, bankCity, swift]. Already-correct order, a missing field and an empty array come back unchanged.
What alternative solutions did you explore? (Optional)
MelvinBot (same root cause): sorts all BANK_INFORMATION_FIELDS members back into their original slots. That is more code than the issue needs, and it needs a careful comparator, because indexOf returns -1 for fields outside the list and a comparator copied from the wallet page would move them to the top. Swapping the two named fields is smaller and cannot reorder anything else.
Reuse the wallet page's .sort(...) comparator as is: this would shuffle account number and SWIFT fields to the top, so I rejected it.
Stop AddressSearch from overwriting an existing city: this fixes the overwrite but not the order the issue asks for.
Change the order on the backend: it is outside the App repo.
I read the code but did not reproduce it in the app.
Please re-state the problem that we are trying to solve in this issue.
In the workspace "Add bank account" manual setup flow for certain country/currency combinations (e.g. Croatia/EUR), "Bank city" renders above "Bank address". Selecting an address in the address search then overwrites a city the user may have already entered, creating unnecessary rework.
What is the root cause of that problem?
In src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx, the form fields are rendered in the raw array order returned by the GetCorpayBankAccountFields API: bankAccountDetailsFields is built by filtering corpayFields.formFields (line 42) and mapped straight into inputs (line 87) with no client-side ordering, so field order is whatever the API happens to return for that country/currency combo. Additionally, fields whose id is in CONST.CORPAY_FIELDS.SPECIAL_LIST_ADDRESS_KEYS render as an AddressSearch input (lines 29-33) with renamedInputKeys mapping city to bankCity (lines 107-111), which auto-populates the city when an address is selected - clobbering any city already entered when the city field sits above.
What changes do you think we should make in order to solve the problem?
Deterministically order bankAccountDetailsFields before rendering so the address-search field(s) come before the city field, on a shallow copy of the array so corpayFields is never mutated. Unknown/new field ids keep their API order (stable fallback). The validate loop iterates the fields order-independently, so no change is needed there.
What alternative solutions did you explore?
Sorting keyed off a hardcoded constant priority list for the whole form - rejected, because the field set is country-dependent (API-driven) and a priority list would silently break ordering for combos not in the list. Ordering keyed on the existing SPECIAL_LIST_ADDRESS_KEYS grouping (address fields before plain text fields) generalizes to all country/currency combos.
I will verify with the issue's exact repro (EUR workspace, manual bank connect, Croatia): Bank address renders above Bank city, selecting an address auto-populates street + city without clobbering a manually entered city, required-field validation still fires regardless of field order, and draft persistence across steps is unchanged. I will also spot-check a second country combo to confirm no ordering regression.
Please re-state the problem that we are trying to solve in this issue.
In the workspace manual bank account setup flow for non-USD currencies (e.g., EUR and Croatia), on the "What are your bank details?" step (BankAccountDetails), the "Bank city" field renders above "Bank address". Because "Bank address" uses AddressSearch with renamedInputKeys={{city: 'bankCity'}}, selecting an address automatically populates the city, overwriting whatever city the user may have already entered and forcing unnecessary rework.
What is the root cause of that problem?
In src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx (lines 42, 87), bankAccountDetailsFields is constructed by filtering corpayFields?.formFields:
It renders fields directly in the raw order returned by the Corpay GetCorpayBankAccountFields API without any deterministic UI ordering. For certain countries (such as Croatia with EUR), the Corpay API lists bankCity before bankAddressLine1.
Because bankAddressLine1 is recognized as a special address key (CONST.CORPAY_FIELDS.SPECIAL_LIST_ADDRESS_KEYS.includes(field.id)), it renders an <AddressSearch> component configured with:
Selecting an address in AddressSearch automatically updates both bankAddressLine1 and bankCity. Having bankCity positioned above bankAddressLine1 creates unnecessary friction and overwrites pre-filled user input.
In contrast, the personal wallet flow (src/pages/settings/Wallet/InternationalDepositAccount/subPages/BankInformation.tsx:95 and Confirmation.tsx:137) explicitly enforces canonical ordering using CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS:
The non-USD workspace flow currently lacks this canonical sorting.
What changes do you think we should make in order to solve the problem?
Create utility helper sortBankInformationFields:
Create src/pages/ReimbursementAccount/NonUSD/utils/sortBankInformationFields.ts that orders all bank information fields according to the canonical sequence in CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS, while preserving the exact relative positions of non-bank-information fields (e.g., IBAN, accountNumber):
importCONSTfrom'@src/CONST';importtype{CorpayFormField}from'@src/types/onyx';/** * Sorts bank information fields according to the canonical order defined in CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS * while preserving the positions of non-bank-information fields. */functionsortBankInformationFields(fields: CorpayFormField[]): CorpayFormField[]{constbankInfoIndices: number[]=[];constbankInfoFields: CorpayFormField[]=[];fields.forEach((field,index)=>{if(CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.includes(field.id)){bankInfoIndices.push(index);bankInfoFields.push(field);}});bankInfoFields.sort((a,b)=>CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.indexOf(a.id)-CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.indexOf(b.id));constresult=[...fields];bankInfoIndices.forEach((originalIndex,i)=>{result[originalIndex]=bankInfoFields[i];});returnresult;}exportdefaultsortBankInformationFields;
Sort fields in BankAccountDetails.tsx:
In src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx:
Unrelated fields (such as IBAN) maintain their original relative slots.
Returns empty or unchanged arrays when no bank info fields are present.
What alternative solutions did you explore? (Optional)
Hardcoding a two-field swap between bankCity and bankAddressLine1: Brittle and fails if bankAddressLine2, bankRegion, or bankPostal are also returned out of sequence. Utilizing the established CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS constant ensures all address fields adhere to canonical order.
Sorting the entire array directly via .sort((a, b) => indexOf(a.id) - indexOf(b.id)): Rejected because indexOf returns -1 for account details (e.g., IBAN), which would unintentionally shift non-address fields to the top. The proposed slot-replacement strategy cleanly sorts bank info fields in-place without altering non-bank fields.
Please re-state the problem that we are trying to solve in this issue.
In the Add Bank Account manual setup flow for non-USD accounts (e.g. workspace with EUR currency and selecting Croatia), the "Bank city" field appears before the "Bank address" field. When a user enters the city first and then selects their bank address via AddressSearch, the auto-populated city overwrites the previously entered value.
What is the root cause of that problem?
In src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx:39: bankAccountDetailsFields extracts form fields directly from corpayFields?.formFields:
It renders them in whatever arbitrary order the Corpay API returns. For countries like Croatia, the API lists bankCity before bankAddressLine1.
In contrast, src/pages/settings/Wallet/InternationalDepositAccount/subPages/BankInformation.tsx:82-84 already standardizes the field order by sorting against CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS:
Where CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS defines: ['bankName', 'bankAddressLine1', 'bankAddressLine2', 'bankCity', 'bankRegion', 'bankPostal', 'BeneficiaryBankBranchName']. BankAccountDetails.tsx does not sort bankAccountDetailsFields, causing the input order to drift based on raw API responses.
What changes do you think we should make in order to solve the problem?
In src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx:39:
Sort bankAccountDetailsFields using CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS:
This guarantees consistent field ordering across all countries: bankAddressLine1 will always precede bankCity.
What alternative solutions did you explore? (Optional)
Hardcoding a swap for bankAddressLine1 and bankCity: Rejected because reusing CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS matches the existing implementation in BankInformation.tsx and ensures all bank information fields follow the identical canonical order.
Testing
Create a workspace with EUR currency.
Navigate to Workflows > Payments > Add bank account > Connect manually.
Select Croatia and confirm.
On the Bank Information step, verify that "Bank address" is displayed before "Bank city".
Use AddressSearch to select an address and verify that the city autocompletes seamlessly without user disruption.
Please re-state the problem that we are trying to solve in this issue.
In the workspace manual bank account flow for non-USD currencies (e.g. a EUR workspace with Croatia), the "What are your bank details?" step shows "Bank city" above "Bank address". "Bank address" is an address-search input, and picking a suggestion also fills in the city. If the user has already typed a city, it gets overwritten. "Bank address" should come before "Bank city".
What is the root cause of that problem?
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx builds bankAccountDetailsFields by filtering corpayFields?.formFields and maps the result straight into inputs. Nothing sorts it, so the UI follows whatever order the GetCorpayBankAccountFields API returns. For Croatia/EUR the backend returns bankCity before bankAddressLine1.
The bankAddressLine1 input renders as AddressSearch with renamedInputKeys={{street: 'bankAddressLine1', city: 'bankCity', country: ''}}. Selecting a suggestion therefore writes bankCity and clobbers a manually entered city.
The personal wallet page (InternationalDepositAccount/subPages/BankInformation.tsx) already sorts by CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS, which lists bankAddressLine1 before bankCity. The workspace flow never got this sort.
What changes do you think we should make in order to solve the problem?
Add a utilsrc/pages/ReimbursementAccount/NonUSD/utils/sortBankInformationFields.ts.
It takes a list of Corpay form fields and returns a new array. It never mutates the input, because the input comes from Onyx.
It collects the fields whose id is in CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS, along with the indexes they occupy.
It sorts those fields by their position in the constant.
It writes them back into the same slots. Account number, IBAN, SWIFT and all other fields keep their original positions.
fieldIds, subStepKeys, the validation loop and the inputs map all derive from this list. They need no other change.
Use it in Confirmation.tsx for the formFields that feed summaryItems, so the summary order matches the form.
Do not copy the wallet page's comparator as-is. Fields outside the constant get indexOf = -1, so that comparator would move account number and SWIFT fields to the top. The slot-replacement approach avoids this.
What alternative solutions did you explore? (Optional)
Sort the whole array with indexOf or a "-1 goes last" comparator. This moves account and SWIFT fields relative to the bank-info fields, which changes the layout for other countries. I rejected it.
Swap only bankCity and bankAddressLine1. This is smaller, but it is brittle. It does not fix bankAddressLine2, bankRegion or bankPostal if they arrive out of order, and it ignores the existing canonical constant.
Sort by SPECIAL_LIST_ADDRESS_KEYS or a new priority list. This adds a second source of truth next to BANK_INFORMATION_FIELDS.
Stop AddressSearch from overwriting an existing city. This fixes the overwrite but leaves the order the issue asks to change.
Change the order on the backend. This is outside the App repo, and the client-side fix works on its own.
Testing
Unit tests (tests/unit/sortBankInformationFieldsTest.ts):
📣 @Abdallah-1551! 📣
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:
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>
🤖 Draft PR created: #104679
Please mark it as "Ready for review" or ask me to do that for you when it is ready for review.
The PR puts Bank address before Bank city on the bank details step and on the confirmation summary. Other fields, such as IBAN and SWIFT, keep their positions.
What changed and what was tested
New helper sortBankInformationFields.ts sorts the bank information fields by CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS. The sorted fields go back into the slots they held.
BankAccountDetails.tsx and Confirmation.tsx use the helper.
New unit tests pass, along with 8 related suites (58 tests), typecheck, lint, the React Compiler check, and spell check.
I couldn't check the UI in a browser. The test browser showed a blank page on both tries, which is an environment problem. Please check the Croatia/EUR flow by hand.
Activity
MelvinBot commentedon Oct 21, 2026
Proposal
What is the root cause of that problem?
BankAccountDetailsrenderscorpayFields.formFieldsin the order theGetCorpayBankAccountFieldsAPI returns them. It never sorts them. For this country/currency, the backend listsbankCitybeforebankAddressLine1. Picking an address in the Bank address search fills inbankCityautomatically, so a city the user already typed gets overwritten.The personal wallet version of this page already sorts the fields by
CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS, wherebankAddressLine1comes beforebankCity. The workspace flow is missing that sort.Code references
BankAccountDetails.tsx:42,:87bankCitywhen you pick a suggestion:BankAccountDetails.tsx:107-111InternationalDepositAccount/subPages/BankInformation.tsx:94-95CONST/index.ts:9515formFieldsas returned, with no ordering:BankAccounts.ts:884-925What changes do you think we should make in order to solve the problem?
BankAccountDetails.tsx, reorder the fields that appear inCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDSinto that list's order. Leave every other field (account number, SWIFT, and so on) in its original slot. Put the sorted bank-info fields back into the slots those fields held before. This puts Bank address before Bank city for every country, whatever order the backend sends.indexOf = -1, so that comparator would move them to the top.NonUSD/utils/. Reuse it inConfirmation.tsx:34so the summary uses the same order.What alternative solutions did you explore? (Optional)
Possibly related
I found the root cause in the code. I didn't reproduce it in the app.
Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/104561)to create a draft PR.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
view run
j3ffffff commentedon Oct 21, 2026
VERDICT: POST
ROOT_CAUSE_ONELINER: The
BankAccountDetailscomponent renderscorpayFields.formFieldsin the raw API-returned order, and for countries like Croatia the API placesbankCitybeforebankAddressLine1, despiteCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDSdefining the correct order (address before city).PROPOSAL_TYPE: FIRST
AUTOPOST_SAFE: YES
melvin-bot commentedon Oct 21, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @marufsharifi (
External)[-]Improvement: Reorder "Bank address" and "Bank city" inputs[/-][+][$175] Improvement: Reorder "Bank address" and "Bank city" inputs[/+]melvin-bot commentedon Oct 21, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022112862969074386381
camesenin commentedon Oct 21, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
In the workspace "Add bank account" manual setup flow for certain country/currency combinations (e.g., EUR and Croatia), "Bank city" renders above "Bank address". Selecting an address in the address search overwrites an already filled city field. "Bank address" must render before "Bank city".
What is the root cause of that problem?
BankAccountDetailsrenderscorpayFields.formFieldsdirectly in the array order returned by theGetCorpayBankAccountFieldsAPI without applying deterministic UI field sorting.What changes do you think we should make in order to solve the problem?
Sort
corpayFields.formFieldsprior to rendering insrc/pages/workspace/expensifyCard/BankAccountDetails.tsxusing the pre-defined priority array inCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.Create a shallow copy of the form fields array before sorting to prevent mutating props/state directly:
Replace iteration over
corpayFields.formFieldswithsortedFormFieldsin the JSX output.What alternative solutions did you explore? (Optional)
None. Sorting on the client side using existing application constants mirrors the established behavior of the personal bank account flow.
Contributor details
Your Expensify account email: [email protected]
Upwork Profile Link: https://www.upwork.com/freelancers/~01b60d704ba377be83
melvin-bot commentedon Oct 21, 2026
✅ Contributor details stored successfully. Thank you for contributing to Expensify!
Stephen3453 commentedon Oct 21, 2026
Proposal
What is the root cause of that problem?
In
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx,bankAccountDetailsFieldsiscorpayFields?.formFields?.filter(...)andinputsis a plain.mapover it, so the inputs follow the order the Corpay API returns. For Croatia that order listsbankCitybeforebankAddressLine1. The Bank address input is anAddressSearchwithrenamedInputKeys={{city: 'bankCity'}}, so picking an address overwrites a city the user already typed. The personal-wallet page (InternationalDepositAccount/subPages/BankInformation.tsx) avoids this by sorting withCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS.indexOf(...). The workspace flow has no sort.What changes do you think we should make in order to solve the problem?
putAddressBeforeCity(fields)(for example inNonUSD/utils/). It finds the indexes ofbankAddressLine1andbankCity. IfbankCitycomes first, it returns a copy with those two entries swapped. Otherwise it returns the fields unchanged. Every other field keeps its slot, and it is a no-op for countries that don't return both fields.BankAccountDetails.tsx, wrap the filter result:const bankAccountDetailsFields = putAddressBeforeCity(corpayFields?.formFields?.filter(...) ?? []).fieldIdsandsubStepKeysderive from it, so nothing else changes.formFieldsinConfirmation.tsx(summaryItems) so the summary matches the form order.[bankCity, bankAddressLine1, swift]gives[bankAddressLine1, bankCity, swift]. Already-correct order, a missing field and an empty array come back unchanged.What alternative solutions did you explore? (Optional)
BANK_INFORMATION_FIELDSmembers back into their original slots. That is more code than the issue needs, and it needs a careful comparator, becauseindexOfreturns -1 for fields outside the list and a comparator copied from the wallet page would move them to the top. Swapping the two named fields is smaller and cannot reorder anything else..sort(...)comparator as is: this would shuffle account number and SWIFT fields to the top, so I rejected it.AddressSearchfrom overwriting an existing city: this fixes the overwrite but not the order the issue asks for.I read the code but did not reproduce it in the app.
khizzcr7 commentedon Oct 21, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
In the workspace "Add bank account" manual setup flow for certain country/currency combinations (e.g. Croatia/EUR), "Bank city" renders above "Bank address". Selecting an address in the address search then overwrites a city the user may have already entered, creating unnecessary rework.
What is the root cause of that problem?
In
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx, the form fields are rendered in the raw array order returned by theGetCorpayBankAccountFieldsAPI:bankAccountDetailsFieldsis built by filteringcorpayFields.formFields(line 42) and mapped straight into inputs (line 87) with no client-side ordering, so field order is whatever the API happens to return for that country/currency combo. Additionally, fields whose id is inCONST.CORPAY_FIELDS.SPECIAL_LIST_ADDRESS_KEYSrender as anAddressSearchinput (lines 29-33) withrenamedInputKeysmappingcitytobankCity(lines 107-111), which auto-populates the city when an address is selected - clobbering any city already entered when the city field sits above.What changes do you think we should make in order to solve the problem?
Deterministically order
bankAccountDetailsFieldsbefore rendering so the address-search field(s) come before the city field, on a shallow copy of the array socorpayFieldsis never mutated. Unknown/new field ids keep their API order (stable fallback). Thevalidateloop iterates the fields order-independently, so no change is needed there.What alternative solutions did you explore?
Sorting keyed off a hardcoded constant priority list for the whole form - rejected, because the field set is country-dependent (API-driven) and a priority list would silently break ordering for combos not in the list. Ordering keyed on the existing
SPECIAL_LIST_ADDRESS_KEYSgrouping (address fields before plain text fields) generalizes to all country/currency combos.I will verify with the issue's exact repro (EUR workspace, manual bank connect, Croatia): Bank address renders above Bank city, selecting an address auto-populates street + city without clobbering a manually entered city, required-field validation still fires regardless of field order, and draft persistence across steps is unchanged. I will also spot-check a second country combo to confirm no ordering regression.
sijo0218 commentedon Oct 21, 2026
Contributor details
Your Expensify account email: [email protected]
Upwork Profile Link: https://www.upwork.com/freelancers/~011091133bbb09cd1c
Proposal
Please re-state the problem that we are trying to solve in this issue.
In the workspace manual bank account setup flow for non-USD currencies (e.g., EUR and Croatia), on the "What are your bank details?" step (
BankAccountDetails), the "Bank city" field renders above "Bank address". Because "Bank address" usesAddressSearchwithrenamedInputKeys={{city: 'bankCity'}}, selecting an address automatically populates the city, overwriting whatever city the user may have already entered and forcing unnecessary rework.What is the root cause of that problem?
In
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx(lines 42, 87),bankAccountDetailsFieldsis constructed by filteringcorpayFields?.formFields:It renders fields directly in the raw order returned by the Corpay
GetCorpayBankAccountFieldsAPI without any deterministic UI ordering. For certain countries (such as Croatia with EUR), the Corpay API listsbankCitybeforebankAddressLine1.Because
bankAddressLine1is recognized as a special address key (CONST.CORPAY_FIELDS.SPECIAL_LIST_ADDRESS_KEYS.includes(field.id)), it renders an<AddressSearch>component configured with:Selecting an address in
AddressSearchautomatically updates bothbankAddressLine1andbankCity. HavingbankCitypositioned abovebankAddressLine1creates unnecessary friction and overwrites pre-filled user input.In contrast, the personal wallet flow (
src/pages/settings/Wallet/InternationalDepositAccount/subPages/BankInformation.tsx:95andConfirmation.tsx:137) explicitly enforces canonical ordering usingCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS:The non-USD workspace flow currently lacks this canonical sorting.
What changes do you think we should make in order to solve the problem?
sortBankInformationFields:Create
src/pages/ReimbursementAccount/NonUSD/utils/sortBankInformationFields.tsthat orders all bank information fields according to the canonical sequence inCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS, while preserving the exact relative positions of non-bank-information fields (e.g.,IBAN,accountNumber):BankAccountDetails.tsx:In
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx:Confirmation.tsx:In
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/Confirmation.tsx:This ensures the Confirmation review summary reflects the exact same field order as the input step.
Add comprehensive unit tests in
tests/unit/sortBankInformationFieldsTest.tsvalidating:bankAddressLine1is ordered beforebankCitywhen Corpay returns them in reverse.bankName->bankAddressLine1->bankAddressLine2->bankCity->bankRegion->bankPostal.IBAN) maintain their original relative slots.What alternative solutions did you explore? (Optional)
bankCityandbankAddressLine1: Brittle and fails ifbankAddressLine2,bankRegion, orbankPostalare also returned out of sequence. Utilizing the establishedCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDSconstant ensures all address fields adhere to canonical order..sort((a, b) => indexOf(a.id) - indexOf(b.id)): Rejected becauseindexOfreturns-1for account details (e.g.,IBAN), which would unintentionally shift non-address fields to the top. The proposed slot-replacement strategy cleanly sorts bank info fields in-place without altering non-bank fields.bonnhatnguyen commentedon Oct 21, 2026
Contributor details
Your Expensify account email: [email protected]
Upwork Profile Link: https://www.upwork.com/freelancers/~0139ed4098bdc50182
Proposal
Please re-state the problem that we are trying to solve in this issue.
In the Add Bank Account manual setup flow for non-USD accounts (e.g. workspace with EUR currency and selecting Croatia), the "Bank city" field appears before the "Bank address" field. When a user enters the city first and then selects their bank address via AddressSearch, the auto-populated city overwrites the previously entered value.
What is the root cause of that problem?
In
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx:39:bankAccountDetailsFieldsextracts form fields directly fromcorpayFields?.formFields:It renders them in whatever arbitrary order the Corpay API returns. For countries like Croatia, the API lists
bankCitybeforebankAddressLine1.In contrast,
src/pages/settings/Wallet/InternationalDepositAccount/subPages/BankInformation.tsx:82-84already standardizes the field order by sorting againstCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS:Where
CONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDSdefines:['bankName', 'bankAddressLine1', 'bankAddressLine2', 'bankCity', 'bankRegion', 'bankPostal', 'BeneficiaryBankBranchName'].BankAccountDetails.tsxdoes not sortbankAccountDetailsFields, causing the input order to drift based on raw API responses.What changes do you think we should make in order to solve the problem?
In
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsx:39:Sort
bankAccountDetailsFieldsusingCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS:This guarantees consistent field ordering across all countries:
bankAddressLine1will always precedebankCity.What alternative solutions did you explore? (Optional)
bankAddressLine1andbankCity: Rejected because reusingCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDSmatches the existing implementation inBankInformation.tsxand ensures all bank information fields follow the identical canonical order.Testing
melvin-bot commentedon Oct 21, 2026
✅ Contributor details stored successfully. Thank you for contributing to Expensify!
Abdallah-1551 commentedon Oct 22, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
In the workspace manual bank account flow for non-USD currencies (e.g. a EUR workspace with Croatia), the "What are your bank details?" step shows "Bank city" above "Bank address". "Bank address" is an address-search input, and picking a suggestion also fills in the city. If the user has already typed a city, it gets overwritten. "Bank address" should come before "Bank city".
What is the root cause of that problem?
src/pages/ReimbursementAccount/NonUSD/BankInfo/subSteps/BankAccountDetails.tsxbuildsbankAccountDetailsFieldsby filteringcorpayFields?.formFieldsand maps the result straight into inputs. Nothing sorts it, so the UI follows whatever order theGetCorpayBankAccountFieldsAPI returns. For Croatia/EUR the backend returnsbankCitybeforebankAddressLine1.The
bankAddressLine1input renders asAddressSearchwithrenamedInputKeys={{street: 'bankAddressLine1', city: 'bankCity', country: ''}}. Selecting a suggestion therefore writesbankCityand clobbers a manually entered city.The personal wallet page (
InternationalDepositAccount/subPages/BankInformation.tsx) already sorts byCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS, which listsbankAddressLine1beforebankCity. The workspace flow never got this sort.What changes do you think we should make in order to solve the problem?
src/pages/ReimbursementAccount/NonUSD/utils/sortBankInformationFields.ts.idis inCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS, along with the indexes they occupy.BankAccountDetails.tsx. Wrap the filtered list:fieldIds,subStepKeys, the validation loop and theinputsmap all derive from this list. They need no other change.Use it in
Confirmation.tsxfor theformFieldsthat feedsummaryItems, so the summary order matches the form.Do not copy the wallet page's comparator as-is. Fields outside the constant get
indexOf = -1, so that comparator would move account number and SWIFT fields to the top. The slot-replacement approach avoids this.What alternative solutions did you explore? (Optional)
indexOfor a "-1 goes last" comparator. This moves account and SWIFT fields relative to the bank-info fields, which changes the layout for other countries. I rejected it.bankCityandbankAddressLine1. This is smaller, but it is brittle. It does not fixbankAddressLine2,bankRegionorbankPostalif they arrive out of order, and it ignores the existing canonical constant.SPECIAL_LIST_ADDRESS_KEYSor a new priority list. This adds a second source of truth next toBANK_INFORMATION_FIELDS.AddressSearchfrom overwriting an existing city. This fixes the overwrite but leaves the order the issue asks to change.Testing
Unit tests (
tests/unit/sortBankInformationFieldsTest.ts):[bankCity, bankAddressLine1, swift]returns[bankAddressLine1, bankCity, swift].bankName,bankAddressLine1,bankAddressLine2,bankCity,bankRegion,bankPostal.IBAN,accountNumber) keep their original slots when interleaved with bank fields.Manual:
melvin-bot commentedon Oct 22, 2026
📣 @Abdallah-1551! 📣
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:
Format:
marufsharifi commentedon Oct 22, 2026
@MelvinBot Implement this
MelvinBot commentedon Oct 22, 2026
🤖 Draft PR created: #104679
Please mark it as "Ready for review" or ask me to do that for you when it is ready for review.
The PR puts Bank address before Bank city on the bank details step and on the confirmation summary. Other fields, such as IBAN and SWIFT, keep their positions.
What changed and what was tested
sortBankInformationFields.tssorts the bank information fields byCONST.CORPAY_FIELDS.BANK_INFORMATION_FIELDS. The sorted fields go back into the slots they held.BankAccountDetails.tsxandConfirmation.tsxuse the helper.