Playground translations#1324
Playground translations#1324david-roper wants to merge 6 commits intoDouglasNeuroInformatics:mainfrom
Conversation
WalkthroughReplaced hardcoded English strings with calls to a Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/playground/src/components/FileUploadDialog/FileUploadDialog.tsx (1)
26-42:⚠️ Potential issue | 🟡 MinorMissing
tinuseCallbackdependency array.
tis used insidehandleDrop(line 29) but not listed in the dependencies (line 41). If the language changes, the callback will use a stale translation function.Proposed fix
const handleDrop = useCallback( (acceptedFiles: File[], rejections: FileRejection[]) => { for (const { errors, file } of rejections) { setErrorMessage(t({ en: `Invalid file type: ${file.name} `, fr: `Type de fichier invalide : ${file.name} ` })); console.error(errors); return; } const validation = onValidate?.(acceptedFiles); if (validation?.result === 'error') { setErrorMessage(validation.message); return; } setFiles(acceptedFiles); setErrorMessage(null); }, - [setFiles, setErrorMessage, onValidate] + [setFiles, setErrorMessage, onValidate, t] );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/FileUploadDialog/FileUploadDialog.tsx` around lines 26 - 42, handleDrop uses the translation function t inside the useCallback but t is missing from the dependency array, causing stale translations when language changes; update the dependency array for the useCallback that defines handleDrop to include t (alongside setFiles, setErrorMessage, onValidate) so React recreates handleDrop when the translation function changes.
🧹 Nitpick comments (6)
apps/playground/src/components/Header/SaveButton/SaveButton.tsx (1)
24-25: Consider movinguseTranslationhook to top of component.Hooks are typically grouped at the beginning of a component. Moving
const { t } = useTranslation();aboveuseInterval(around line 14) would improve consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/Header/SaveButton/SaveButton.tsx` around lines 24 - 25, Move the `const { t } = useTranslation();` hook call to the top of the SaveButton component so hooks are grouped together (place it above the `useInterval` call); locate the `SaveButton` component and update the order so `useTranslation()` is invoked before `useInterval` to keep hooks consistent and follow the rules of hooks.apps/playground/src/components/Header/DownloadButton/DownloadButton.tsx (1)
27-28: Consider movinguseTranslationhook earlier.Hook is placed after the
downloadFilesfunction definition. For consistency, move it near line 14 with other hook calls.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/Header/DownloadButton/DownloadButton.tsx` around lines 27 - 28, Move the useTranslation hook call so it appears with the other hooks and before the downloadFiles function definition: locate the current useTranslation usage (const { t } = useTranslation()) and relocate it above or alongside other hook calls (near where hooks are initialized) so that downloadFiles is declared after hooks are set up; ensure any references to t inside downloadFiles still resolve after the move.apps/playground/src/components/Editor/Editor.tsx (1)
3-4: Fix import order.ESLint flags that
@douglasneuroinformatics/libui/hooksshould precede@opendatacapture/instrument-bundler.♻️ Proposed fix
-import { extractInputFileExtension } from '@opendatacapture/instrument-bundler'; import { useTranslation } from '@douglasneuroinformatics/libui/hooks'; +import { extractInputFileExtension } from '@opendatacapture/instrument-bundler';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/Editor/Editor.tsx` around lines 3 - 4, Reorder the two imports in Editor.tsx so that the module from `@douglasneuroinformatics/libui/hooks` (useTranslation) appears before `@opendatacapture/instrument-bundler` (extractInputFileExtension); update the import statements' order to satisfy ESLint's import ordering rule, keeping the same named imports (useTranslation and extractInputFileExtension) and nothing else.apps/playground/src/components/Header/ActionsDropdown/RestoreDefaultsDialog.tsx (1)
22-34: Splitting sentences across multiplet()calls can be fragile.This works for EN/FR but may cause issues if more languages with different word orders are added later. Consider using a single translation with a placeholder for the bold segment, or leave as-is if EN/FR is the intended scope.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/Header/ActionsDropdown/RestoreDefaultsDialog.tsx` around lines 22 - 34, In RestoreDefaultsDialog replace the multiple t() calls inside Dialog.Description with a single translated string that includes a placeholder for the bold segment (so translation keys contain the full sentence and allow injection), and render the injected placeholder value as the uppercase bold span; update the component logic around Dialog.Description and the t() usage so translations for both en/fr use the same sentence shape and you pass the bold text as an interpolation value to t() instead of concatenating multiple t() results.apps/playground/src/components/Header/ActionsDropdown/UploadBundleDialog.tsx (1)
120-125: Avoid fragmenting translatable sentences around inline UI.This 3-part composition (
"Please " + button + " to upload...") is hard to localize correctly when word order differs. Prefer a single translatable sentence pattern with a dedicated CTA nearby.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/Header/ActionsDropdown/UploadBundleDialog.tsx` around lines 120 - 125, The current translatable sentence in UploadBundleDialog is split across three parts which breaks localization; replace the fragmented pattern by using a single translation key/string (via t) that includes a placeholder for the CTA or restructure so the CTA is adjacent but outside the translatable sentence. Locate the UploadBundleDialog component and update the text rendering (where t(...) is used together with the button and onLoginRequired) to either call t with a parameterized sentence (e.g., "Please {cta} to upload a bundle.") and render the button into that placeholder, or move the button out and use a complete translatable sentence followed by a clearly labeled CTA button; ensure you reference the same t function and the onLoginRequired handler when wiring the CTA.apps/playground/src/components/Viewer/RuntimeErrorFallback.tsx (1)
5-15: Removedescriptionfrom the allowed props to prevent unintended overrides.The component always provides its own localized
description, but currently allows it to be overridden via the spread sincedescriptionis not omitted fromInstrumentErrorFallbackProps. Change the type toOmit<InstrumentErrorFallbackProps, 'title' | 'description'>to make this intent explicit.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/Viewer/RuntimeErrorFallback.tsx` around lines 5 - 15, Change the RuntimeErrorFallback props type so callers cannot override the built-in description: update the component signature from using Omit<InstrumentErrorFallbackProps, 'title'> to Omit<InstrumentErrorFallbackProps, 'title' | 'description'> (affecting the RuntimeErrorFallback declaration) so the spread {...props} cannot supply a description and the component-provided localized description remains enforced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/playground/src/components/Editor/EditorPane.tsx`:
- Around line 121-127: The error branch currently checks if (!fileType) but then
interpolates fileType into the message which will be falsy; update the
EditorPanePlaceholder rendering to show the file identifier instead (use
defaultFile.name or extract the extension from defaultFile.name) so the message
reads e.g. `Invalid file type "myfile.tsx"` or `Invalid file type ".tsx"`.
Locate the check around inferFileType(defaultFile.name) and replace the
interpolation of fileType in the error string with defaultFile.name or the
computed extension while keeping the condition and component
EditorPanePlaceholder the same.
---
Outside diff comments:
In `@apps/playground/src/components/FileUploadDialog/FileUploadDialog.tsx`:
- Around line 26-42: handleDrop uses the translation function t inside the
useCallback but t is missing from the dependency array, causing stale
translations when language changes; update the dependency array for the
useCallback that defines handleDrop to include t (alongside setFiles,
setErrorMessage, onValidate) so React recreates handleDrop when the translation
function changes.
---
Nitpick comments:
In `@apps/playground/src/components/Editor/Editor.tsx`:
- Around line 3-4: Reorder the two imports in Editor.tsx so that the module from
`@douglasneuroinformatics/libui/hooks` (useTranslation) appears before
`@opendatacapture/instrument-bundler` (extractInputFileExtension); update the
import statements' order to satisfy ESLint's import ordering rule, keeping the
same named imports (useTranslation and extractInputFileExtension) and nothing
else.
In
`@apps/playground/src/components/Header/ActionsDropdown/RestoreDefaultsDialog.tsx`:
- Around line 22-34: In RestoreDefaultsDialog replace the multiple t() calls
inside Dialog.Description with a single translated string that includes a
placeholder for the bold segment (so translation keys contain the full sentence
and allow injection), and render the injected placeholder value as the uppercase
bold span; update the component logic around Dialog.Description and the t()
usage so translations for both en/fr use the same sentence shape and you pass
the bold text as an interpolation value to t() instead of concatenating multiple
t() results.
In
`@apps/playground/src/components/Header/ActionsDropdown/UploadBundleDialog.tsx`:
- Around line 120-125: The current translatable sentence in UploadBundleDialog
is split across three parts which breaks localization; replace the fragmented
pattern by using a single translation key/string (via t) that includes a
placeholder for the CTA or restructure so the CTA is adjacent but outside the
translatable sentence. Locate the UploadBundleDialog component and update the
text rendering (where t(...) is used together with the button and
onLoginRequired) to either call t with a parameterized sentence (e.g., "Please
{cta} to upload a bundle.") and render the button into that placeholder, or move
the button out and use a complete translatable sentence followed by a clearly
labeled CTA button; ensure you reference the same t function and the
onLoginRequired handler when wiring the CTA.
In `@apps/playground/src/components/Header/DownloadButton/DownloadButton.tsx`:
- Around line 27-28: Move the useTranslation hook call so it appears with the
other hooks and before the downloadFiles function definition: locate the current
useTranslation usage (const { t } = useTranslation()) and relocate it above or
alongside other hook calls (near where hooks are initialized) so that
downloadFiles is declared after hooks are set up; ensure any references to t
inside downloadFiles still resolve after the move.
In `@apps/playground/src/components/Header/SaveButton/SaveButton.tsx`:
- Around line 24-25: Move the `const { t } = useTranslation();` hook call to the
top of the SaveButton component so hooks are grouped together (place it above
the `useInterval` call); locate the `SaveButton` component and update the order
so `useTranslation()` is invoked before `useInterval` to keep hooks consistent
and follow the rules of hooks.
In `@apps/playground/src/components/Viewer/RuntimeErrorFallback.tsx`:
- Around line 5-15: Change the RuntimeErrorFallback props type so callers cannot
override the built-in description: update the component signature from using
Omit<InstrumentErrorFallbackProps, 'title'> to
Omit<InstrumentErrorFallbackProps, 'title' | 'description'> (affecting the
RuntimeErrorFallback declaration) so the spread {...props} cannot supply a
description and the component-provided localized description remains enforced.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: deb098c0-58a5-4d9d-942d-305c9becfd26
📒 Files selected for processing (22)
apps/playground/src/components/Editor/DeleteFileDialog.tsxapps/playground/src/components/Editor/Editor.tsxapps/playground/src/components/Editor/EditorFileButton.tsxapps/playground/src/components/Editor/EditorPane.tsxapps/playground/src/components/FileUploadDialog/FileUploadDialog.tsxapps/playground/src/components/Header/ActionsDropdown/ActionsDropdown.tsxapps/playground/src/components/Header/ActionsDropdown/DeleteInstrumentDialog.tsxapps/playground/src/components/Header/ActionsDropdown/LoginDialog.tsxapps/playground/src/components/Header/ActionsDropdown/RestoreDefaultsDialog.tsxapps/playground/src/components/Header/ActionsDropdown/StorageUsageDialog.tsxapps/playground/src/components/Header/ActionsDropdown/UploadBundleDialog.tsxapps/playground/src/components/Header/ActionsDropdown/UserSettingsDialog.tsxapps/playground/src/components/Header/CloneButton/CloneButton.tsxapps/playground/src/components/Header/DownloadButton/DownloadButton.tsxapps/playground/src/components/Header/RefreshButton/RefreshButton.tsxapps/playground/src/components/Header/SaveButton/SaveButton.tsxapps/playground/src/components/Header/ShareButton/ShareButton.tsxapps/playground/src/components/Header/UploadButton/UploadButton.tsxapps/playground/src/components/MainContent/MainContent.tsxapps/playground/src/components/Viewer/CompileErrorFallback.tsxapps/playground/src/components/Viewer/RuntimeErrorFallback.tsxapps/playground/src/components/Viewer/Viewer.tsx
joshunrau
left a comment
There was a problem hiding this comment.
this looks fine but can you just look at the coderabbit comment I tagged you in.
7dab93b to
a53b2fc
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/playground/src/components/FileUploadDialog/FileUploadDialog.tsx (1)
26-42:⚠️ Potential issue | 🟡 MinorMissing
tin dependency array.The
tfunction is used insidehandleDropbut isn't included in theuseCallbackdependency array. If the user changes language while the dialog is open, the error message would use a stale translation.🛠️ Proposed fix
[setFiles, setErrorMessage, onValidate] + [setFiles, setErrorMessage, onValidate, t]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/FileUploadDialog/FileUploadDialog.tsx` around lines 26 - 42, handleDrop uses the translation function t but t is missing from the useCallback dependency array, which can cause stale translations when language changes; update the useCallback for handleDrop (the callback that references setFiles, setErrorMessage, onValidate) to include t in its dependency array so the callback is recreated when t changes.
🧹 Nitpick comments (2)
apps/playground/src/components/Header/ActionsDropdown/UploadBundleDialog.tsx (1)
119-125: Fragmented sentence is an i18n anti-pattern.Splitting a sentence into pieces around a JSX element assumes all languages share the same word order. This works for EN/FR but may break for future locales (e.g., German, Japanese).
Consider using a single translation key with a placeholder and a component interpolation pattern if your i18n library supports it, or use a
Transcomponent.♻️ Possible approach (if libui supports component interpolation)
- {t({ en: 'Please ', fr: 'Veuillez ' })} - <button className="text-sky-700 hover:underline" type="button" onClick={onLoginRequired}> - {t({ en: 'login to your account', fr: 'vous connecter à votre compte' })} - </button>{' '} - {t({ en: ' to upload a bundle.', fr: ' pour téléverser un paquet.' })} + <Trans + i18nKey="uploadBundle.loginPrompt" + components={{ + loginLink: <button className="text-sky-700 hover:underline" type="button" onClick={onLoginRequired} /> + }} + />With translation strings like:
{ "en": "Please <loginLink>login to your account</loginLink> to upload a bundle.", "fr": "Veuillez <loginLink>vous connecter à votre compte</loginLink> pour téléverser un paquet." }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/Header/ActionsDropdown/UploadBundleDialog.tsx` around lines 119 - 125, The JSX currently builds the sentence in fragments using t(...) and a button (onLoginRequired) which breaks i18n—replace this fragmented string in UploadBundleDialog (the t calls and the inline button) with a single translation key that includes a placeholder or component interpolation (e.g., "Please <loginLink>login to your account</loginLink> to upload a bundle.") and render the loginLink as the clickable element that calls onLoginRequired (or use your i18n library's Trans/component interpolation) so word order remains correct across locales.apps/playground/src/components/Editor/Editor.tsx (1)
3-4: Import order violation.Static analysis indicates
@douglasneuroinformatics/libui/hooksshould come before@opendatacapture/instrument-bundler.♻️ Proposed fix
-import { extractInputFileExtension } from '@opendatacapture/instrument-bundler'; import { useTranslation } from '@douglasneuroinformatics/libui/hooks'; +import { extractInputFileExtension } from '@opendatacapture/instrument-bundler';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/Editor/Editor.tsx` around lines 3 - 4, The import order is incorrect: move the import of useTranslation from '@douglasneuroinformatics/libui/hooks' to appear before the import of extractInputFileExtension from '@opendatacapture/instrument-bundler' in Editor.tsx; update the top-of-file import statements so useTranslation is imported first (look for the symbols useTranslation and extractInputFileExtension) to satisfy the static analysis ordering rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@apps/playground/src/components/FileUploadDialog/FileUploadDialog.tsx`:
- Around line 26-42: handleDrop uses the translation function t but t is missing
from the useCallback dependency array, which can cause stale translations when
language changes; update the useCallback for handleDrop (the callback that
references setFiles, setErrorMessage, onValidate) to include t in its dependency
array so the callback is recreated when t changes.
---
Nitpick comments:
In `@apps/playground/src/components/Editor/Editor.tsx`:
- Around line 3-4: The import order is incorrect: move the import of
useTranslation from '@douglasneuroinformatics/libui/hooks' to appear before the
import of extractInputFileExtension from '@opendatacapture/instrument-bundler'
in Editor.tsx; update the top-of-file import statements so useTranslation is
imported first (look for the symbols useTranslation and
extractInputFileExtension) to satisfy the static analysis ordering rule.
In
`@apps/playground/src/components/Header/ActionsDropdown/UploadBundleDialog.tsx`:
- Around line 119-125: The JSX currently builds the sentence in fragments using
t(...) and a button (onLoginRequired) which breaks i18n—replace this fragmented
string in UploadBundleDialog (the t calls and the inline button) with a single
translation key that includes a placeholder or component interpolation (e.g.,
"Please <loginLink>login to your account</loginLink> to upload a bundle.") and
render the loginLink as the clickable element that calls onLoginRequired (or use
your i18n library's Trans/component interpolation) so word order remains correct
across locales.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 05300400-6391-4476-8778-faf08b063348
📒 Files selected for processing (22)
apps/playground/src/components/Editor/DeleteFileDialog.tsxapps/playground/src/components/Editor/Editor.tsxapps/playground/src/components/Editor/EditorFileButton.tsxapps/playground/src/components/Editor/EditorPane.tsxapps/playground/src/components/FileUploadDialog/FileUploadDialog.tsxapps/playground/src/components/Header/ActionsDropdown/ActionsDropdown.tsxapps/playground/src/components/Header/ActionsDropdown/DeleteInstrumentDialog.tsxapps/playground/src/components/Header/ActionsDropdown/LoginDialog.tsxapps/playground/src/components/Header/ActionsDropdown/RestoreDefaultsDialog.tsxapps/playground/src/components/Header/ActionsDropdown/StorageUsageDialog.tsxapps/playground/src/components/Header/ActionsDropdown/UploadBundleDialog.tsxapps/playground/src/components/Header/ActionsDropdown/UserSettingsDialog.tsxapps/playground/src/components/Header/CloneButton/CloneButton.tsxapps/playground/src/components/Header/DownloadButton/DownloadButton.tsxapps/playground/src/components/Header/RefreshButton/RefreshButton.tsxapps/playground/src/components/Header/SaveButton/SaveButton.tsxapps/playground/src/components/Header/ShareButton/ShareButton.tsxapps/playground/src/components/Header/UploadButton/UploadButton.tsxapps/playground/src/components/MainContent/MainContent.tsxapps/playground/src/components/Viewer/CompileErrorFallback.tsxapps/playground/src/components/Viewer/RuntimeErrorFallback.tsxapps/playground/src/components/Viewer/Viewer.tsx
✅ Files skipped from review due to trivial changes (6)
- apps/playground/src/components/Editor/EditorFileButton.tsx
- apps/playground/src/components/Header/ActionsDropdown/DeleteInstrumentDialog.tsx
- apps/playground/src/components/Header/CloneButton/CloneButton.tsx
- apps/playground/src/components/Header/ShareButton/ShareButton.tsx
- apps/playground/src/components/Header/ActionsDropdown/RestoreDefaultsDialog.tsx
- apps/playground/src/components/Header/ActionsDropdown/UserSettingsDialog.tsx
🚧 Files skipped from review as they are similar to previous changes (11)
- apps/playground/src/components/Header/RefreshButton/RefreshButton.tsx
- apps/playground/src/components/Header/SaveButton/SaveButton.tsx
- apps/playground/src/components/MainContent/MainContent.tsx
- apps/playground/src/components/Viewer/Viewer.tsx
- apps/playground/src/components/Viewer/CompileErrorFallback.tsx
- apps/playground/src/components/Header/UploadButton/UploadButton.tsx
- apps/playground/src/components/Header/ActionsDropdown/LoginDialog.tsx
- apps/playground/src/components/Header/DownloadButton/DownloadButton.tsx
- apps/playground/src/components/Viewer/RuntimeErrorFallback.tsx
- apps/playground/src/components/Header/ActionsDropdown/StorageUsageDialog.tsx
- apps/playground/src/components/Header/ActionsDropdown/ActionsDropdown.tsx
Using antigravity and model gemini 3.1 translations to multiple dialogs, labels and buttons were added the the playground ui
translations include:
dialog components
button labels
viewer components
login, delete and drop database components
Summary by CodeRabbit