From de65f77ab09fb78aa0f223027eaee912455731fe Mon Sep 17 00:00:00 2001 From: "ahmedGaber93 (via MelvinBot)" Date: Fri, 15 May 2026 08:59:57 +0000 Subject: [PATCH 1/6] Guard invoice empty state CTA on canSendInvoice and fix money request back navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a user without an invoice-enabled admin workspace taps "Send invoice" from the empty search view, they are sent to a "not found" page. This hides the Send invoice button for users who cannot send invoices and shows an informative subtitle instead. Also fixes inconsistent back navigation on the not-found page for money request flows — the header back button now calls Navigation.goBack() instead of goBackFromWorkspaceSettingPages(), matching the hardware back behavior. Co-authored-by: ahmedGaber93 --- src/languages/de.ts | 1 + src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/languages/fr.ts | 1 + src/languages/it.ts | 1 + src/languages/ja.ts | 1 + src/languages/nl.ts | 1 + src/languages/pl.ts | 1 + src/languages/pt-BR.ts | 1 + src/languages/zh-hans.ts | 1 + src/pages/Search/EmptySearchView.tsx | 29 +++++++++---- .../workspace/AccessOrNotFoundWrapper.tsx | 2 +- tests/ui/components/EmptySearchViewTest.tsx | 43 ++++++++++++++++++- 13 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index 8d7ddb9bafd9..bc60b1cb19bc 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -7711,6 +7711,7 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc `), subtitle: 'Sende eine Rechnung oder mache eine Probefahrt mit Expensify, um mehr zu erfahren.', subtitleWithOnlyCreateButton: 'Verwende die grüne Schaltfläche unten, um eine Rechnung zu senden.', + subtitleCannotSend: 'Du benötigst einen Arbeitsbereich mit aktivierter Rechnungsstellung, um Rechnungen zu senden.', }, emptyTripResults: { title: 'Keine Reisen zum Anzeigen', diff --git a/src/languages/en.ts b/src/languages/en.ts index b96ea888eef5..dc1975bea631 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -7739,6 +7739,7 @@ const translations = { `), subtitle: 'Send an invoice or take a test drive of Expensify to learn more.', subtitleWithOnlyCreateButton: 'Use the green button below to send an invoice.', + subtitleCannotSend: 'You need a workspace with invoicing enabled to send invoices.', }, emptyTripResults: { title: 'No trips to display', diff --git a/src/languages/es.ts b/src/languages/es.ts index 810bc30742d1..c5de616e6d2c 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -7554,6 +7554,7 @@ ${amount} para ${merchant} - ${date}`, title: 'Aún no has creado \nninguna factura', subtitle: 'Envía una factura o haz una prueba por Expensify para aprender más.', subtitleWithOnlyCreateButton: 'Usa el botón verde de abajo para enviar una factura.', + subtitleCannotSend: 'Necesitas un espacio de trabajo con facturación habilitada para enviar facturas.', }, emptyTripResults: { title: 'No tienes viajes', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 28ae8f63da5f..37ea3526d002 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -7733,6 +7733,7 @@ Ajoutez davantage de règles de dépenses pour protéger la trésorerie de l’e `), subtitle: 'Envoyez une facture ou faites un essai d’Expensify pour en savoir plus.', subtitleWithOnlyCreateButton: 'Utilisez le bouton vert ci-dessous pour envoyer une facture.', + subtitleCannotSend: "Vous avez besoin d'un espace de travail avec la facturation activée pour envoyer des factures.", }, emptyTripResults: { title: 'Aucun voyage à afficher', diff --git a/src/languages/it.ts b/src/languages/it.ts index 9274d0f98d29..8a57a96c891a 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -7702,6 +7702,7 @@ Aggiungi altre regole di spesa per proteggere il flusso di cassa aziendale.`, `), subtitle: 'Invia una fattura o fai un giro di prova con Expensify per saperne di più.', subtitleWithOnlyCreateButton: 'Usa il pulsante verde qui sotto per inviare una fattura.', + subtitleCannotSend: 'Hai bisogno di uno spazio di lavoro con la fatturazione abilitata per inviare fatture.', }, emptyTripResults: { title: 'Nessun viaggio da visualizzare', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 83cfec2d5542..fc8abe5eda78 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -7608,6 +7608,7 @@ ${reportName} `), subtitle: '請求書を送信するか、Expensify を試用してさらに詳しく知りましょう。', subtitleWithOnlyCreateButton: '下の緑色のボタンを使って請求書を送信してください。', + subtitleCannotSend: '請求書を送信するには、請求書機能が有効なワークスペースが必要です。', }, emptyTripResults: { title: '表示する出張はありません', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 0bd883d417dc..88d5f4379e5e 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -7673,6 +7673,7 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`, `), subtitle: 'Stuur een factuur of maak een testrit met Expensify om meer te weten te komen.', subtitleWithOnlyCreateButton: 'Gebruik de groene knop hieronder om een factuur te versturen.', + subtitleCannotSend: 'Je hebt een werkruimte met facturering ingeschakeld nodig om facturen te versturen.', }, emptyTripResults: { title: 'Geen reizen om weer te geven', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 88e5e1c48d87..0c654652dfc1 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -7665,6 +7665,7 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`, `), subtitle: 'Wyślij fakturę lub wypróbuj Expensify, aby dowiedzieć się więcej.', subtitleWithOnlyCreateButton: 'Użyj zielonego przycisku poniżej, aby wysłać fakturę.', + subtitleCannotSend: 'Potrzebujesz przestrzeni roboczej z włączonym fakturowaniem, aby wysyłać faktury.', }, emptyTripResults: { title: 'Brak podróży do wyświetlenia', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 37fc5ab6348c..f4f47c938b2d 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -7667,6 +7667,7 @@ Adicione mais regras de gasto para proteger o fluxo de caixa da empresa.`, `), subtitle: 'Envie uma fatura ou faça um test drive do Expensify para saber mais.', subtitleWithOnlyCreateButton: 'Use o botão verde abaixo para enviar uma fatura.', + subtitleCannotSend: 'Você precisa de um espaço de trabalho com faturamento habilitado para enviar faturas.', }, emptyTripResults: { title: 'Nenhuma viagem para exibir', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index a6de1885ef59..350125b5e4c2 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -7473,6 +7473,7 @@ ${reportName} `), subtitle: '发送发票或试用 Expensify,了解更多信息。', subtitleWithOnlyCreateButton: '使用下方的绿色按钮发送发票。', + subtitleCannotSend: '您需要一个启用了发票功能的工作区才能发送发票。', }, emptyTripResults: { title: '没有行程可显示', diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx index 3e957b916c8b..10ec38779b73 100644 --- a/src/pages/Search/EmptySearchView.tsx +++ b/src/pages/Search/EmptySearchView.tsx @@ -28,7 +28,7 @@ import {createNewReport} from '@libs/actions/Report'; import {startTestDrive} from '@libs/actions/Tour'; import interceptAnonymousUser from '@libs/interceptAnonymousUser'; import Navigation from '@libs/Navigation/Navigation'; -import {getDefaultChatEnabledPolicy, getGroupPaidPoliciesWithExpenseChatEnabled} from '@libs/PolicyUtils'; +import {canSendInvoice, getDefaultChatEnabledPolicy, getGroupPaidPoliciesWithExpenseChatEnabled} from '@libs/PolicyUtils'; import {generateReportID, hasViolations as hasViolationsReportUtils} from '@libs/ReportUtils'; import {isDefaultExpenseReportsQuery, isDefaultExpensesQuery} from '@libs/SearchQueryUtils'; import type {SearchTypeMenuSection} from '@libs/SearchUIUtils'; @@ -386,12 +386,20 @@ function EmptySearchViewContent({ } break; // We want to display the default nothing to show message if there is any filter applied. - case CONST.SEARCH.DATA_TYPES.INVOICE: + case CONST.SEARCH.DATA_TYPES.INVOICE: { + const userCanSendInvoice = canSendInvoice(allPolicies, currentUserPersonalDetails.login); if (!content && !hasResults) { content = { ...defaultViewItemHeader.folder, title: translate('search.searchResults.emptyInvoiceResults.title'), - subtitle: translate(hasSeenTour ? 'search.searchResults.emptyInvoiceResults.subtitleWithOnlyCreateButton' : 'search.searchResults.emptyInvoiceResults.subtitle'), + subtitle: translate( + // eslint-disable-next-line no-nested-ternary + !userCanSendInvoice + ? 'search.searchResults.emptyInvoiceResults.subtitleCannotSend' + : hasSeenTour + ? 'search.searchResults.emptyInvoiceResults.subtitleWithOnlyCreateButton' + : 'search.searchResults.emptyInvoiceResults.subtitle', + ), buttons: [ ...(!hasSeenTour ? [ @@ -401,15 +409,20 @@ function EmptySearchViewContent({ }, ] : []), - { - buttonText: translate('workspace.invoices.sendInvoice'), - buttonAction: () => handleCreateMoneyRequest(CONST.IOU.TYPE.INVOICE), - success: true, - }, + ...(userCanSendInvoice + ? [ + { + buttonText: translate('workspace.invoices.sendInvoice'), + buttonAction: () => handleCreateMoneyRequest(CONST.IOU.TYPE.INVOICE), + success: true, + }, + ] + : []), ], }; } break; + } case CONST.SEARCH.DATA_TYPES.CHAT: default: if (!content) { diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 9c940b676613..111fb1c48b69 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -118,7 +118,7 @@ function PageNotFoundFallback({policyID, fullPageNotFoundViewProps, isFeatureEna shouldForceFullScreen={shouldShowFullScreenFallback} shouldShowOfflineIndicator={false} onBackButtonPress={() => { - if (isPolicyNotAccessible) { + if (isPolicyNotAccessible && !isMoneyRequest) { goBackFromWorkspaceSettingPages(); return; } diff --git a/tests/ui/components/EmptySearchViewTest.tsx b/tests/ui/components/EmptySearchViewTest.tsx index 5c1f37a2373e..ba840a657d37 100644 --- a/tests/ui/components/EmptySearchViewTest.tsx +++ b/tests/ui/components/EmptySearchViewTest.tsx @@ -246,11 +246,22 @@ describe('EmptySearchView', () => { describe('type is Invoice', () => { const dataType = CONST.SEARCH.DATA_TYPES.INVOICE; + const INVOICE_POLICY_ID = 'invoicePolicy'; + const createInvoiceEnabledPolicy = () => ({ + id: INVOICE_POLICY_ID, + name: 'Invoice Workspace', + type: CONST.POLICY.TYPE.TEAM, + role: CONST.POLICY.ROLE.ADMIN, + areInvoicesEnabled: true, + isPolicyExpenseChatEnabled: true, + }); it('should display correct buttons and subtitle when user has not clicked on "Take a test drive"', async () => { - // Given user hasn't clicked on "Take a test drive" yet + // Given user hasn't clicked on "Take a test drive" yet and has an invoice-enabled workspace await act(async () => { await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {selfTourViewed: false}); + await Onyx.merge(ONYXKEYS.SESSION, SESSION); + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${INVOICE_POLICY_ID}`, createInvoiceEnabledPolicy()); }); // Render component @@ -273,9 +284,11 @@ describe('EmptySearchView', () => { }); it('should display correct buttons and subtitle when user already did "Take a test drive"', async () => { - // Given user clicked on "Take a test drive" + // Given user clicked on "Take a test drive" and has an invoice-enabled workspace await act(async () => { await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {selfTourViewed: true}); + await Onyx.merge(ONYXKEYS.SESSION, SESSION); + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${INVOICE_POLICY_ID}`, createInvoiceEnabledPolicy()); }); // Render component @@ -296,5 +309,31 @@ describe('EmptySearchView', () => { // And correct modal subtitle expect(screen.getByText(translateLocal('search.searchResults.emptyInvoiceResults.subtitleWithOnlyCreateButton'))).toBeVisible(); }); + + it('should hide Send invoice button when user cannot send invoices', async () => { + // Given user has no invoice-enabled workspace + await act(async () => { + await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {selfTourViewed: true}); + await Onyx.merge(ONYXKEYS.SESSION, SESSION); + }); + + // Render component + render( + + + , + ); + await waitForBatchedUpdatesWithAct(); + + // Then it should not display Send invoice button + expect(screen.queryByText(translateLocal('workspace.invoices.sendInvoice'))).not.toBeOnTheScreen(); + + // And should show the cannot-send subtitle + expect(screen.getByText(translateLocal('search.searchResults.emptyInvoiceResults.subtitleCannotSend'))).toBeVisible(); + }); }); }); From 98ec5456aa73c18634e26fef0c7a33bb5ad491bc Mon Sep 17 00:00:00 2001 From: "ahmedGaber93 (via MelvinBot)" Date: Tue, 26 May 2026 16:44:32 +0000 Subject: [PATCH 2/6] Update feature name from 'invoicing' to 'Invoices' in subtitleCannotSend across all translation files Co-authored-by: ahmedGaber93 --- src/languages/de.ts | 2 +- src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- src/languages/fr.ts | 2 +- src/languages/it.ts | 2 +- src/languages/ja.ts | 2 +- src/languages/nl.ts | 2 +- src/languages/pl.ts | 2 +- src/languages/pt-BR.ts | 2 +- src/languages/zh-hans.ts | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index bc60b1cb19bc..72dff4a7d538 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -7711,7 +7711,7 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc `), subtitle: 'Sende eine Rechnung oder mache eine Probefahrt mit Expensify, um mehr zu erfahren.', subtitleWithOnlyCreateButton: 'Verwende die grüne Schaltfläche unten, um eine Rechnung zu senden.', - subtitleCannotSend: 'Du benötigst einen Arbeitsbereich mit aktivierter Rechnungsstellung, um Rechnungen zu senden.', + subtitleCannotSend: 'Du benötigst einen Arbeitsbereich mit aktiviertem Invoices, um Rechnungen zu senden.', }, emptyTripResults: { title: 'Keine Reisen zum Anzeigen', diff --git a/src/languages/en.ts b/src/languages/en.ts index dc1975bea631..933ffd34a3dd 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -7739,7 +7739,7 @@ const translations = { `), subtitle: 'Send an invoice or take a test drive of Expensify to learn more.', subtitleWithOnlyCreateButton: 'Use the green button below to send an invoice.', - subtitleCannotSend: 'You need a workspace with invoicing enabled to send invoices.', + subtitleCannotSend: 'You need a workspace with Invoices enabled to send invoices.', }, emptyTripResults: { title: 'No trips to display', diff --git a/src/languages/es.ts b/src/languages/es.ts index c5de616e6d2c..a91d77318da6 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -7554,7 +7554,7 @@ ${amount} para ${merchant} - ${date}`, title: 'Aún no has creado \nninguna factura', subtitle: 'Envía una factura o haz una prueba por Expensify para aprender más.', subtitleWithOnlyCreateButton: 'Usa el botón verde de abajo para enviar una factura.', - subtitleCannotSend: 'Necesitas un espacio de trabajo con facturación habilitada para enviar facturas.', + subtitleCannotSend: 'Necesitas un espacio de trabajo con Invoices habilitado para enviar facturas.', }, emptyTripResults: { title: 'No tienes viajes', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 37ea3526d002..4bc399862dbb 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -7733,7 +7733,7 @@ Ajoutez davantage de règles de dépenses pour protéger la trésorerie de l’e `), subtitle: 'Envoyez une facture ou faites un essai d’Expensify pour en savoir plus.', subtitleWithOnlyCreateButton: 'Utilisez le bouton vert ci-dessous pour envoyer une facture.', - subtitleCannotSend: "Vous avez besoin d'un espace de travail avec la facturation activée pour envoyer des factures.", + subtitleCannotSend: "Vous avez besoin d'un espace de travail avec Invoices activé pour envoyer des factures.", }, emptyTripResults: { title: 'Aucun voyage à afficher', diff --git a/src/languages/it.ts b/src/languages/it.ts index 8a57a96c891a..ba1495e2be24 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -7702,7 +7702,7 @@ Aggiungi altre regole di spesa per proteggere il flusso di cassa aziendale.`, `), subtitle: 'Invia una fattura o fai un giro di prova con Expensify per saperne di più.', subtitleWithOnlyCreateButton: 'Usa il pulsante verde qui sotto per inviare una fattura.', - subtitleCannotSend: 'Hai bisogno di uno spazio di lavoro con la fatturazione abilitata per inviare fatture.', + subtitleCannotSend: 'Hai bisogno di uno spazio di lavoro con Invoices abilitato per inviare fatture.', }, emptyTripResults: { title: 'Nessun viaggio da visualizzare', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index fc8abe5eda78..ac44af23ac6a 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -7608,7 +7608,7 @@ ${reportName} `), subtitle: '請求書を送信するか、Expensify を試用してさらに詳しく知りましょう。', subtitleWithOnlyCreateButton: '下の緑色のボタンを使って請求書を送信してください。', - subtitleCannotSend: '請求書を送信するには、請求書機能が有効なワークスペースが必要です。', + subtitleCannotSend: '請求書を送信するには、Invoicesが有効なワークスペースが必要です。', }, emptyTripResults: { title: '表示する出張はありません', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 88d5f4379e5e..e1dd7ce9d345 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -7673,7 +7673,7 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`, `), subtitle: 'Stuur een factuur of maak een testrit met Expensify om meer te weten te komen.', subtitleWithOnlyCreateButton: 'Gebruik de groene knop hieronder om een factuur te versturen.', - subtitleCannotSend: 'Je hebt een werkruimte met facturering ingeschakeld nodig om facturen te versturen.', + subtitleCannotSend: 'Je hebt een werkruimte met Invoices ingeschakeld nodig om facturen te versturen.', }, emptyTripResults: { title: 'Geen reizen om weer te geven', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 0c654652dfc1..f822e86373bc 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -7665,7 +7665,7 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`, `), subtitle: 'Wyślij fakturę lub wypróbuj Expensify, aby dowiedzieć się więcej.', subtitleWithOnlyCreateButton: 'Użyj zielonego przycisku poniżej, aby wysłać fakturę.', - subtitleCannotSend: 'Potrzebujesz przestrzeni roboczej z włączonym fakturowaniem, aby wysyłać faktury.', + subtitleCannotSend: 'Potrzebujesz przestrzeni roboczej z włączonym Invoices, aby wysyłać faktury.', }, emptyTripResults: { title: 'Brak podróży do wyświetlenia', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index f4f47c938b2d..fa61dc79d7a1 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -7667,7 +7667,7 @@ Adicione mais regras de gasto para proteger o fluxo de caixa da empresa.`, `), subtitle: 'Envie uma fatura ou faça um test drive do Expensify para saber mais.', subtitleWithOnlyCreateButton: 'Use o botão verde abaixo para enviar uma fatura.', - subtitleCannotSend: 'Você precisa de um espaço de trabalho com faturamento habilitado para enviar faturas.', + subtitleCannotSend: 'Você precisa de um espaço de trabalho com Invoices habilitado para enviar faturas.', }, emptyTripResults: { title: 'Nenhuma viagem para exibir', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 350125b5e4c2..4f5c073843e2 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -7473,7 +7473,7 @@ ${reportName} `), subtitle: '发送发票或试用 Expensify,了解更多信息。', subtitleWithOnlyCreateButton: '使用下方的绿色按钮发送发票。', - subtitleCannotSend: '您需要一个启用了发票功能的工作区才能发送发票。', + subtitleCannotSend: '您需要一个启用了Invoices的工作区才能发送发票。', }, emptyTripResults: { title: '没有行程可显示', From b8ebb3d9016622e346f98fa65a318e644a00a54b Mon Sep 17 00:00:00 2001 From: "ahmedGaber93 (via MelvinBot)" Date: Tue, 26 May 2026 16:46:44 +0000 Subject: [PATCH 3/6] Revert out-of-scope change to AccessOrNotFoundWrapper back navigation Co-authored-by: ahmedGaber93 --- src/pages/workspace/AccessOrNotFoundWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 111fb1c48b69..9c940b676613 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -118,7 +118,7 @@ function PageNotFoundFallback({policyID, fullPageNotFoundViewProps, isFeatureEna shouldForceFullScreen={shouldShowFullScreenFallback} shouldShowOfflineIndicator={false} onBackButtonPress={() => { - if (isPolicyNotAccessible && !isMoneyRequest) { + if (isPolicyNotAccessible) { goBackFromWorkspaceSettingPages(); return; } From 96937ff2a1420cd7c178768f35c97bf82946d74e Mon Sep 17 00:00:00 2001 From: "ahmedGaber93 (via MelvinBot)" Date: Tue, 26 May 2026 21:18:30 +0000 Subject: [PATCH 4/6] Add justification comment for eslint-disable no-nested-ternary Co-authored-by: ahmedGaber93 --- src/pages/Search/EmptySearchView.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx index 10ec38779b73..c1083934e8a2 100644 --- a/src/pages/Search/EmptySearchView.tsx +++ b/src/pages/Search/EmptySearchView.tsx @@ -393,6 +393,7 @@ function EmptySearchViewContent({ ...defaultViewItemHeader.folder, title: translate('search.searchResults.emptyInvoiceResults.title'), subtitle: translate( + // Nested ternary selects among three subtitle variants based on invoice permission and tour status // eslint-disable-next-line no-nested-ternary !userCanSendInvoice ? 'search.searchResults.emptyInvoiceResults.subtitleCannotSend' From b9994597bbc4214bc5d391bd0912f3485f8582c0 Mon Sep 17 00:00:00 2001 From: "ahmedGaber93 (via MelvinBot)" Date: Wed, 27 May 2026 11:43:07 +0000 Subject: [PATCH 5/6] Refactor invoice subtitle selection to use if/else instead of nested ternary Co-authored-by: ahmedGaber93 --- src/pages/Search/EmptySearchView.tsx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx index c1083934e8a2..b962db91674e 100644 --- a/src/pages/Search/EmptySearchView.tsx +++ b/src/pages/Search/EmptySearchView.tsx @@ -35,6 +35,7 @@ import type {SearchTypeMenuSection} from '@libs/SearchUIUtils'; import {TODO_SEARCH_KEYS} from '@libs/SearchUIUtils'; import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils'; import CONST from '@src/CONST'; +import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {PersonalDetails, Policy, Report, Transaction} from '@src/types/onyx'; @@ -388,19 +389,17 @@ function EmptySearchViewContent({ // We want to display the default nothing to show message if there is any filter applied. case CONST.SEARCH.DATA_TYPES.INVOICE: { const userCanSendInvoice = canSendInvoice(allPolicies, currentUserPersonalDetails.login); + let subtitleKey: TranslationPaths = 'search.searchResults.emptyInvoiceResults.subtitle'; + if (!userCanSendInvoice) { + subtitleKey = 'search.searchResults.emptyInvoiceResults.subtitleCannotSend'; + } else if (hasSeenTour) { + subtitleKey = 'search.searchResults.emptyInvoiceResults.subtitleWithOnlyCreateButton'; + } if (!content && !hasResults) { content = { ...defaultViewItemHeader.folder, title: translate('search.searchResults.emptyInvoiceResults.title'), - subtitle: translate( - // Nested ternary selects among three subtitle variants based on invoice permission and tour status - // eslint-disable-next-line no-nested-ternary - !userCanSendInvoice - ? 'search.searchResults.emptyInvoiceResults.subtitleCannotSend' - : hasSeenTour - ? 'search.searchResults.emptyInvoiceResults.subtitleWithOnlyCreateButton' - : 'search.searchResults.emptyInvoiceResults.subtitle', - ), + subtitle: translate(subtitleKey), buttons: [ ...(!hasSeenTour ? [ From 737747564b086483da71f50be5abda2738fbffd1 Mon Sep 17 00:00:00 2001 From: "ahmedGaber93 (via MelvinBot)" Date: Wed, 27 May 2026 12:59:32 +0000 Subject: [PATCH 6/6] Add hasSeenTour-aware subtitleCannotSend variant for invoice empty state Co-authored-by: ahmedGaber93 --- src/languages/de.ts | 2 ++ src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/languages/fr.ts | 1 + src/languages/it.ts | 1 + src/languages/ja.ts | 1 + src/languages/nl.ts | 1 + src/languages/pl.ts | 1 + src/languages/pt-BR.ts | 1 + src/languages/zh-hans.ts | 1 + src/pages/Search/EmptySearchView.tsx | 4 +++- 11 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index 72dff4a7d538..a72e4aa89fd2 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -7712,6 +7712,8 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc subtitle: 'Sende eine Rechnung oder mache eine Probefahrt mit Expensify, um mehr zu erfahren.', subtitleWithOnlyCreateButton: 'Verwende die grüne Schaltfläche unten, um eine Rechnung zu senden.', subtitleCannotSend: 'Du benötigst einen Arbeitsbereich mit aktiviertem Invoices, um Rechnungen zu senden.', + subtitleCannotSendWithTestDrive: + 'Du benötigst einen Arbeitsbereich mit aktiviertem Invoices, um Rechnungen zu senden. Mache eine Probefahrt mit Expensify, um mehr zu erfahren.', }, emptyTripResults: { title: 'Keine Reisen zum Anzeigen', diff --git a/src/languages/en.ts b/src/languages/en.ts index 933ffd34a3dd..189ddedff3a7 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -7740,6 +7740,7 @@ const translations = { subtitle: 'Send an invoice or take a test drive of Expensify to learn more.', subtitleWithOnlyCreateButton: 'Use the green button below to send an invoice.', subtitleCannotSend: 'You need a workspace with Invoices enabled to send invoices.', + subtitleCannotSendWithTestDrive: 'You need a workspace with Invoices enabled to send invoices. Take a test drive of Expensify to learn more.', }, emptyTripResults: { title: 'No trips to display', diff --git a/src/languages/es.ts b/src/languages/es.ts index a91d77318da6..ff05ef556d80 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -7555,6 +7555,7 @@ ${amount} para ${merchant} - ${date}`, subtitle: 'Envía una factura o haz una prueba por Expensify para aprender más.', subtitleWithOnlyCreateButton: 'Usa el botón verde de abajo para enviar una factura.', subtitleCannotSend: 'Necesitas un espacio de trabajo con Invoices habilitado para enviar facturas.', + subtitleCannotSendWithTestDrive: 'Necesitas un espacio de trabajo con Invoices habilitado para enviar facturas. Haz una prueba por Expensify para aprender más.', }, emptyTripResults: { title: 'No tienes viajes', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 4bc399862dbb..35951d4d5ae8 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -7734,6 +7734,7 @@ Ajoutez davantage de règles de dépenses pour protéger la trésorerie de l’e subtitle: 'Envoyez une facture ou faites un essai d’Expensify pour en savoir plus.', subtitleWithOnlyCreateButton: 'Utilisez le bouton vert ci-dessous pour envoyer une facture.', subtitleCannotSend: "Vous avez besoin d'un espace de travail avec Invoices activé pour envoyer des factures.", + subtitleCannotSendWithTestDrive: "Vous avez besoin d'un espace de travail avec Invoices activé pour envoyer des factures. Faites un essai d'Expensify pour en savoir plus.", }, emptyTripResults: { title: 'Aucun voyage à afficher', diff --git a/src/languages/it.ts b/src/languages/it.ts index ba1495e2be24..7c310e0667bd 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -7703,6 +7703,7 @@ Aggiungi altre regole di spesa per proteggere il flusso di cassa aziendale.`, subtitle: 'Invia una fattura o fai un giro di prova con Expensify per saperne di più.', subtitleWithOnlyCreateButton: 'Usa il pulsante verde qui sotto per inviare una fattura.', subtitleCannotSend: 'Hai bisogno di uno spazio di lavoro con Invoices abilitato per inviare fatture.', + subtitleCannotSendWithTestDrive: 'Hai bisogno di uno spazio di lavoro con Invoices abilitato per inviare fatture. Fai un giro di prova con Expensify per saperne di più.', }, emptyTripResults: { title: 'Nessun viaggio da visualizzare', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index ac44af23ac6a..c16fc9332734 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -7609,6 +7609,7 @@ ${reportName} subtitle: '請求書を送信するか、Expensify を試用してさらに詳しく知りましょう。', subtitleWithOnlyCreateButton: '下の緑色のボタンを使って請求書を送信してください。', subtitleCannotSend: '請求書を送信するには、Invoicesが有効なワークスペースが必要です。', + subtitleCannotSendWithTestDrive: '請求書を送信するには、Invoicesが有効なワークスペースが必要です。Expensify を試用してさらに詳しく知りましょう。', }, emptyTripResults: { title: '表示する出張はありません', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index e1dd7ce9d345..1ed656734cd3 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -7674,6 +7674,7 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`, subtitle: 'Stuur een factuur of maak een testrit met Expensify om meer te weten te komen.', subtitleWithOnlyCreateButton: 'Gebruik de groene knop hieronder om een factuur te versturen.', subtitleCannotSend: 'Je hebt een werkruimte met Invoices ingeschakeld nodig om facturen te versturen.', + subtitleCannotSendWithTestDrive: 'Je hebt een werkruimte met Invoices ingeschakeld nodig om facturen te versturen. Maak een testrit met Expensify om meer te weten te komen.', }, emptyTripResults: { title: 'Geen reizen om weer te geven', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index f822e86373bc..7062684d22d8 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -7666,6 +7666,7 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`, subtitle: 'Wyślij fakturę lub wypróbuj Expensify, aby dowiedzieć się więcej.', subtitleWithOnlyCreateButton: 'Użyj zielonego przycisku poniżej, aby wysłać fakturę.', subtitleCannotSend: 'Potrzebujesz przestrzeni roboczej z włączonym Invoices, aby wysyłać faktury.', + subtitleCannotSendWithTestDrive: 'Potrzebujesz przestrzeni roboczej z włączonym Invoices, aby wysyłać faktury. Wypróbuj Expensify, aby dowiedzieć się więcej.', }, emptyTripResults: { title: 'Brak podróży do wyświetlenia', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index fa61dc79d7a1..2bfb4c708864 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -7668,6 +7668,7 @@ Adicione mais regras de gasto para proteger o fluxo de caixa da empresa.`, subtitle: 'Envie uma fatura ou faça um test drive do Expensify para saber mais.', subtitleWithOnlyCreateButton: 'Use o botão verde abaixo para enviar uma fatura.', subtitleCannotSend: 'Você precisa de um espaço de trabalho com Invoices habilitado para enviar faturas.', + subtitleCannotSendWithTestDrive: 'Você precisa de um espaço de trabalho com Invoices habilitado para enviar faturas. Faça um test drive do Expensify para saber mais.', }, emptyTripResults: { title: 'Nenhuma viagem para exibir', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 4f5c073843e2..2f66b26e38ef 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -7474,6 +7474,7 @@ ${reportName} subtitle: '发送发票或试用 Expensify,了解更多信息。', subtitleWithOnlyCreateButton: '使用下方的绿色按钮发送发票。', subtitleCannotSend: '您需要一个启用了Invoices的工作区才能发送发票。', + subtitleCannotSendWithTestDrive: '您需要一个启用了Invoices的工作区才能发送发票。试用 Expensify,了解更多信息。', }, emptyTripResults: { title: '没有行程可显示', diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx index b962db91674e..8ce4f9de1c21 100644 --- a/src/pages/Search/EmptySearchView.tsx +++ b/src/pages/Search/EmptySearchView.tsx @@ -390,8 +390,10 @@ function EmptySearchViewContent({ case CONST.SEARCH.DATA_TYPES.INVOICE: { const userCanSendInvoice = canSendInvoice(allPolicies, currentUserPersonalDetails.login); let subtitleKey: TranslationPaths = 'search.searchResults.emptyInvoiceResults.subtitle'; - if (!userCanSendInvoice) { + if (!userCanSendInvoice && hasSeenTour) { subtitleKey = 'search.searchResults.emptyInvoiceResults.subtitleCannotSend'; + } else if (!userCanSendInvoice) { + subtitleKey = 'search.searchResults.emptyInvoiceResults.subtitleCannotSendWithTestDrive'; } else if (hasSeenTour) { subtitleKey = 'search.searchResults.emptyInvoiceResults.subtitleWithOnlyCreateButton'; }