Skip to content

feat: translate volcano dashboard into chinese#269

Open
Jetshree wants to merge 1 commit into
volcano-sh:mainfrom
Jetshree:lfx-task
Open

feat: translate volcano dashboard into chinese#269
Jetshree wants to merge 1 commit into
volcano-sh:mainfrom
Jetshree:lfx-task

Conversation

@Jetshree
Copy link
Copy Markdown

This PR addresses the LFX Mentorship prerequisite task (Issue #197) and translate dashboard into chinese.

Logic:
This PR introduces a scalable translation setup using react-i18next. All UI strings were moved into separate translation.json files for each language and components now use useTranslation() for dynamic text rendering. Translations are lazy-loaded with i18next-http-backend, keeping the initial bundle lightweight. handles loading gracefully. This setup also makes future translations straightforward, as it is only needed to add new keys to the JSON files and replace strings with useTranslation() calls.
I've not translated entire dashboard website to keep the PR minimal. Other pages can be translated with same logic as mentioned above.

Changes

  • Dependencies: Added i18next, react-i18next, i18next-http-backend, and i18next-browser-languagedetector.
  • i18n Initialization: Configured frontend/src/i18n.js with HTTP lazy-loading and wired it into main.jsx with a React Suspense boundary.
  • Locales: Added en and zh translation JSONs containing keys for all Dashboard cards, charts, and buttons in frontend/public/locales/.
  • Target Page Components Updated:
    • DashboardHeader.jsx: Added the toggle language button and translated the main page title.
    • StatCardsContainer.jsx: Translated card labels ("Total Jobs", "Active Queues", etc.).
    • JobStatusPieChart.jsx: Translated jobs status card title, legends, tooltips, and empty states.
    • QueueResourcesBarChart.jsx: Translated queue card header, select labels, y-axis labels, and dataset descriptions ("Allocated", "Capacity").

Testing Done

  • Verified that clicking the "中文" toggle re-renders all text on the Dashboard page immediately.
  • Verified that clicking the "English" toggle instantly returns all labels to standard English.
  • Verified that the appropriate translation JSONs are correctly lazy-loaded via network calls only when requested.
  • Verified that all unit tests continue to pass without issues.

Screenshots

English
image

Chinese
image

Signed-off-by: Jetshree <jetshreesharma@gmail.com>
@volcano-sh-bot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign monokaix for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces internationalization (i18n) support to the Volcano Dashboard using i18next and react-i18next, including English and Chinese translations. Key changes involve setting up the i18n configuration, adding translation files, and updating components such as charts and the dashboard to use the useTranslation hook. Feedback focuses on improving error handling by throwing Error instances instead of plain objects to preserve stack traces, simplifying translation key mapping in the resource bar chart, and localizing remaining hardcoded strings in the language toggle and Suspense fallback.


if (!jobsRes.ok)
throw new Error(`Jobs API error: ${jobsRes.status}`);
throw { key: "dashboard.apiError.jobs", params: { status: jobsRes.status } };
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Throwing a plain object instead of an Error instance is generally considered an anti-pattern in JavaScript because it does not capture a stack trace. This can make debugging significantly harder in production environments. It is recommended to throw an Error object and attach the translation metadata as custom properties.

Comment on lines +76 to +87
return Array.from(resourceTypes).map((resource) => {
let label = `${resource.charAt(0).toUpperCase() + resource.slice(1)} Resources`;
if (resource === "memory") label = t("dashboard.memory");
else if (resource === "cpu") label = t("dashboard.cpu");
else if (resource === "pods") label = t("dashboard.pods");
else if (resource === "nvidia.com/gpu") label = t("dashboard.gpu");

return {
value: resource,
label: label,
};
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The manual mapping of resource types to translation keys is redundant and can be simplified. By using a consistent naming convention in your translation files, you can dynamically construct the key or use the defaultValue option in the t function to handle fallback labels gracefully.

        return Array.from(resourceTypes).map((resource) => ({
            value: resource,
            label: t(`dashboard.${resource === "nvidia.com/gpu" ? "gpu" : resource}`, {
                defaultValue: `${resource.charAt(0).toUpperCase() + resource.slice(1)} Resources`,
            }),
        }));

},
}}
>
{i18n.language.startsWith("zh") ? "中 / EN" : "EN / 中"}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The language toggle labels '中 / EN' and 'EN / 中' are hardcoded. To ensure full localization support and maintain consistency with the rest of the application's internationalization strategy, these strings should be moved to the translation JSON files.

Comment thread frontend/src/main.jsx
createRoot(document.getElementById("root")).render(
<StrictMode>
<App />
<Suspense fallback="Loading...">
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The Suspense fallback text 'Loading...' is hardcoded. Since this pull request focuses on internationalization, all user-facing strings should be localized. Consider using a translated string or a dedicated loading component to provide a consistent localized experience.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants