Skip to content

fix: bank account not shown after added to workspace until page refresh#79577

Merged
cead22 merged 7 commits intoExpensify:mainfrom
rohit9625:fix/BA-not-shown
Feb 6, 2026
Merged

fix: bank account not shown after added to workspace until page refresh#79577
cead22 merged 7 commits intoExpensify:mainfrom
rohit9625:fix/BA-not-shown

Conversation

@rohit9625
Copy link
Contributor

Explanation of Change

The bank account wasn't displayed when added to a Workspace because we were only adding two fields to the policy.achAccount optimistic data. So, I updated the setWorkspaceReimbursement function to add other fields to the achAccount that are required to show the added bank account right away, without waiting for the backend response. However, the backend is also updated by cead22 to return the achAccount field, and it will be deployed soon.

Fixed Issues

$ #78459
PROPOSAL: $ #78459 (comment)

Tests

Precondition: Create a workspace, at Workflows payments, add bank account Plaid Saving Ending in 1111

  1. Open the Expensify app
  2. Go to Workspaces
  3. Create a new workspace with currency USD
  4. Click on Workflows
  5. Click Add bank account
  6. Select the bank account ending in 1111 (it's the bank account mentioned in the pre-condition)
  7. Make sure that the added bank account displayed after loading indicator is resolved
  8. Try refreshing the page and make sure the added account is still visible
  • Verify that no errors appear in the JS console

Offline tests

None, we cannot add a bank account when offline, as the Add bank account button is disabled.

QA Steps

// TODO: These must be filled out, or the issue title must include "[No QA]."
Same as tests

  • 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 verified there are no new alerts related to the canBeMissing param for useOnyx
  • 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
Android_Native.mov
Android: mWeb Chrome
Android_Chrome.mov
iOS: Native
iOS_Native.mov
iOS: mWeb Safari
iOS_Safari.mov
MacOS: Chrome / Safari
Mac_Safari.mov

@rohit9625 rohit9625 requested review from a team as code owners January 14, 2026 14:34
@melvin-bot melvin-bot bot requested review from aimane-chnaif and heyjennahay and removed request for a team January 14, 2026 14:34
@melvin-bot
Copy link

melvin-bot bot commented Jan 14, 2026

@aimane-chnaif 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]

Copy link

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

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: b918155860

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

@codecov
Copy link

codecov bot commented Jan 14, 2026

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 Δ
...rkspace/ConnectExistingBusinessBankAccountPage.tsx 0.00% <ø> (ø)
src/libs/actions/Policy/Policy.ts 36.24% <0.00%> (-0.04%) ⬇️
...ges/workspace/workflows/WorkspaceWorkflowsPage.tsx 0.00% <0.00%> (ø)
... and 7 files with indirect coverage changes

@rohit9625
Copy link
Contributor Author

@codex review

Copy link

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

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: 8214a604c7

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

isLoadingWorkspaceReimbursement: true,
reimburser: reimburserEmail,
achAccount: {reimburser: reimburserEmail, bankAccountID},
achAccount: {reimburser: reimburserEmail, bankAccountID, accountNumber, addressName, bankName, state},

Choose a reason for hiding this comment

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

P2 Badge Avoid overwriting existing achAccount fields with undefined

This optimistic merge now always writes accountNumber, addressName, bankName, and state into policy.achAccount. Call sites like WorkspaceWorkflowsPage invoke setWorkspaceReimbursement without these fields, so the merge will overwrite existing values with undefined, and because the success payload doesn’t restore them (and the API response doesn’t yet return achAccount), the bank account details/last‑4 can disappear after toggling reimbursement until a full policy refresh. Consider only including these keys when defined or merging from the existing policy.achAccount to avoid wiping the data.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, @aimane-chnaif
I am pretty unsure about this one. Could you please help?

Copy link
Contributor

Choose a reason for hiding this comment

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

the API response doesn’t yet return achAccount

Genius or stupid? Bot already tested api response 😄

For safety, let's add those fields only when exist, instead of undefined

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What should we do if not exist? The bankAccountID already existed the same way without checking undefined.

Copy link
Contributor

Choose a reason for hiding this comment

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

We can skip this warning but instead please make sure to test workspace workflows page to confirm it doesn't cause any regression.

@rohit9625
Copy link
Contributor Author

Hi, @aimane-chnaif
I've tested this branch against the staging web app, and nothing breaks except this:

Screen.Recording.2026-01-14.at.9.52.18.PM.mov

However, the above behaviour is expected as we now add optimisticData which reflects even when offline. What should we do in that case?
Also, the Add the account button is disabled when offline but we can still try to add a bank account after forcing offline once the RHP is opened.

@rohit9625
Copy link
Contributor Author

Wait, I retested switching back to online after adding the BA when offline and the behavior on this branch looks more promising than staging or latest main.

Screen.Recording.2026-01-14.at.9.59.30.PM.mov

Also on staging, the Add bank account is shown breifly which doesn't happen on this branch. Apart from that, everything works fine and it's ready to review from my side. Let me know if you have any questions, @aimane-chnaif :)

@aimane-chnaif
Copy link
Contributor

Sounds good to me. Please merge main

@rohit9625
Copy link
Contributor Author

Done 👍

@aimane-chnaif
Copy link
Contributor

aimane-chnaif commented Jan 16, 2026

Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible 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 checked that screenshots or videos are included for tests on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified that the composer does not automatically focus or open the keyboard on mobile unless explicitly intended. This includes checking that returning the app from the background does not unexpectedly open the keyboard.
  • I verified tests pass on all platforms & I tested again on:
    • Android: HybridApp
    • Android: mWeb Chrome
    • iOS: HybridApp
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
    • MacOS: Desktop
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified there are no new alerts related to the canBeMissing param for useOnyx
  • I verified proper code patterns were followed (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
    • 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 verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • 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
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • 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 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.
  • For any bug fix or new feature in this PR, I verified that sufficient unit tests are included to prevent regressions in this 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.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp
android.mov
Android: mWeb Chrome
mchrome.mov
iOS: HybridApp
ios.mov
iOS: mWeb Safari
msafari.mov
MacOS: Chrome / Safari
web.mov
web-offline.mov

@rohit9625
Copy link
Contributor Author

Hi @heyjennahay, we are waiting for you to review this PR. Thanks :)

@rohit9625
Copy link
Contributor Author

Friendly bump! @heyjennahay :)

@melvin-bot melvin-bot bot requested a review from cead22 January 20, 2026 08:20
heyjennahay
heyjennahay previously approved these changes Jan 20, 2026
Copy link
Contributor

@heyjennahay heyjennahay left a comment

Choose a reason for hiding this comment

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

Product change LGTM

@rohit9625
Copy link
Contributor Author

Can we merge this PR now?

cead22
cead22 previously approved these changes Jan 21, 2026
@cead22
Copy link
Contributor

cead22 commented Jan 21, 2026

@rohit9625 @aimane-chnaif why do we show a spinner in these flows? I thought with optimistic data we wouldn't show a spinner, and the UI would update instantly. Similarly, when offline and we make the update, the update happens instantly, but when going back online we see a spinner again. Can we get rid of it?

@cead22
Copy link
Contributor

cead22 commented Jan 22, 2026

This one

@rohit9625
Copy link
Contributor Author

Hi @cead22, I looked into the code, and we have to remove the code that sets isLoadingWorkspaceReimbursement to true at the setWorkspaceReimbursement function. Also, we have to remove the ActivityIndicator entirely from here:

!isOffline && policy?.isLoadingWorkspaceReimbursement === true ? (
<ActivityIndicator
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
style={styles.mt7}
/>
) : (

Only this way, we can avoid showing the indicator. Although I'm still not having a good feeling about making this change, as it was added for a reason. I understand we now update the BA in the optimistic data and showing loading indicator won't make sense.

The isLoadingWorkspaceReimbursement is also used at the ReimbursementAccountPage and I think removing this code may cause regressions for that page. What do you think, @cead22? Should we take the risk or just remove the ActivityIndicator component at the WorkspaceWorkflowPage?

@rohit9625
Copy link
Contributor Author

Friendly bump! @cead22 on the above comment.

@rohit9625 rohit9625 dismissed stale reviews from cead22 and heyjennahay via 8429d43 January 30, 2026 07:15
@rohit9625
Copy link
Contributor Author

rohit9625 commented Jan 30, 2026

Hi @cead22, I've removed the loading indicator as you suggested. This is the behavior right now:

Screen.Recording.2026-01-30.at.12.44.19.PM.mov

Please take a look and possibly try to merge if everything seems fine, @cead22 @aimane-chnaif
Thanks :)

@cead22
Copy link
Contributor

cead22 commented Jan 30, 2026

Video looks great. @aimane-chnaif can you please give it another review?

@rohit9625
Copy link
Contributor Author

Friendly bump! @aimane-chnaif

@rohit9625
Copy link
Contributor Author

rohit9625 commented Feb 3, 2026

Hi @aimane-chnaif, please take a look at this PR :)

@aimane-chnaif
Copy link
Contributor

aimane-chnaif commented Feb 3, 2026

While completely removing loading indicator makes our issue better, I think there's side effect.
i.e. when close add bank account flow in the middle, Add bank account button is suddenly replaced with partially setup bank account (without loading)

I'm afraid QA will mark it as regression. (this is just one example. there might be other cases which might confuse user)

Screen.Recording.2026-02-03.at.4.31.02.pm.mov

As such, can we restore loading indicator back?

@cead22
Copy link
Contributor

cead22 commented Feb 6, 2026

That looks fine to me actually

@rohit9625
Copy link
Contributor Author

Are we not supposed to show partially setup bank accounts, @aimane-chnaif?

@aimane-chnaif
Copy link
Contributor

ok then we can proceed. Please fix conflict.

@aimane-chnaif
Copy link
Contributor

Are we not supposed to show partially setup bank accounts, @aimane-chnaif?

We should show them

@rohit9625
Copy link
Contributor Author

rohit9625 commented Feb 6, 2026

ok then we can proceed. Please fix conflict.

Done 👍
I agree that the behavior in your screen-recording looks weird, @aimane-chnaif. But, if @cead22 thinks it's fine, then let's proceed with that :)

@melvin-bot melvin-bot bot requested a review from cead22 February 6, 2026 07:21
@cead22 cead22 merged commit bc3f6a9 into Expensify:main Feb 6, 2026
30 checks passed
@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

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

@OSBotify
Copy link
Contributor

OSBotify commented Feb 6, 2026

✋ 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
Contributor

🚀 Deployed to staging by https://github.com/cead22 in version: 9.3.16-0 🚀

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

@OSBotify
Copy link
Contributor

🚀 Deployed to production by https://github.com/lakchote in version: 9.3.16-9 🚀

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

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.

5 participants

Comments