Skip to content

Add a Time sensitive to-do for employees with missing deposit accounts - #96623

Open
sharabai wants to merge 10 commits into
Expensify:mainfrom
software-mansion-labs:feature/home/time-sensitive-card
Open

Add a Time sensitive to-do for employees with missing deposit accounts#96623
sharabai wants to merge 10 commits into
Expensify:mainfrom
software-mansion-labs:feature/home/time-sensitive-card

Conversation

@sharabai

@sharabai sharabai commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Explanation of Change

This PR adds a Time sensitive Home item when an ACH reimbursement is queued because the current payee has no personal deposit account. It uses the queued action's paymentType to exclude Wallet/KYC waits, opens the existing bank-account setup flow, and adds the required route, copy, documentation, and unit coverage.

Fixed Issues

$ #88187
PROPOSAL: #88187 (comment)

Tests

ACH reimbursement waiting for a personal bank account

Preconditions:

  • User A owns or administers a workspace with Payments enabled, a verified business bank account selected as the payment account, and User A selected as the authorized payer.
  • User B is a validated regular member of that workspace and has no personal bank account under Account → Wallet.
  1. As User B, create a small manual expense in the workspace and submit it.
  2. As User A, approve the expense if required and pay it with the workspace's business bank account.
  3. As User B, go directly to Home without opening the expense report.
  4. Verify that Time sensitive shows one item titled Add a bank account to get reimbursed, with Wallet as the subtitle and Add as the CTA.
  5. Hard-refresh Home and verify that the item remains visible and is not duplicated.
  6. Press Add and verify that the personal bank-account setup flow opens.
  7. Add a personal bank account using Plaid sandbox credentials.
  8. Verify that the Add a bank account to get reimbursed item disappears from Home.

Wallet payment exclusion (not manually verified)

Note

I couldn't manually verify this case with the available test setup. The payer has a test Wallet, while an unactivated recipient is treated as a non-test Wallet, and the backend rejects that pairing with error code 666: “Cannot mix test and non-test wallets in a payment.” Therefore, the queued Wallet state can't currently be reached with these test accounts.

Preconditions:

  • User C has an activated non-test Expensify Wallet.
  • User D has not activated their Expensify Wallet and has no personal bank account.
  1. As User C, send or pay money to User D using Pay with Expensify.
  2. As User D, open the affected report.
  3. Verify that the queued-payment message shows Enable wallet.
  4. Go to Home.
  5. Verify that Add a bank account to get reimbursed is not shown for this Wallet/KYC wait.
  • Verify that no errors appear in the JS console

Offline tests

N/A — this change only derives UI from existing Onyx state and opens the existing bank-account setup flow. It adds no API calls, writes, or offline-specific behavior.

QA Steps

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 followed proper code patterns (see Reviewing the code)
    • 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 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)
  • 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)
  • 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.
  • 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: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
time.card.mp4

[!NOTE]
The second recording was captured after fixing the bank-account setup exit navigation. It shows that Continue now closes the flow and returns to Home instead of navigating back to /add-us-bank-account/entry-point.

fix.success.navigation.mp4

@melvin-bot

melvin-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

Hey, I noticed you changed src/languages/en.ts in a PR from a fork. For security reasons, translations are not generated automatically for PRs from forks.

If you want to automatically generate translations for other locales, an Expensify employee will have to:

  1. Look at the code and make sure there are no malicious changes.
  2. Run the Generate static translations GitHub workflow. If you have write access and the K2 extension, you can simply click: [this button]

Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running:

npx ts-node ./scripts/generateTranslations.ts --help

Typically, you'd want to translate only what you changed by running npx ts-node ./scripts/generateTranslations.ts --compare-ref main

@sharabai
sharabai marked this pull request as ready for review July 21, 2026 11:13
@sharabai
sharabai requested review from a team as code owners July 21, 2026 11:14
@melvin-bot
melvin-bot Bot requested review from trjExpensify and removed request for a team July 21, 2026 11:14
@sharabai
sharabai marked this pull request as draft July 21, 2026 11:14
@melvin-bot
melvin-bot Bot requested review from Gonals and removed request for a team July 21, 2026 11:14
@melvin-bot

melvin-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

@Gonals 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]

Comment thread src/pages/home/TimeSensitiveSection/hooks/useTimeSensitiveAddBankAccount.ts Outdated
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ Changes either increased or maintained existing code coverage, great job!

Files with missing lines Coverage Δ
src/CONST/index.ts 94.81% <ø> (ø)
src/ROUTES.ts 22.31% <ø> (+0.15%) ⬆️
src/libs/ReportUtils.ts 86.62% <100.00%> (+0.02%) ⬆️
src/pages/AddPersonalBankAccountPage.tsx 96.77% <100.00%> (+96.77%) ⬆️
...iveSection/hooks/useTimeSensitiveAddBankAccount.ts 100.00% <100.00%> (ø)
src/pages/home/TimeSensitiveSection/index.tsx 75.60% <100.00%> (+0.92%) ⬆️
...home/TimeSensitiveSection/items/AddBankAccount.tsx 100.00% <100.00%> (ø)
...port/actionContents/ReimbursementQueuedContent.tsx 95.00% <100.00%> (ø)
... and 110 files with indirect coverage changes

@sharabai

Copy link
Copy Markdown
Contributor Author

@codex review

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

Copy link
Copy Markdown

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: 89c755aa46

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

@sharabai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 89c755aa46

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

@sharabai

Copy link
Copy Markdown
Contributor Author

@codex review

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

Copy link
Copy Markdown

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: 89c755aa46

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

@sharabai
sharabai marked this pull request as ready for review July 23, 2026 18:36
Comment on lines +38 to +39
Object.values(allReports ?? {})
.filter((report): report is Report => !!report?.reportID && report.isWaitingOnBankAccount === true && report.ownerAccountID === accountID)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we add !isSettled(report) to this filter @sharabai

@sharabai sharabai Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@grgia Great question! As far as I can tell, we don't need it. REIMBURSEMENT_QUEUED remains in the action history even after the report transitions to REIMBURSED. That's why getIndicatedMissingPaymentMethod() uses !isSettled() - to avoid acting on that historical action once the report has transitioned to REIMBURSED.

Our selector already requires isWaitingOnBankAccount === true, so adding !isSettled() would only guard against an invalid REIMBURSED + isWaitingOnBankAccount state. I tested the full flow, and the backend cleared the flag when the report transitioned to REIMBURSED, and that persisted after a refresh.

@sharabai
sharabai requested a review from grgia July 27, 2026 10:53
@sharabai

Copy link
Copy Markdown
Contributor Author

@grgia Could you run the workflow to make sure the translations match?

Run the Generate static translations GitHub workflow. If you have write access and the K2 extension, you can simply click: [this button]

@OSBotify

This comment has been minimized.

@OSBotify

Copy link
Copy Markdown
Contributor

🦜 Polyglot Parrot! 🦜

Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues:

View the translation diff
diff --git a/src/languages/de.ts b/src/languages/de.ts
index cd7a0ad4132..f6cb6092ebf 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -964,9 +964,7 @@ const translations: TranslationDeepObject<typeof en> = {
             title: 'Zeitkritisch',
             addShippingAddress: {title: 'Wir benötigen deine Versandadresse', subtitle: 'Geben Sie eine Adresse an, um Ihre Expensify Karte zu erhalten.', cta: 'Adresse hinzufügen'},
             addPaymentCard: {title: 'Fügen Sie eine Zahlungskarte hinzu, um Expensify weiter zu nutzen', subtitle: 'Konto > Abonnement', cta: 'Hinzufügen'},
-            addBankAccount: {
-                title: 'Fügen Sie ein Bankkonto hinzu, um Rückerstattungen zu erhalten',
-            },
+            addBankAccount: {title: 'Fügen Sie ein Bankkonto hinzu, um eine Erstattung zu erhalten'},
             activateCard: {title: 'Aktivieren Sie Ihre Expensify Karte', subtitle: 'Validieren Sie Ihre Karte und beginnen Sie mit dem Ausgeben.', cta: 'Aktivieren'},
             reviewCardFraud: {
                 title: 'Möglichen Betrug mit Ihrer Expensify Karte überprüfen',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 1b0bc747878..8c29a3f5ad1 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -929,9 +929,7 @@ const translations: TranslationDeepObject<typeof en> = {
                 subtitle: 'Cuenta > Suscripción',
                 cta: 'Añadir',
             },
-            addBankAccount: {
-                title: 'Añade una cuenta bancaria para recibir tus reembolsos',
-            },
+            addBankAccount: {title: 'Añade una cuenta bancaria para recibir el reembolso'},
             activateCard: {
                 title: 'Activa tu Tarjeta Expensify',
                 subtitle: 'Valida tu tarjeta y empieza a gastar.',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 50252f59ad7..16bdc7fd84b 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -967,9 +967,7 @@ const translations: TranslationDeepObject<typeof en> = {
             title: 'Urgent',
             addShippingAddress: {title: 'Nous avons besoin de votre adresse de livraison', subtitle: 'Indiquez une adresse pour recevoir votre Carte Expensify.', cta: 'Ajouter une adresse'},
             addPaymentCard: {title: 'Ajoutez une carte de paiement pour continuer à utiliser Expensify', subtitle: 'Compte > Abonnement', cta: 'Ajouter'},
-            addBankAccount: {
-                title: 'Ajoutez un compte bancaire pour recevoir vos remboursements',
-            },
+            addBankAccount: {title: 'Ajoutez un compte bancaire pour être remboursé'},
             activateCard: {title: 'Activer votre Carte Expensify', subtitle: 'Validez votre carte et commencez à dépenser.', cta: 'Activer'},
             reviewCardFraud: {
                 title: 'Examiner une éventuelle fraude sur votre Carte Expensify',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index a97e1ee6851..63a2e9165bc 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -965,9 +965,7 @@ const translations: TranslationDeepObject<typeof en> = {
             title: 'Sensibile al tempo',
             addShippingAddress: {title: 'Ci serve il tuo indirizzo di spedizione', subtitle: 'Fornisci un indirizzo per ricevere la tua Carta Expensify.', cta: 'Aggiungi indirizzo'},
             addPaymentCard: {title: 'Aggiungi una carta di pagamento per continuare a usare Expensify', subtitle: 'Account > Abbonamento', cta: 'Aggiungi'},
-            addBankAccount: {
-                title: 'Aggiungi un conto bancario per ricevere i rimborsi',
-            },
+            addBankAccount: {title: 'Aggiungi un conto bancario per ricevere il rimborso'},
             activateCard: {title: 'Attiva la tua Carta Expensify', subtitle: 'Convalida la tua carta e inizia a spendere.', cta: 'Attiva'},
             reviewCardFraud: {
                 title: 'Esamina una possibile frode sulla tua Carta Expensify',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 2543093b7de..aa94a25afb6 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -954,9 +954,7 @@ const translations: TranslationDeepObject<typeof en> = {
             title: '時間に敏感',
             addShippingAddress: {title: '配送先住所が必要です', subtitle: 'Expensify カードを受け取る住所を入力してください。', cta: '住所を追加'},
             addPaymentCard: {title: 'Expensify を引き続きご利用いただくには、支払いカードを追加してください', subtitle: 'アカウント > サブスクリプション', cta: '追加'},
-            addBankAccount: {
-                title: '払い戻しを受け取るために銀行口座を追加してください',
-            },
+            addBankAccount: {title: '銀行口座を追加して払い戻しを受け取りましょう'},
             activateCard: {title: 'Expensify カードを有効化する', subtitle: 'カードを認証して支出を始めましょう。', cta: '有効化'},
             reviewCardFraud: {
                 title: 'Expensify カードの不正利用の可能性を確認する',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 804a5f07729..b4c2e9b14ff 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -963,9 +963,7 @@ const translations: TranslationDeepObject<typeof en> = {
             title: 'Tijdgevoelig',
             addShippingAddress: {title: 'We hebben je verzendadres nodig', subtitle: 'Geef een adres op om je Expensify Kaart te ontvangen.', cta: 'Adres toevoegen'},
             addPaymentCard: {title: 'Voeg een betaalkaart toe om Expensify te blijven gebruiken', subtitle: 'Account > Abonnement', cta: 'Toevoegen'},
-            addBankAccount: {
-                title: 'Voeg een bankrekening toe om vergoedingen te ontvangen',
-            },
+            addBankAccount: {title: 'Voeg een bankrekening toe om je terugbetaling te ontvangen'},
             activateCard: {title: 'Activeer je Expensify Kaart', subtitle: 'Valideer je kaart en begin met uitgeven.', cta: 'Activeren'},
             reviewCardFraud: {
                 title: 'Controleer mogelijk misbruik van je Expensify Kaart',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 1123d54abb8..dd237b53364 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -965,9 +965,7 @@ const translations: TranslationDeepObject<typeof en> = {
             title: 'Wymaga szybkiej reakcji',
             addShippingAddress: {title: 'Potrzebujemy Twojego adresu wysyłki', subtitle: 'Podaj adres, na który mamy wysłać twoją Kartę Expensify.', cta: 'Dodaj adres'},
             addPaymentCard: {title: 'Dodaj kartę płatniczą, żeby dalej korzystać z Expensify', subtitle: 'Konto > Subskrypcja', cta: 'Dodaj'},
-            addBankAccount: {
-                title: 'Dodaj konto bankowe, aby otrzymywać zwroty',
-            },
+            addBankAccount: {title: 'Dodaj konto bankowe, aby otrzymać zwrot'},
             activateCard: {title: 'Aktywuj swoją Kartę Expensify', subtitle: 'Zatwierdź swoją kartę i zacznij wydawać.', cta: 'Aktywuj'},
             reviewCardFraud: {
                 title: 'Sprawdź potencjalne oszustwo na swojej Karcie Expensify',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 815e16930eb..f170d55a27f 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -963,9 +963,7 @@ const translations: TranslationDeepObject<typeof en> = {
             title: 'Urgente',
             addShippingAddress: {title: 'Precisamos do seu endereço de entrega', subtitle: 'Informe um endereço para receber seu Cartão Expensify.', cta: 'Adicionar endereço'},
             addPaymentCard: {title: 'Adicione um cartão de pagamento para continuar usando o Expensify', subtitle: 'Conta > Assinatura', cta: 'Adicionar'},
-            addBankAccount: {
-                title: 'Adicione uma conta bancária para receber reembolsos',
-            },
+            addBankAccount: {title: 'Adicione uma conta bancária para ser reembolsado'},
             activateCard: {title: 'Ative seu Cartão Expensify', subtitle: 'Valide seu cartão e comece a gastar.', cta: 'Ativar'},
             reviewCardFraud: {
                 title: 'Analisar possível fraude no seu Cartão Expensify',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 06ebf221ab8..04bf2d21e13 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -937,9 +937,7 @@ const translations: TranslationDeepObject<typeof en> = {
             title: '时间敏感',
             addShippingAddress: {title: '我们需要您的收货地址', subtitle: '请提供一个地址以接收您的 Expensify 卡。', cta: '添加地址'},
             addPaymentCard: {title: '添加支付卡以继续使用 Expensify', subtitle: '账户 > 订阅', cta: '添加'},
-            addBankAccount: {
-                title: '添加银行账户以便接收报销款',
-            },
+            addBankAccount: {title: '添加银行账户以接收报销'},
             activateCard: {title: '激活你的 Expensify 卡', subtitle: '验证您的银行卡并开始消费。', cta: '启用'},
             reviewCardFraud: {
                 title: '审查您 Expensify 卡上的潜在欺诈交易',

Note

You can apply these changes to your branch by copying the patch to your clipboard, then running pbpaste | git apply 😉

View workflow run

@grgia

grgia commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Applied

@trjExpensify
trjExpensify requested review from JmillsExpensify and removed request for trjExpensify July 28, 2026 11:51
@trjExpensify

Copy link
Copy Markdown
Contributor

@JmillsExpensify's issue, re-assigning.

Comment on lines +38 to +42
switch (activeTab) {
case NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR:
Navigation.goBack(ROUTES.SETTINGS_WALLET);
break;
case SCREENS.HOME:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

NAB. should we add a test covering the Home exit path in goBack, asserting Navigation.closeRHPFlow fires when the flow starts from SCREENS.HOME?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good idea, I'll add one.

@grgia
grgia requested a review from ZhenjaHorbach July 28, 2026 14:23
@grgia

grgia commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

@ZhenjaHorbach the autoassigner didn't add ya

Comment thread src/languages/en.ts
cta: 'Add',
},
addBankAccount: {
// @context Home reminder shown to a payment recipient when a reimbursement is waiting for them to add a personal deposit account.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what is this @context

@sharabai sharabai Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not sure why @context is used to provide context for the strings 🤔, but that's the convention I've seen in this file. There are lots of examples that do the same thing.

grgia
grgia previously approved these changes Jul 28, 2026

@grgia grgia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

comments are NAB

@github-actions

Copy link
Copy Markdown
Contributor

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

Comment thread src/libs/ReportUtils.ts
Comment thread src/libs/ReportUtils.ts Outdated
const waitingReportIDsSelector = (allReports: OnyxCollection<Report>): string[] =>
Object.values(allReports ?? {})
.filter((report): report is Report => !!report?.reportID && report.isWaitingOnBankAccount === true && report.ownerAccountID === accountID)
.map((report) => report.reportID);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we use reduce to decrease the number of operations?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion, thanks! In this case, though, .map() only runs on the filtered result, which is at most one report in practice, so there's nothing meaningful to save here. I'd rather keep filter().map() for readability.

const [userWalletTierName] = useOnyx(ONYXKEYS.USER_WALLET, {selector: tierNameSelector});
const canShowAddBankAccount = accountID !== undefined && !isLoadingOnyxValue(bankAccountListMetadata) && !hasCreditBankAccount(bankAccountList);

const shouldShowAddBankAccountSelector = (allReportActions: OnyxCollection<ReportActions>): boolean => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's move this to the selectors folder for consistency
And let's add tests

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@ZhenjaHorbach Hmm, I had a look before replying, and I'm not sure we have a consistent convention here:

  • src/selectors/ has 136 exported selectors across 26 files.
  • There are also 199 named selectors defined in the same file that uses them, across 164 files, plus 45 inline selectors at the call site.

So moving selectors into src/selectors/ doesn't really seem to be the dominant pattern. It also doesn't seem to provide much benefit: 56 of those 136 selectors are referenced from exactly one file, and 2 aren't referenced outside the selectors folder at all. If they'd stayed next to the code that used them, they would have been removed along with it instead of being left behind.

With that in mind, I'd rather keep this one next to the hook, especially since it isn't just projecting a single Onyx value. It would need canShowAddBankAccount, waitingReportIDs, userWalletTierName, and bankAccountList passed in, three of which are themselves the results of useOnyx calls.

When you mentioned consistency, did you have something more specific in mind? Happy to move it if I'm missing the pattern you're pointing out.

Comment thread src/pages/home/TimeSensitiveSection/items/AddBankAccount.tsx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
Built from App PR #96623.

Android 🤖 iOS 🍎
https://ad-hoc-expensify-cash.s3.us-east-1.amazonaws.com/rock-artifacts/ad-hoc/rock-android-Adhoc-a63cee5d2fb-2be666f-4c03ba28340dc98f44a959dad879974ffe77036a/index.html ❌ FAILED ❌
Android The QR code can't be generated, because the iOS build failed
Web 🕸️
https://96623.pr-testing.expensify.com
Web

👀 View the workflow run that generated this build 👀

@sharabai

Copy link
Copy Markdown
Contributor Author

@grgia could you rerun the build? The iOS build failed because this branch wasn't up to date. I've synced it with the latest main.

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

@sharabai
sharabai requested review from ZhenjaHorbach and grgia July 29, 2026 18:32
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