Skip to content

Add a Rejected suggested search that appears once the user has a rejected expense - #104438

Draft
MelvinBot wants to merge 5 commits into
mainfrom
claude-rejectedSuggestedSearch
Draft

MelvinBot wants to merge 5 commits into
mainfrom
claude-rejectedSuggestedSearch

Conversation

@MelvinBot

Copy link
Copy Markdown
Contributor

Explanation of Change

Users lose track of expenses after they are rejected. This PR adds a Rejected suggested search to the Expense reports section of the Search left-hand nav, so users can find those expenses.

  • What it opens: type:expense declined:yes, using the Rejected filter added in [Payment due @QichenZhu] Add Rejected search filter for expenses and expense reports. It uses the same ThumbsDown icon as the Rejected filter chip.
  • When it appears: a new useHasRejectedExpense hook returns true when any transaction has the rejected-expense violation (hasTransactionBeenRejected). It also returns true when any report was rejected as a whole (hasReportBeenRejectedToSubmitter), because whole-report rejections don't add per-transaction violations. Both checks use boolean Onyx selectors, so the nav only re-renders when the answer changes.
  • Why it stays: the first time the hook returns true, useSearchTypeMenuSections sets a new nvp_hasSeenRejectedSuggestedSearch NVP. This follows the nvp_hasSeenForYouTodo pattern. The item then stays visible even after every rejection is resolved, so it doesn't appear and disappear.
  • Visibility wiring: getSuggestedSearchesVisibility / createTypeMenuSections take a new shouldShowRejectedSuggestion flag. The item has its own empty state and translations in all locales.

Not included in this PR:

  • Held suggested search. Its held:yes filter hasn't merged yet. It's still a draft in Add Held search filter for expenses. Held can follow the same pattern once that PR lands.

Open questions for reviewers:

  • The new nvp_hasSeenRejectedSuggestedSearch NVP is written through SetNameValuePair. An internal engineer should confirm the backend accepts this NVP name.
  • The issue says expenses in a fully rejected report should appear under Rejected. That depends on backend matching for declined:yes, which I couldn't verify from the App repo.

Fixed Issues

$ #103339
PROPOSAL: #103339 (comment)

Tests

// TODO: The human co-author must fill out the tests you ran before marking this PR as "ready for review"
// Please describe what tests you performed that validates your changed worked.

  • Verify that no errors appear in the JS console

Offline tests

QA Steps

// TODO: The human co-author must fill out the QA tests you ran before marking this PR as "ready for review".
// Please describe what QA needs to do to validate your changes and what areas do they need to test for regressions.

  • 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 any copy / text that was added to the app 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 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 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 the PR adds or modifies the UI:
    • I asked an AI agent to review the changes for accessibility issues and addressed its findings.
    • I tested with a screen reader (VoiceOver on macOS) and verified all new/changed elements are reachable with a logical focus order.
    • I verified all new/changed elements have meaningful accessible names and roles.
    • I verified state changes are announced (e.g. checked/unchecked, expanded/collapsed, selected).
  • 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

…cted expense

Co-authored-by: Krishna <Krishna2323@users.noreply.github.com>
@MelvinBot
MelvinBot requested a review from a team October 20, 2026 04:05
@melvin-bot melvin-bot Bot added Melvin-Test-Android Melvin-Test-Web Triggers Melvin to run the testing steps of the PR on web labels Oct 20, 2026
@MelvinBot

Copy link
Copy Markdown
Contributor Author

I created this PR from an upstream branch because I don't have push access to your fork.

To take ownership of this branch and push updates, run:

git remote add upstream https://github.com/Expensify/App.git
git fetch upstream claude-rejectedSuggestedSearch
git checkout -b claude-rejectedSuggestedSearch upstream/claude-rejectedSuggestedSearch
git push -u origin claude-rejectedSuggestedSearch

Then you can close this PR and open a new one from your fork.

@OSBotify

This comment has been minimized.

@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

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/CONST/index.ts 95.90% <ø> (ø)
src/ONYXKEYS.ts 100.00% <ø> (ø)
src/libs/ExportOnyxState/masking.ts 80.95% <ø> (ø)
src/libs/SearchSuggestionUtils.ts 95.18% <100.00%> (+0.27%) ⬆️
src/libs/SearchUIUtils.ts 74.31% <100.00%> (+0.04%) ⬆️
src/hooks/useHasRejectedExpense.ts 96.87% <96.87%> (ø)
src/hooks/useSearchTypeMenuSections.ts 93.65% <90.00%> (-3.79%) ⬇️
src/libs/actions/Search.ts 66.57% <0.00%> (-0.46%) ⬇️
... and 4280 files with indirect coverage changes

Co-authored-by: Krishna <Krishna2323@users.noreply.github.com>
@MelvinBot

Copy link
Copy Markdown
Contributor Author

Fixed the failing Oxfmt check. Oxfmt's import sorting needs a blank line between the import type group and the external value import in src/hooks/useHasRejectedExpense.ts. I added that blank line in d0aedce. Other hooks, such as useTodoSearchResults.ts, already use this layout.

Check independent approval is also failing. It needs a reviewer approval and does not need a code change.


view run

@MelvinBot

MelvinBot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Android test steps verification results: ⚠️ partial

The Rejected suggested search appears with its thumbs-down icon once a rejection exists and opens the type:expense declined:yes filter, but it disappeared after the rejected expense was deleted, which contradicts the PR's claim that it stays visible permanently. The PR's Tests section is still a TODO, so these steps come from the PR description and the linked issue.
Rejected chip absent after deleting the rejected expense

Step Status
Before any rejection, the Spend (Reports) tab shows no Rejected suggested searchThe suggested-search row showed only Needs approval, Drafts, Reports, and Expenses. Scrolling the row found no Rejected item.
Spend tab before any rejection, no Rejected chip
✅
Create a workspace, then create, submit, and reject a manual expense as the approverCreated a $25.00 "Test Merchant" expense, submitted it, then used More > Reject with a reason. The banner read: "This report was rejected. Waiting on you to fix the issues and manually resubmit."
Report shows rejected banner
✅
After the rejection, a Rejected suggested search appears with a thumbs-down iconThe row showed Ready to pay, Needs approval, Drafts, Reports, and Rejected. Rejected had a thumbs-down icon.
Rejected chip with thumbs-down icon
✅
Tapping Rejected opens the type:expense declined:yes searchThe search applied a "Rejected: Yes" filter, which matches typing type:expense declined:yes. It showed the "No rejected expenses" empty state, not the rejected expense. The report had already returned to Draft after the whole-report rejection, so it no longer matched the filter.
Rejected filter applied, No rejected expenses empty state
✅
After the rejection is resolved, Rejected stays visibleAfter the rejected report was deleted, Rejected disappeared from the row. It was still gone after leaving the Spend tab and coming back. This may be linked to the PR's open question about whether the backend accepts the new nvp_hasSeenRejectedSuggestedSearch NVP.
Rejected chip absent after deleting the rejected expense
❌
No crash or red error screen during the flowThe app stayed in the foreground with no crashes or error screens from sign-in through deletion.
✅

view run · view recording

@MelvinBot

MelvinBot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Web test steps verification results: ✅ pass

The Rejected suggested search appears only after a rejection, stays visible after the rejection is resolved, and opens type:expense declined:yes, but that search never listed the rejected expense because Reject immediately reopens the report as a Draft. The PR's Tests section is still a TODO, so these steps come from the PR description and the linked issue.
Rejected nav item still present after the rejected expense was deleted

Step Status
Before any rejection, the Expense reports section has no Rejected itemThe section listed only Expenses, Reports, Drafts, Needs approval, and Ready to pay.
Expense reports nav with no Rejected item before any rejection
✅
Create, submit, and reject a manual expense as the approverCreated a $25.00 "Melvin Test Merchant" expense, submitted the report, then used More > Reject with a reason. The banner read: "This report was rejected. Waiting on you to fix the issues and manually resubmit."
Report showing rejected state
✅
A Rejected item appears in the Expense reports section with a thumbs-down iconA new Rejected item appeared in Expense reports with a thumbs-down icon.
Rejected item with thumbs-down icon in Expense reports nav
✅
Clicking Rejected opens the type:expense declined:yes searchThe search opened with a "Rejected: Yes" filter. It showed the "No rejected expenses" empty state, not the expense just rejected. Rejecting the report returned it to Draft, so it no longer matched the filter.
Rejected search showing No rejected expenses empty state
✅
Rejected stays visible after the rejection is resolvedAfter the rejected report was deleted, Rejected was still visible after leaving the Spend page and coming back. The test did not reload the browser page, because a reload can lock the test session out of sign-in. On Android, the same step failed: Rejected disappeared after the report was deleted.
Rejected nav item still present after the rejected expense was deleted
✅
No new JS console errors related to Search or the Rejected itemNo error banners, red toasts, or failure dialogs appeared during the flow. The test tool can't read the browser console on this setup, so this check relies on what the screen showed.
✅

view run · view recording

@Krishna2323

Copy link
Copy Markdown
Contributor

@MelvinBot resolve conflicts

…tedSearch

Co-authored-by: Krishna <Krishna2323@users.noreply.github.com>

# Conflicts:
#	tests/unit/Search/SearchUIUtilsTest.ts
@MelvinBot

Copy link
Copy Markdown
Contributor Author

I resolved the merge conflicts with main and pushed the merge commit (f1bf21d).

The only conflict was in tests/unit/Search/SearchUIUtilsTest.ts. This PR and main each added a new test at the same spot in the getSuggestedSearchesVisibility block. I kept both tests:

  • "Should show the Rejected suggestion only when shouldShowRejectedSuggestion is true" (from this PR)
  • "Should not throw when employeeList contains a null entry" (from main)

All 46 getSuggestedSearchesVisibility tests pass locally, including both of these.

@OSBotify

This comment has been minimized.

@MelvinBot

Copy link
Copy Markdown
Contributor Author

The failing typecheck check is unrelated to this PR, so I didn't push a fix. The errors come from two PRs that merged to main on Oct 21. typecheck fails the same way on other open PRs, such as cmartins-insights-remove-beta-checks.

Analysis: Running npm run typecheck on this branch finds errors in only two files. This PR changes neither of them:

Evidence: None of the 21 files this PR changes has a type error. Once main is fixed, merge main into this branch again and the check should pass. Check independent approval is also failing, but it's a review-gate check, not a code failure. The test jobs were still pending when I checked.


view run

@MelvinBot

Copy link
Copy Markdown
Contributor Author

I didn't push a fix because nothing has changed since my previous comment. typecheck is still the only failing code check, and the errors still come from main, not this PR.

Once main has a fix, ask me to merge main into this branch and the check should pass.


view run

Comment thread src/hooks/useHasRejectedExpense.ts Outdated
Comment on lines +13 to +17
const hasRejectedTransactionSelector = (allTransactionViolations: OnyxCollection<TransactionViolations>): boolean =>
Object.values(allTransactionViolations ?? {}).some((transactionViolations) => hasTransactionBeenRejected(transactionViolations));

// A whole-report rejection doesn't add a violation to the report's transactions, so it has to be checked on the report.
const hasRejectedReportSelector = (allReports: OnyxCollection<Report>): boolean => Object.values(allReports ?? {}).some((report) => hasReportBeenRejectedToSubmitter(report));

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.

These selectors also match rejections on expenses the current user doesn't own.

Repro: an approver rejects one expense and one report from a submitter. On the approver's account, the server copy of transactionViolations_* still has autoReportedRejectedExpense with rejectedBy set to the approver, and the report matches hasReportBeenRejectedToSubmitter with ownerAccountID set to the submitter.

So hasRejectedExpense is true for the approver, the NVP gets set, and "Rejected" stays in their nav even though none of their own expenses were rejected.

@MelvinBot please investigate

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.

You're right. Neither selector checks who owns the expense, so an approver or admin who rejects someone else's expense trips the hook and gets the NVP set.

Root cause

Recommended fix: limit both checks to reports the current user owns. The violation doesn't identify the submitter, so the expense path has to go from violation to transaction (reportID) to report (ownerAccountID). isCurrentUserSubmitter already does the owner check. Checking rejectedBy !== currentUserLogin isn't enough, because a second admin who didn't reject the expense would still match.

Sketch

This uses closure selectors, the same pattern as useReportTransactionViolations.ts:15. The last selector still returns a boolean, so the nav only re-renders when the answer changes.

function useHasRejectedExpense(): boolean {
    const {accountID} = useCurrentUserPersonalDetails();

    // 1. IDs of transactions with the rejected-expense violation (usually a short list)
    const [rejectedTransactionIDs = []] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {selector: rejectedTransactionIDsSelector});

    // 2. The reports those transactions live on
    const [rejectedTransactionReportIDs = []] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {selector: reportIDsForTransactionsSelector(rejectedTransactionIDs)});

    // 3. True only if the current user owns a report that was rejected, or that holds a rejected expense
    const [hasRejectedExpense = false] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {
        selector: hasOwnRejectionSelector(accountID, rejectedTransactionReportIDs),
    });
    return hasRejectedExpense;
}

hasOwnRejectionSelector returns report.ownerAccountID === accountID && (hasReportBeenRejectedToSubmitter(report) || rejectedTransactionReportIDs.includes(report.reportID)).

Test accounts that already have nvp_hasSeenRejectedSuggestedSearch set will keep seeing "Rejected" after the fix. Reset that NVP before you retest.

There's a related gap: the suggested query is type:expense declined:yes with no from:me. An approver who has their own rejected expense may also see others' rejections in the results, depending on how the backend scopes declined:yes. I couldn't verify that from the App repo.


Reply with @MelvinBot implement this to push the fix to this PR, or @MelvinBot <your feedback> to change the approach.

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.

@MelvinBot implement this

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.

Done in 97af161. "Rejected" now appears only when one of your own expenses or reports was rejected.

useHasRejectedExpense.ts now:

  • Counts a whole-report rejection only on a report you own.
  • Traces each rejected expense to its report and counts it only if you own that report.
  • Counts a rejected expense that has no report. Rejecting an expense on an instantly submitted report moves it out of the report, and unreported expenses sync only to their owner. Without this, the submitter would never see "Rejected" in that case.
  • Skips expenses you rejected yourself. The approver's device keeps an optimistic copy of the expense with no report, so the rule above would otherwise match it.

I added useHasRejectedExpenseTest.tsx. It covers the submitter, the approver who rejected, and a second admin. Lint, typecheck, the React Compiler check, and spellcheck pass on the changed files. All 706 tests pass, including the Search tests.

Before you retest, reset nvp_hasSeenRejectedSuggestedSearch on the approver account. If that flag is already set, "Rejected" stays visible.

I haven't tested this in the App. One case is unconfirmed: whether the server syncs an unreported rejected expense to a second admin. If it does, that admin would still see "Rejected".


view run

Comment thread src/hooks/useHasRejectedExpense.ts Outdated
Comment on lines +13 to +17
const hasRejectedTransactionSelector = (allTransactionViolations: OnyxCollection<TransactionViolations>): boolean =>
Object.values(allTransactionViolations ?? {}).some((transactionViolations) => hasTransactionBeenRejected(transactionViolations));

// A whole-report rejection doesn't add a violation to the report's transactions, so it has to be checked on the report.
const hasRejectedReportSelector = (allReports: OnyxCollection<Report>): boolean => Object.values(allReports ?? {}).some((report) => hasReportBeenRejectedToSubmitter(report));

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.

@MelvinBot please investigate: the report check here shows "Rejected" for whole-report rejections, but declined:yes doesn't seem to return those expenses.

Repro: an approver rejects two expenses individually and one whole report (5778504925457019). The report matches hasReportBeenRejectedToSubmitter, but type:expense declined:yes only returns the two individually rejected expenses (reports 4298380125836590 and 8678739946184850). Nothing from the rejected report comes back. I checked this from the approver's account.

Can you confirm whether the backend's declined:yes match includes expenses in a fully rejected report? If not, a submitter whose whole report was rejected will see "Rejected" in the nav but get "No rejected expenses".

@MelvinBot

Copy link
Copy Markdown
Contributor Author

No. As far as I can tell, type:expense declined:yes matches only expenses rejected one by one. A whole-report rejection is matched only by type:expense-report declined:yes. So the problem you describe is real: a submitter whose whole report was rejected sees "Rejected" in the nav and then gets "No rejected expenses".

I couldn't read the backend search code from here, so I haven't confirmed the exact backend condition. The evidence comes from the PR that added the filter, and it all points the same way:

  • The filter's own test plan expects this split. In [Payment due @QichenZhu] Add Rejected search filter for expenses and expense reports, the approver rejects one expense on report 1 and the whole of report 2. Step 7 expects Expenses + Rejected: Yes to list "only the rejected expense". Step 13 expects Reports + Rejected: Yes to list "only the second report". Those checks were run from the submitter's account, so the approver account doesn't explain your result.
  • A whole-report rejection leaves no marker on the expenses. RejectExpenseReport only updates the report (state Open, next step "rejectedReport") and adds report actions. No transaction violation is written. This PR's own comment says so at useHasRejectedExpense.ts:16-17 and ReportUtils.ts:1614-1620.
  • The App doesn't drop any results. No client code filters search results by declined. The backend alone decides which rows come back.

This conflicts with the issue. [$175] Add a "Rejected" and a "Held" suggested search that appears once a user has rejected/held expenses says: "If an entire report is rejected, the expenses in that report should also display in that filter."

What's needed: an internal engineer has to change the backend so that type:expense declined:yes also matches expenses on a report rejected back to the submitter. That reverses step 7 of the filter PR, so the issue owner should confirm it first. If the backend isn't changing, remove the report check (hasRejectedReportSelector) so the nav item appears only when its search can return results. A submitter whose only rejection was a whole report would then never see the item.

How the two checks differ
  • The nav item appears when hasTransactionBeenRejected is true (the autoReportedRejectedExpense violation) or when hasReportBeenRejectedToSubmitter is true (report Open with next step rejectedReport).
  • The item opens type:expense declined:yes (SearchSuggestionUtils.ts:262-270). On expenses, that query matches only the violation case.
  • So the report check makes the item appear for a case its search can't return.

@Krishna2323

Copy link
Copy Markdown
Contributor

@MelvinBot resolve conflicts

@melvin-bot

melvin-bot Bot commented Oct 27, 2026

Copy link
Copy Markdown

⚠️ Something went wrong. This may be a transient issue — try again. If it persists, check status.anthropic.com.

@Krishna2323

Copy link
Copy Markdown
Contributor

@MelvinBot resolve conflicts

…tedSearch

Co-authored-by: Krishna <Krishna2323@users.noreply.github.com>

# Conflicts:
#	src/hooks/useSearchTypeMenuSections.ts
@MelvinBot

Copy link
Copy Markdown
Contributor Author

I merged main into this branch and fixed the conflict in src/hooks/useSearchTypeMenuSections.ts (commit caa633f).

main removed the useMemo wrapper around createTypeMenuSections because React Compiler now handles it, and it added omitTravelApprovalMenuItems. I kept main's version and added this PR's setHasSeenRejectedSuggestedSearch import and shouldShowRejectedSuggestion argument.

Checks:

  • ESLint and the React Compiler check pass.
  • No type errors in the files this PR changes.
  • SearchUIUtilsTest and SearchRouterNavigationTest pass: 699 of 699 tests.

view run

@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 16950479..64175f48 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -10319,10 +10319,7 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc
                 title: 'Keine zu bezahlenden Ausgaben',
                 subtitle: 'Glückwunsch! Du hast die Ziellinie überquert.',
             },
-            emptyRejectedResults: {
-                title: 'Keine abgelehnten Ausgaben',
-                subtitle: 'Nichts zu korrigieren. Gute Arbeit!',
-            },
+            emptyRejectedResults: {title: 'Keine abgelehnten Ausgaben', subtitle: 'Nichts zu beheben. Gute Arbeit!'},
             emptyExportResults: {
                 title: 'Keine Spesen zum Exportieren',
                 subtitle: 'Zeit, es ruhig angehen zu lassen – gute Arbeit.',
diff --git a/src/languages/el.ts b/src/languages/el.ts
index 13ed8bb5..4c435336 100644
--- a/src/languages/el.ts
+++ b/src/languages/el.ts
@@ -10526,10 +10526,7 @@ ${reportName}`,
                 title: 'Δεν υπάρχουν έξοδα προς πληρωμή',
                 subtitle: 'Συγχαρητήρια! Περάσατε τη γραμμή τερματισμού.',
             },
-            emptyRejectedResults: {
-                title: 'Δεν υπάρχουν απορριφθέντα έξοδα',
-                subtitle: 'Τίποτα για διόρθωση. Μπράβο!',
-            },
+            emptyRejectedResults: {title: 'Δεν υπάρχουν απορριφθείσες δαπάνες', subtitle: 'Δεν υπάρχει τίποτα για διόρθωση. Μπράβο!'},
             emptyExportResults: {
                 title: 'Δεν υπάρχουν έξοδα για εξαγωγή',
                 subtitle: 'Ώρα να χαλαρώσετε, μπράβο σας.',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 145d96fa..9209baea 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -10157,10 +10157,7 @@ ${reportName}`,
                 title: 'No hay gastos para pagar',
                 subtitle: '¡Felicidades! Has cruzado la línea de meta.',
             },
-            emptyRejectedResults: {
-                title: 'No hay gastos rechazados',
-                subtitle: 'Nada que corregir. ¡Buen trabajo!',
-            },
+            emptyRejectedResults: {title: 'No hay gastos rechazados', subtitle: 'Nada que corregir. ¡Buen trabajo!'},
             emptyExportResults: {
                 title: 'No hay gastos para exportar',
                 subtitle: 'Es hora de relajarse, buen trabajo.',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index da0ace96..6a3f45ce 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -10345,10 +10345,7 @@ Ajoutez davantage de règles de dépenses pour protéger la trésorerie de l’e
                 title: 'Aucune dépense à payer',
                 subtitle: 'Félicitations ! Vous avez franchi la ligne d’arrivée.',
             },
-            emptyRejectedResults: {
-                title: 'Aucune dépense rejetée',
-                subtitle: 'Rien à corriger. Beau travail !',
-            },
+            emptyRejectedResults: {title: 'Aucune dépense rejetée', subtitle: 'Rien à corriger. Beau travail !'},
             emptyExportResults: {
                 title: 'Aucune dépense à exporter',
                 subtitle: 'Il est temps de se détendre, beau travail.',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 7ffc642b..faf3dddb 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -10273,10 +10273,7 @@ Aggiungi altre regole di spesa per proteggere il flusso di cassa aziendale.`,
                 title: 'Nessuna spesa da pagare',
                 subtitle: 'Congratulazioni! Hai tagliato il traguardo.',
             },
-            emptyRejectedResults: {
-                title: 'Nessuna spesa rifiutata',
-                subtitle: 'Niente da correggere. Ottimo lavoro!',
-            },
+            emptyRejectedResults: {title: 'Nessuna spesa rifiutata', subtitle: 'Niente da correggere. Bel lavoro!'},
             emptyExportResults: {
                 title: 'Nessuna spesa da esportare',
                 subtitle: 'È il momento di rilassarsi, bel lavoro.',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index d895db16..04be4494 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -10121,10 +10121,7 @@ ${reportName}`,
                 title: '支払う経費はありません',
                 subtitle: 'おめでとうございます!ゴールに到達しました。',
             },
-            emptyRejectedResults: {
-                title: '却下された経費はありません',
-                subtitle: '修正が必要なものはありません。お疲れさまでした!',
-            },
+            emptyRejectedResults: {title: '却下された経費はありません', subtitle: '修正する箇所はありません。よくできました!'},
             emptyExportResults: {
                 title: 'エクスポートする経費はありません',
                 subtitle: 'ひと休みする時間です、お疲れさまでした。',
@@ -10374,7 +10371,7 @@ ${reportName}`,
             submit: '下書き',
             approve: '承認が必要',
             pay: '支払いの準備完了',
-            rejected: '却下済み',
+            rejected: '却下されました',
             accounting: '会計',
             export: 'エクスポート待ち',
             unapprovedCash: '現金発生主義',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index fff120a7..0821040a 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -10242,10 +10242,7 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`,
                 title: 'Geen uitgaven om te betalen',
                 subtitle: 'Gefeliciteerd! Je hebt de finish gehaald.',
             },
-            emptyRejectedResults: {
-                title: 'Geen afgekeurde uitgaven',
-                subtitle: 'Niets om te corrigeren. Goed gedaan!',
-            },
+            emptyRejectedResults: {title: 'Geen afgekeurde uitgaven', subtitle: 'Niets om te herstellen. Goed gedaan!'},
             emptyExportResults: {
                 title: 'Geen uitgaven om te exporteren',
                 subtitle: 'Tijd om rustig aan te doen, goed gedaan.',
@@ -10505,7 +10502,7 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`,
             submit: 'Concepten',
             approve: 'Moet worden goedgekeurd',
             pay: 'Klaar om te betalen',
-            rejected: 'Afgekeurd',
+            rejected: 'Afgewezen',
             accounting: 'Boekhouding',
             export: 'Wachten op export',
             unapprovedCash: 'Kasverplichtingen',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index b4df9eb5..f73c316d 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -10258,10 +10258,7 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`,
                 title: 'Brak wydatków do opłacenia',
                 subtitle: 'Gratulacje! Przekroczyłeś linię mety.',
             },
-            emptyRejectedResults: {
-                title: 'Brak odrzuconych wydatków',
-                subtitle: 'Nie ma nic do poprawienia. Dobra robota!',
-            },
+            emptyRejectedResults: {title: 'Brak odrzuconych wydatków', subtitle: 'Nic do poprawy. Dobra robota!'},
             emptyExportResults: {
                 title: 'Brak wydatków do wyeksportowania',
                 subtitle: 'Czas trochę odetchnąć, dobra robota.',
@@ -10527,7 +10524,7 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`,
             submit: 'Szkice',
             approve: 'Wymaga zatwierdzenia',
             pay: 'Gotowe do zapłaty',
-            rejected: 'Odrzucone',
+            rejected: 'Odrzucono',
             accounting: 'Księgowość',
             export: 'Oczekuje na eksport',
             unapprovedCash: 'Rozliczenia kasowe',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index a4c4c81e..d96ecf89 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -10235,10 +10235,7 @@ Adicione mais regras de gasto para proteger o fluxo de caixa da empresa.`,
                 title: 'Nenhuma despesa para pagar',
                 subtitle: 'Parabéns! Você cruzou a linha de chegada.',
             },
-            emptyRejectedResults: {
-                title: 'Nenhuma despesa rejeitada',
-                subtitle: 'Nada para corrigir. Bom trabalho!',
-            },
+            emptyRejectedResults: {title: 'Nenhuma despesa rejeitada', subtitle: 'Nada para corrigir. Bom trabalho!'},
             emptyExportResults: {
                 title: 'Nenhuma despesa para exportar',
                 subtitle: 'Hora de relaxar, bom trabalho.',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index c40e62e7..3c2fc64b 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -9854,10 +9854,7 @@ ${reportName}`,
                 title: '暂无可支付的报销',
                 subtitle: '恭喜!你已冲过终点线。',
             },
-            emptyRejectedResults: {
-                title: '暂无被拒绝的报销',
-                subtitle: '没有需要修正的内容。干得好!',
-            },
+            emptyRejectedResults: {title: '无被拒的报销', subtitle: '没什么需要修改的。干得好!'},
             emptyExportResults: {
                 title: '没有可导出的报销费用',
                 subtitle: '该放松一下了,干得不错。',

Note

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

View workflow run

… expenses

Co-authored-by: Krishna <Krishna2323@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Melvin-Test-Android Melvin-Test-Web Triggers Melvin to run the testing steps of the PR on web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants