Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve i18n support and add missing translations #6070

Open
wants to merge 78 commits into
base: main
Choose a base branch
from

Conversation

neubig
Copy link
Contributor

@neubig neubig commented Jan 6, 2025

This PR improves the internationalization (i18n) support in the frontend by:

  1. Adding missing translations for all supported languages (zh-CN, zh-TW, ko-KR, de, no, it, pt, es, ar, fr, tr) for:

    • Workspace labels and titles
    • Project and terminal status messages
    • Time-related messages
  2. Adding i18n test utilities and translation tests:

    • Added test to verify all translation keys have translations for all supported languages
    • Added test to detect duplicate translation keys
    • Added test utilities for i18n testing
  3. Updating UI components to use translations consistently

Fixes #6066
Fixes #4280

Here are examples of the localized screens. I have confirmed that all settings menus, etc. are localized.
Screenshot 2025-01-07 at 9 40 02 PM
Screenshot 2025-01-07 at 9 39 23 PM
Screenshot 2025-01-07 at 9 38 57 PM
Screenshot 2025-01-07 at 9 37 25 PM
Screenshot 2025-01-07 at 9 37 07 PM


To run this PR locally, use the following command:

docker run -it --rm   -p 3000:3000   -v /var/run/docker.sock:/var/run/docker.sock   --add-host host.docker.internal:host-gateway   -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:edb4ed6-nikolaik   --name openhands-app-edb4ed6   docker.all-hands.dev/all-hands-ai/openhands:edb4ed6

@neubig neubig marked this pull request as draft January 6, 2025 08:26
@neubig neubig self-assigned this Jan 6, 2025
@neubig
Copy link
Contributor Author

neubig commented Jan 6, 2025

The localization is very incomplete. For instance, look at these two screens when Japanese is selected as a language:

Screenshot 2025-01-06 at 6 30 14 PM Screenshot 2025-01-06 at 6 28 56 PM

Only one part of the screen is actually translated in the two main screens. All of the English should be converted into the appropriate language when a different language is selected.

frontend/src/i18n/translation.json Outdated Show resolved Hide resolved
frontend/src/i18n/translation.json Outdated Show resolved Hide resolved
frontend/src/i18n/translation.json Outdated Show resolved Hide resolved
frontend/src/i18n/translation.json Outdated Show resolved Hide resolved
frontend/src/i18n/translation.json Outdated Show resolved Hide resolved
@neubig neubig changed the title Add Japanese translations to frontend Improve i18n support and add missing translations Jan 6, 2025
openhands-agent and others added 5 commits January 6, 2025 17:09
- Add missing translation keys for browser, user avatar, and suggestions
- Add translations for all supported languages
- Create test to catch hardcoded English strings
- Fix components to use translation system properly
- Remove CHAT$WHAT_DO_YOU_WANT_TO_BUILD and LANDING$BUILD_PROMPT in favor of SUGGESTIONS$WHAT_TO_BUILD
- Remove unused keys:
  - STATUS$CONNECTED_TO_SERVER
  - BROWSER$SCREENSHOT and BROWSER$SCREENSHOT_ALT
  - SUGGESTIONS$AUTO_MERGE and SUGGESTIONS$AUTO_MERGE_PRS
  - USER$AVATAR_PLACEHOLDER (duplicate)
- Remove WORKSPACE$LABEL (unused)
- Remove CONNECT_TO_GITHUB_BY_TOKEN_MODAL$TERMS_OF_SERVICE (unused)
@neubig neubig marked this pull request as ready for review January 7, 2025 13:07
@neubig neubig requested a review from amanape January 7, 2025 13:09
@neubig
Copy link
Contributor Author

neubig commented Jan 7, 2025

@amanape , apologies that this is a huge PR but hopefully the logic is relatively straightforward.

Copy link
Member

@amanape amanape left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About time! This is going to cause some open PRs to have to resolve some conflicts 😭 but definitely worth it.

If you could just address / answer the comments first 😃

expect(uniqueDuplicates).toHaveLength(0);
});

it('should have consistent translations for each key', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean?

Comment on lines +22 to +23
describe('Translations', () => {
describe('Translation Coverage', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nested describe, we can unpack to have under a single describe since there are no other describe suites present.

Comment on lines +15 to +33
const { container } = render(
<InteractiveChatBox
onSubmit={() => {}}
onStop={() => {}}
/>
);

// Get all text content
const text = container.textContent;

// List of English strings that should be translated
const hardcodedStrings = [
"What do you want to build?",
];

// Check each string
hardcodedStrings.forEach(str => {
expect(text).not.toContain(str);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const { container } = render(
<InteractiveChatBox
onSubmit={() => {}}
onStop={() => {}}
/>
);
// Get all text content
const text = container.textContent;
// List of English strings that should be translated
const hardcodedStrings = [
"What do you want to build?",
];
// Check each string
hardcodedStrings.forEach(str => {
expect(text).not.toContain(str);
});
render(<InteractiveChatBox onSubmit={() => {}} onStop={() => {}} />);
expect(screen.queryByText("What do you want to build?")).not.toBeInTheDocument();

It is not necessary to introduce an array since it contains a single value only, and I doubt this test will be extended in the foreseeable future.

@@ -0,0 +1,47 @@
import { render } from "@testing-library/react";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { render } from "@testing-library/react";
import { render, screen } from "@testing-library/react";

Comment on lines +37 to +45
const { container } = render(
<ChatInput
onSubmit={() => {}}
/>
);

// The placeholder should be a translation key, not English text
const textarea = container.querySelector("textarea");
expect(textarea?.placeholder).toBe("SUGGESTIONS$WHAT_TO_BUILD");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const { container } = render(
<ChatInput
onSubmit={() => {}}
/>
);
// The placeholder should be a translation key, not English text
const textarea = container.querySelector("textarea");
expect(textarea?.placeholder).toBe("SUGGESTIONS$WHAT_TO_BUILD");
render(<ChatInput onSubmit={() => {}} />);
screen.getByPlaceholderText("SUGGESTIONS$WHAT_TO_BUILD");

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added by mistake, should remove

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added by mistake, should remove

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes necessary? They seem repetitive and it previously worked without them

@neubig neubig added the fix-me Attempt to fix this issue with OpenHands label Jan 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fix-me Attempt to fix this issue with OpenHands
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Japanese to localization settings Update the frontend to use i18n keys
3 participants