Repository navigation
Add Translate to receipts behind the receiptTranslation beta - #105350
Conversation
Adds a Translate button to the Receipt modal and a Translate icon button to the receipt thumbnail hover row on web and desktop. While translating, a scanning line runs over the receipt and the button row becomes a spinner. The result is drawn as a receipt card with a "View original" button. Translations are saved on this device per receipt source and locale, so a replaced receipt is translated again. The TranslateReceipt command name and response shape are placeholders until Expensify/Web-Expensify#57518 is final. Signed-off-by: krishna2323 <belivethatkg@gmail.com>
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running: npx bun ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
Puts the RAM-only translation state in the safe keys and the saved translations in the masked keys, since they hold receipt text. Also stops exporting the TranslatedReceipt type, which nothing else uses. Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Keeps the scanning line inside the receipt image instead of across the whole modal, and fades its tint toward the bottom like the design. The translated card now fills its width, uses the design's text sizes and spacing, shows the first line as the store name in bold, and uses the swap arrows icon for View original. Signed-off-by: krishna2323 <belivethatkg@gmail.com>
The card is 400px wide with 40px padding. Rows in a group are 8px apart, dividers have 20px on each side, and text lines that follow each other stack as one block, like the address under the store name. Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Translation errors now show in a growl instead of under the receipt, as agreed on the issue. The viewer stays on the original receipt and can press Translate again. Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
…r visible Signed-off-by: krishna2323 <belivethatkg@gmail.com>
…r visible Signed-off-by: krishna2323 <belivethatkg@gmail.com>
…late' into krishna2323/105053-receipt-translate
…ceipt-translate # Conflicts: # src/CONST/index.ts
…323/105053-receipt-translate # Conflicts: # src/components/ReportActionItem/MoneyRequestReceiptView.tsx
…323/105053-receipt-translate Signed-off-by: krishna2323 <belivethatkg@gmail.com>
|
@MelvinBot review |
|
🤖 Web test steps verification results: Receipt testing was blocked because the account has no expenses and the supported browser interface cannot upload receipts. Source review found three P2 issues, detailed in steps 2, 3, and 6 below; these were not runtime-verified.
|
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
|
@codex review |
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
🚧 dubielzyk-expensify has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
Based on what I saw from the video of the animation in the issue, I wonder if we could slightly update the animation:
Thoughts? |
… hover zoom over receipt buttons Signed-off-by: krishna2323 <belivethatkg@gmail.com>
…expenses Signed-off-by: krishna2323 <belivethatkg@gmail.com>
|
@daledah thanks, both fixed:
|
|
Thanks all!
|
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
…hile the receipt is scanning Signed-off-by: krishna2323 <belivethatkg@gmail.com>
Reviewer Checklist
Screenshots/VideosiOS: HybridAppios.movMacOS: Chrome / Safariweb-resize.mp4 |
|
🚧 JmillsExpensify has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
The latest is looking very good! Feels very close to a release candidate, such that most everything else on my list of improvements can be handled in a separate PR. Do we want to focus on getting this one merged and then focus on downstream improvements separately? |
|
In terms of the wishlist, I do think that part of translating the receipt is getting the commas and periods right. For instance, if I was reviewing as an accountant in the US and I didn't know that Colombian Pesos used periods instead, I might be confused when I saw 22.000,00 on the receipt. To that US accountant, they'd expect to see 22,000.00. So @lakchote this is something to consider in the core translation piece. |
|
@JmillsExpensify Yes, let's merge this one and do the rest separately. The commas and periods are handled in https://github.com/Expensify/Web-Expensify/pull/58371, which merged this morning, so 22.000,00 will show as 22,000.00 for a US reviewer. A second backend PR sends the receipt's currency code, which @Krishna2323 can show in a follow-up. It's approved too. |
JmillsExpensify
left a comment
There was a problem hiding this comment.
Niiice, officially approving on my end.
|
@JmillsExpensify @Krishna2323 the backend PR that sends the currency code is merged now. It isn't on production yet. I'll confirm here once it is. |
lakchote
left a comment
There was a problem hiding this comment.
Looks good, thanks @Krishna2323.
|
🚧 lakchote has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
Awesome, I'll work with CX on getting customers on the beta. |
|
🚀 Deployed to staging by https://github.com/lakchote in version: 9.5.37-0 🚀
|
|
No help site update needed — receipt translation remains behind the |
|
@Krishna2323 @MelvinBot @daledah Is the
|
|
I can’t confirm that An internal engineer should check the specific QA account in Supportal and enable |
|
Deploy Blocker #106690 was identified to be related to this PR. |
|
🚀 Deployed to production by https://github.com/yuwenmemon in version: 9.5.37-1 🚀
Bundle Size Analysis (Sentry): |


Explanation of Change
Adds a
Translateoption for receipts behind thereceiptTranslationbeta.Translatebutton betweenCropandReplace. While a translation runs, a scanning line moves over the receipt image and the button row shows a spinner. PDFs show only the spinner. The result is shown as a translated receipt card using six row types (heading,text,labelValue,item,total,divider). Rows the backend couldn't translate (isOriginal) are shown as plain left-aligned text. The disclaimer and aView originalbutton sit in the footer, so the disclaimer is always visible, even on tall receipts. Closing the modal always brings back the original receipt.Translateicon button appears on hover. Clicking it starts the translation and opens the Receipt modal. As agreed in the issue, the thumbnail always shows the original receipt and its tooltip always saysTranslate.receiptTranslations_<transactionID>, keyed by the viewer's locale:{receiptID, state, sourceLanguage, rows}. A saved translation is only used when itsreceiptIDmatches the current receipt. As agreed in the issue, a replaced receipt isn't translated automatically. It's translated the next timeTranslateis pressed. The in-progress state and whether the translation is shown live in a RAM-only key (receiptTranslationState_<transactionID>), so the modal and the thumbnail share them.unreadableandalreadyInLanguagecome from the translation'sstate. A failed request shows the generic error.Fixed Issues
$ #105053
PROPOSAL: N/A
Tests
Prerequisite: enable the
receiptTranslationbeta for the test account. Theallbeta doesn't include it, so the account needs it added directly.Translateicon button appears between the add receipt and expand buttons.View originalbutton show in the footer without scrolling, even on a tall receipt.View original. Verify that the original image is shown with the full button row, includingTranslate.Translate.Translate. Verify that the saved translation appears right away, with no scanning line.Translate. Verify that a new translation is requested and shown in the new language.Translateand verify that a new translation is requested instead of showing the old one.Translate.Translateisn't shown.receiptTranslationbeta. Verify thatTranslatedoesn't show anywhere.Offline tests
Translatebutton in the Receipt modal and the hover button on the thumbnail are both disabled.QA Steps
Same as tests. The backend
TranslateReceiptcommand is on production. The QA account needs thereceiptTranslationbeta, which theallbeta doesn't include.Verify that no errors appear in the JS console
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
android_hybrid.mp4
Android: mWeb Chrome
android_mWeb.mp4
iOS: Native
ios_hybrid.mp4
iOS: mWeb Safari
ios_mWeb.mp4
MacOS: Chrome / Safari
web_chrome.mp4