Skip to content

Show submit button with error modal for pending card transactions#87750

Draft
MelvinBot wants to merge 2 commits intomainfrom
claude-pendingCardTransactionSubmitError
Draft

Show submit button with error modal for pending card transactions#87750
MelvinBot wants to merge 2 commits intomainfrom
claude-pendingCardTransactionSubmitError

Conversation

@MelvinBot
Copy link
Copy Markdown
Contributor

Explanation of Change

When a report contains only pending Expensify Card transactions, the submit button was completely hidden across all action surfaces (report header, secondary dropdown, report preview card, and search page). This left users with no indication of why they couldn't submit.

This PR:

  1. Shows the submit button by removing the early-return checks that blocked it when all transactions are pending, across ReportPrimaryActionUtils, ReportSecondaryActionUtils, ReportPreviewActionUtils, and IOU/index.ts (canSubmitReport).
  2. Displays an error modal on click in both MoneyReportHeader and SubmitActionButton (report preview) explaining that submission is blocked because all transactions are pending.
  3. Updates the status bar message from the generic "Transaction pending. It may take a few days to post." to "All transactions are pending. You can't submit this report until they post. This may take a few days." — clearly explaining the submission restriction.

This matches OldDot behavior where the submit button is visible but clicking it shows an explanatory error.

Fixed Issues

$ #86491
PROPOSAL: #86491 (comment)

Tests

  1. Create a pending Expensify Card transaction and place it on its own report
  2. Open the report in NewDot
  3. Verify the submit button is visible
  4. Click submit
  5. Verify an error modal appears with title "Unable to submit report" and description explaining the transactions are pending
  6. Verify the status bar at the top of the report shows "All transactions are pending. You can't submit this report until they post. This may take a few days."
  7. Verify the same behavior works from the report preview card in chat
  8. Verify no errors appear in the JS console
  • Verify that no errors appear in the JS console

Offline tests

  1. Go offline
  2. Open a report with only pending Expensify Card transactions
  3. Verify the submit button is still visible
  4. Click submit
  5. Verify the error modal still appears correctly

QA Steps

  1. Create a pending Expensify Card transaction and place it on its own report
  2. Open the report in NewDot
  3. Verify the submit button is shown (previously it was hidden)
  4. Click the submit button
  5. Verify a modal appears with "Unable to submit report" and an explanation about pending transactions
  6. Verify the status bar shows the updated message about all transactions being pending
  7. Close the modal and verify you return to the report
  8. Repeat from the report preview card in a chat
  • 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 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.

Checks run

Check Result
Prettier Pass
ESLint Pass
TypeScript (tsc) Pass
Unit tests (ReportPrimaryActionUtilsTest, ReportPreviewActionUtilsTest) Pass (73/73)

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari

…d transactions

Instead of hiding the submit button when all transactions on a report are
pending Expensify Card transactions, show the button and display an error
modal when clicked explaining why submission is blocked. Also updates the
status bar message to clearly communicate the submission restriction.

Co-authored-by: Sobit Neupane <sobitneupane@users.noreply.github.com>
@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 a9ebd083..f9258b25 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -1286,7 +1286,7 @@ const translations: TranslationDeepObject<typeof en> = {
         receiptStatusText: 'Nur du kannst diesen Beleg sehen, während er gescannt wird. Schau später noch einmal vorbei oder gib die Details jetzt ein.',
         receiptScanningFailed: 'Belegerkennung fehlgeschlagen. Bitte geben Sie die Details manuell ein.',
         transactionPendingDescription: 'Transaktion ausstehend. Die Buchung kann ein paar Tage dauern.',
-        allTransactionsPendingNextStep: 'Alle Transaktionen sind ausstehend. Du kannst diesen Bericht erst einreichen, wenn sie gebucht sind. Dies kann ein paar Tage dauern.',
+        allTransactionsPendingNextStep: 'Alle Transaktionen sind ausstehend. Sie können diesen Bericht erst einreichen, wenn sie gebucht wurden. Dies kann ein paar Tage dauern.',
         companyInfo: 'Unternehmensinfos',
         companyInfoDescription: 'Wir benötigen noch ein paar weitere Angaben, bevor du deine erste Rechnung senden kannst.',
         yourCompanyName: 'Ihr Firmenname',
@@ -1475,7 +1475,7 @@ const translations: TranslationDeepObject<typeof en> = {
             dateRangeExceedsMaxDays: `Der Datumsbereich darf ${CONST.IOU.SPLITS_LIMIT} Tage nicht überschreiten.`,
             stitchOdometerImagesFailed: 'Kilometerzählerbilder konnten nicht zusammengeführt werden. Bitte versuchen Sie es später noch einmal.',
             unableToSubmitReport: 'Bericht kann nicht eingereicht werden',
-            allTransactionsPendingDescription: 'Du kannst diesen Bericht nicht einreichen, da alle Transaktionen ausstehend sind. Die Buchung kann einige Tage dauern.',
+            allTransactionsPendingDescription: 'Sie können diesen Bericht nicht einreichen, weil alle Transaktionen ausstehend sind. Es kann ein paar Tage dauern, bis sie verbucht werden.',
             nonReimbursablePayment: 'Kann nicht über Expensify bezahlt werden',
             nonReimbursablePaymentDescription: (isMultiple?: boolean) =>
                 isMultiple
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index fc7fa764..edd4b410 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -1291,7 +1291,7 @@ const translations: TranslationDeepObject<typeof en> = {
         receiptScanningFailed: 'L’analyse du reçu a échoué. Veuillez saisir les détails manuellement.',
         transactionPendingDescription: "Transaction en attente. L'inscription peut prendre quelques jours.",
         allTransactionsPendingNextStep:
-            "Toutes les transactions sont en attente. Vous ne pouvez pas soumettre ce rapport tant qu'elles ne sont pas enregistrées. Cela peut prendre quelques jours.",
+            'Toutes les transactions sont en attente. Vous ne pouvez pas soumettre cette note de frais tant qu’elles ne sont pas comptabilisées. Cela peut prendre quelques jours.',
         companyInfo: 'Informations sur l’entreprise',
         companyInfoDescription: 'Nous avons besoin de quelques informations supplémentaires avant que vous puissiez envoyer votre première facture.',
         yourCompanyName: 'Nom de votre entreprise',
@@ -1478,8 +1478,9 @@ const translations: TranslationDeepObject<typeof en> = {
             manySplitsProvided: `Le nombre maximal de répartitions autorisées est de ${CONST.IOU.SPLITS_LIMIT}.`,
             dateRangeExceedsMaxDays: `La plage de dates ne peut pas dépasser ${CONST.IOU.SPLITS_LIMIT} jours.`,
             stitchOdometerImagesFailed: 'Échec de la combinaison des images de l’odomètre. Veuillez réessayer plus tard.',
-            unableToSubmitReport: 'Impossible de soumettre le rapport',
-            allTransactionsPendingDescription: 'Vous ne pouvez pas soumettre ce rapport car toutes les transactions sont en attente. Leur enregistrement peut prendre quelques jours.',
+            unableToSubmitReport: 'Impossible de soumettre la note de frais',
+            allTransactionsPendingDescription:
+                'Vous ne pouvez pas soumettre cette note de frais, car toutes les transactions sont en attente. Leur comptabilisation peut prendre quelques jours.',
             nonReimbursablePayment: 'Impossible de payer via Expensify',
             nonReimbursablePaymentDescription: (isMultiple?: boolean) =>
                 isMultiple
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 503162db..73539e60 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -1285,7 +1285,7 @@ const translations: TranslationDeepObject<typeof en> = {
         receiptStatusText: 'Solo tu puoi vedere questa ricevuta mentre viene scansionata. Controlla più tardi o inserisci i dettagli ora.',
         receiptScanningFailed: 'Scansione della ricevuta non riuscita. Inserisci i dettagli manualmente.',
         transactionPendingDescription: 'Transazione in sospeso. Potrebbero essere necessari alcuni giorni prima che venga registrata.',
-        allTransactionsPendingNextStep: 'Tutte le transazioni sono in sospeso. Non puoi inviare questo report finché non vengono registrate. Potrebbero essere necessari alcuni giorni.',
+        allTransactionsPendingNextStep: 'Tutte le transazioni sono in sospeso. Non puoi inviare questo report finché non vengono contabilizzate. Questo potrebbe richiedere alcuni giorni.',
         companyInfo: 'Informazioni azienda',
         companyInfoDescription: 'Ci servono ancora alcuni dettagli prima che tu possa inviare la tua prima fattura.',
         yourCompanyName: 'Nome dell’azienda',
@@ -1472,7 +1472,8 @@ const translations: TranslationDeepObject<typeof en> = {
             dateRangeExceedsMaxDays: `L’intervallo di date non può superare ${CONST.IOU.SPLITS_LIMIT} giorni.`,
             stitchOdometerImagesFailed: 'Impossibile combinare le immagini del contachilometri. Riprova più tardi.',
             unableToSubmitReport: 'Impossibile inviare il report',
-            allTransactionsPendingDescription: 'Non puoi inviare questo report perché tutte le transazioni sono in sospeso. Potrebbero essere necessari alcuni giorni per la registrazione.',
+            allTransactionsPendingDescription:
+                'Non puoi inviare questo report perché tutte le transazioni sono in sospeso. Potrebbero volerci alcuni giorni prima che vengano contabilizzate.',
             nonReimbursablePayment: 'Impossibile pagare tramite Expensify',
             nonReimbursablePaymentDescription: (isMultiple?: boolean) =>
                 isMultiple
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 7f9577f9..23fde1a8 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -1268,7 +1268,7 @@ const translations: TranslationDeepObject<typeof en> = {
         receiptStatusText: 'スキャン中のレシートは、あなただけが見ることができます。後でまた確認するか、今すぐ詳細を入力してください。',
         receiptScanningFailed: 'レシートのスキャンに失敗しました。詳細を手入力してください。',
         transactionPendingDescription: '取引は保留中です。記帳されるまで数日かかる場合があります。',
-        allTransactionsPendingNextStep: 'すべての取引が保留中です。記帳されるまでこのレポートを提出できません。数日かかる場合があります。',
+        allTransactionsPendingNextStep: 'すべての取引が保留中です。記帳されるまでこのレポートを提出することはできません。処理には数日かかる場合があります。',
         companyInfo: '会社情報',
         companyInfoDescription: '最初の請求書を送信する前に、いくつか追加の情報が必要です。',
         yourCompanyName: '会社名',
@@ -1453,8 +1453,8 @@ const translations: TranslationDeepObject<typeof en> = {
             manySplitsProvided: `分割できる最大数は${CONST.IOU.SPLITS_LIMIT}件です。`,
             dateRangeExceedsMaxDays: `日付範囲は${CONST.IOU.SPLITS_LIMIT}日を超えることはできません。`,
             stitchOdometerImagesFailed: '走行距離計の画像を結合できませんでした。後でもう一度お試しください。',
-            unableToSubmitReport: 'レポートを提出できません',
-            allTransactionsPendingDescription: 'すべての取引が保留中のため、このレポートを提出できません。記帳されるまで数日かかる場合があります。',
+            unableToSubmitReport: 'レポートを送信できません',
+            allTransactionsPendingDescription: 'すべての取引が保留中のため、このレポートを提出できません。取引の反映までに数日かかる場合があります。',
             nonReimbursablePayment: 'Expensify経由では支払えません',
             nonReimbursablePaymentDescription: (isMultiple?: boolean) =>
                 isMultiple
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 5badbfff..1eef3c0d 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -1284,7 +1284,7 @@ const translations: TranslationDeepObject<typeof en> = {
         receiptStatusText: 'Alleen jij kunt deze bon zien terwijl hij wordt gescand. Kom later terug of voer de gegevens nu in.',
         receiptScanningFailed: 'Bon scannen mislukt. Voer de gegevens handmatig in.',
         transactionPendingDescription: 'Transactie in behandeling. Het kan een paar dagen duren voordat deze wordt verwerkt.',
-        allTransactionsPendingNextStep: 'Alle transacties zijn in behandeling. Je kunt dit rapport pas indienen als ze zijn verwerkt. Dit kan een paar dagen duren.',
+        allTransactionsPendingNextStep: 'Alle transacties zijn in behandeling. Je kunt dit rapport pas indienen zodra ze zijn geboekt. Dit kan een paar dagen duren.',
         companyInfo: 'Bedrijfsgegevens',
         companyInfoDescription: 'We hebben nog een paar gegevens nodig voordat je je eerste factuur kunt versturen.',
         yourCompanyName: 'Naam van je bedrijf',
@@ -1469,8 +1469,8 @@ const translations: TranslationDeepObject<typeof en> = {
             manySplitsProvided: `Het maximale aantal toegestane splitsingen is ${CONST.IOU.SPLITS_LIMIT}.`,
             dateRangeExceedsMaxDays: `Het datumbereik mag niet meer dan ${CONST.IOU.SPLITS_LIMIT} dagen zijn.`,
             stitchOdometerImagesFailed: 'Odometerafbeeldingen combineren mislukt. Probeer het later opnieuw.',
-            unableToSubmitReport: 'Kan rapport niet indienen',
-            allTransactionsPendingDescription: 'Je kunt dit rapport niet indienen omdat alle transacties in behandeling zijn. Het kan een paar dagen duren voordat ze worden verwerkt.',
+            unableToSubmitReport: 'Rapport kan niet worden ingediend',
+            allTransactionsPendingDescription: 'Je kunt dit rapport niet indienen omdat alle transacties in behandeling zijn. Het kan een paar dagen duren voordat ze zijn geboekt.',
             nonReimbursablePayment: 'Kan niet via Expensify worden betaald',
             nonReimbursablePaymentDescription: (isMultiple?: boolean) =>
                 isMultiple
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 23e944bc..e546a31a 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -1283,7 +1283,7 @@ const translations: TranslationDeepObject<typeof en> = {
         receiptStatusText: 'Tylko ty widzisz ten paragon podczas skanowania. Sprawdź ponownie później lub wprowadź szczegóły teraz.',
         receiptScanningFailed: 'Skanowanie paragonu nie powiodło się. Wprowadź dane ręcznie.',
         transactionPendingDescription: 'Transakcja w toku. Zaksięgowanie może potrwać kilka dni.',
-        allTransactionsPendingNextStep: 'Wszystkie transakcje są w toku. Nie możesz wysłać tego raportu, dopóki nie zostaną zaksięgowane. Może to potrwać kilka dni.',
+        allTransactionsPendingNextStep: 'Wszystkie transakcje są w toku. Nie możesz wysłać tego raportu, dopóki nie zostaną zaksięgowane. To może potrwać kilka dni.',
         companyInfo: 'Informacje o firmie',
         companyInfoDescription: 'Potrzebujemy jeszcze kilku informacji, zanim będziesz mógł wysłać swoją pierwszą fakturę.',
         yourCompanyName: 'Nazwa Twojej firmy',
@@ -1468,7 +1468,7 @@ const translations: TranslationDeepObject<typeof en> = {
             dateRangeExceedsMaxDays: `Zakres dat nie może przekraczać ${CONST.IOU.SPLITS_LIMIT} dni.`,
             stitchOdometerImagesFailed: 'Nie udało się połączyć zdjęć licznika kilometrów. Spróbuj ponownie później.',
             unableToSubmitReport: 'Nie można wysłać raportu',
-            allTransactionsPendingDescription: 'Nie możesz wysłać tego raportu, ponieważ wszystkie transakcje są w toku. Zaksięgowanie może potrwać kilka dni.',
+            allTransactionsPendingDescription: 'Nie możesz przesłać tego raportu, ponieważ wszystkie transakcje są w toku. Ich zaksięgowanie może zająć kilka dni.',
             nonReimbursablePayment: 'Nie można zapłacić przez Expensify',
             nonReimbursablePaymentDescription: (isMultiple?: boolean) =>
                 isMultiple
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 7651e444..4347a95a 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -1283,7 +1283,7 @@ const translations: TranslationDeepObject<typeof en> = {
         receiptStatusText: 'Só você pode ver este recibo enquanto ele está sendo digitalizado. Volte mais tarde ou insira os detalhes agora.',
         receiptScanningFailed: 'Falha ao escanear o recibo. Insira os detalhes manualmente.',
         transactionPendingDescription: 'Transação pendente. Pode levar alguns dias para ser lançada.',
-        allTransactionsPendingNextStep: 'Todas as transações estão pendentes. Você não pode enviar este relatório até que sejam lançadas. Isso pode levar alguns dias.',
+        allTransactionsPendingNextStep: 'Todas as transações estão pendentes. Você não pode enviar este relatório até que elas sejam lançadas. Isso pode levar alguns dias.',
         companyInfo: 'Informações da empresa',
         companyInfoDescription: 'Precisamos de mais alguns detalhes antes que você possa enviar sua primeira fatura.',
         yourCompanyName: 'Nome da sua empresa',
@@ -1466,8 +1466,8 @@ const translations: TranslationDeepObject<typeof en> = {
             manySplitsProvided: `O número máximo de divisões permitido é ${CONST.IOU.SPLITS_LIMIT}.`,
             dateRangeExceedsMaxDays: `O intervalo de datas não pode exceder ${CONST.IOU.SPLITS_LIMIT} dias.`,
             stitchOdometerImagesFailed: 'Falha ao combinar imagens do hodômetro. Tente novamente mais tarde.',
-            unableToSubmitReport: 'Não é possível enviar o relatório',
-            allTransactionsPendingDescription: 'Você não pode enviar este relatório porque todas as transações estão pendentes. Pode levar alguns dias para serem lançadas.',
+            unableToSubmitReport: 'Não foi possível enviar o relatório',
+            allTransactionsPendingDescription: 'Você não pode enviar este relatório porque todas as transações estão pendentes. Elas podem levar alguns dias para serem lançadas.',
             nonReimbursablePayment: 'Não é possível pagar via Expensify',
             nonReimbursablePaymentDescription: (isMultiple?: boolean) =>
                 isMultiple
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index b34e3200..1533c383 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -1244,7 +1244,7 @@ const translations: TranslationDeepObject<typeof en> = {
         receiptStatusText: '扫描期间只有你自己能看到这张收据。稍后再来查看,或立即输入详细信息。',
         receiptScanningFailed: '收据扫描失败。请手动输入详细信息。',
         transactionPendingDescription: '交易待处理。入账可能需要几天时间。',
-        allTransactionsPendingNextStep: '所有交易均待处理。在入账之前,您无法提交此报告。这可能需要几天时间。',
+        allTransactionsPendingNextStep: '所有交易都在待处理状态。在入账之前,你无法提交此报表。这可能需要几天时间。',
         companyInfo: '公司信息',
         companyInfoDescription: '在您发送第一张发票之前,我们还需要一些详细信息。',
         yourCompanyName: '您的公司名称',
@@ -1426,8 +1426,8 @@ const translations: TranslationDeepObject<typeof en> = {
             manySplitsProvided: `允许的最大拆分数为 ${CONST.IOU.SPLITS_LIMIT}。`,
             dateRangeExceedsMaxDays: `日期范围不能超过 ${CONST.IOU.SPLITS_LIMIT} 天。`,
             stitchOdometerImagesFailed: '合并里程表图片失败。请稍后重试。',
-            unableToSubmitReport: '无法提交报告',
-            allTransactionsPendingDescription: '您无法提交此报告,因为所有交易均待处理。入账可能需要几天时间。',
+            unableToSubmitReport: '无法提交报表',
+            allTransactionsPendingDescription: '您无法提交此报表,因为所有交易都在待处理状态。它们可能需要几天时间才能入账。',
             nonReimbursablePayment: '无法通过 Expensify 付款',
             nonReimbursablePaymentDescription: (isMultiple?: boolean) =>
                 isMultiple ? '一个或多个所选报告没有可报销的费用。请再次检查费用,或手动将其标记为已支付。' : '该报告没有可报销的费用。请再次检查费用,或手动将其标记为已支付。',

Note

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

View workflow run

The PR now shows the submit button for reports with only pending
transactions (displaying an error modal on click), so the test
should expect SUBMIT to be included in secondary actions.

Co-authored-by: Sobit Neupane <sobitneupane@users.noreply.github.com>
@MelvinBot
Copy link
Copy Markdown
Contributor Author

Fixed the failing check: updated ReportSecondaryActionUtilsTest.ts — the test "should not include SUBMIT option for admin with only pending transactions" was asserting the old behavior. Since this PR intentionally shows the submit button (to display an error modal), the test now expects SUBMIT to be included and the description was updated accordingly.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 13, 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 Δ
src/libs/ReportPreviewActionUtils.ts 92.85% <ø> (-0.13%) ⬇️
src/libs/ReportPrimaryActionUtils.ts 91.96% <ø> (-0.08%) ⬇️
src/libs/ReportSecondaryActionUtils.ts 93.53% <ø> (-0.03%) ⬇️
src/libs/actions/IOU/index.ts 79.73% <ø> (-0.08%) ⬇️
...c/components/MoneyReportHeaderStatusBarSection.tsx 2.32% <0.00%> (ø)
...m/MoneyRequestReportPreview/SubmitActionButton.tsx 0.00% <0.00%> (ø)
src/components/MoneyReportHeader.tsx 0.00% <0.00%> (ø)
... and 17 files with indirect coverage changes

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.

3 participants