Skip to content

feat: comprehensive localization (zh-CN) and UI/UX polish for resource views#272

Open
rabbitc0der wants to merge 1 commit into
volcano-sh:mainfrom
rabbitc0der:feat/chinese-localization
Open

feat: comprehensive localization (zh-CN) and UI/UX polish for resource views#272
rabbitc0der wants to merge 1 commit into
volcano-sh:mainfrom
rabbitc0der:feat/chinese-localization

Conversation

@rabbitc0der
Copy link
Copy Markdown

feat: comprehensive localization (zh-CN) and UI/UX polish for resource views

I. Overview

This Pull Request completes the prerequisite task for the LFX Mentorship 2026 Term 2 project: "Scheduler Management, Observability & Log Explorer UI." While the primary goal was the translation of UI sections into Chinese, I treated this task as an opportunity to perform a deep audit of the Dashboard’s current resource observability. I have implemented a system-wide localization for the Dashboard, Jobs, Queues, Pods, and PodGroups sections, ensuring that the interface is accessible to the Chinese-speaking CNCF community while maintaining technical consistency with Kubernetes standards.


II. The Journey: Phase-wise Implementation

  1. Phase 0: Frontend-First Baseline & UI Mapping
    I initially deployed the dashboard in a frontend-only standalone mode. This allowed me to map the entire UI hierarchy and identify static English strings without the complexity of backend data. By starting with this "mock" baseline, I was able to create the translations.js framework and verify the layout's responsiveness to Chinese characters before integrating real-time cluster data.

  2. Phase 1: Environment & Observability Audit
    Then, I began by deploying a local development environment using k3d and a mock-cluster to understand how the dashboard consumes data. I identified several "hardcoded" English strings within the charts and table rows that were not just language barriers but also inconsistent with standard Chinese technical nomenclature.

  3. Phase 2: Scalable Localization Architecture
    Instead of using "quick-fix" string replacements, I implemented a centralized configuration strategy:

    • a) Centralized Source: Created frontend/src/config/translations.js to serve as a single source of truth. This ensures that as the proposed /scheduler section is built, future contributors can easily add new keys.
    • b) Context-Aware Mapping: Developed a statusMap logic to translate backend states (e.g., Running, Pending) into Chinese labels (e.g., 运行中, 等待中) without breaking the Material UI theme logic or the underlying Kubernetes API contracts.
  4. Phase 3: Deep-Dive Implementation (The "Five Pillars")

    • a) Dashboard: Localized Prometheus-style chart legends, Y-axis labels (e.g., CPU Cores to CPU 核心数), and Stat Cards.
    • b) Jobs & PodGroups: Refactored table rows to support localized status badges.
    • c) Queues: Mapped technical allocation units and state toggles (e.g., Open to 开启).
    • d) Pods: Localized the "Age" column to use industry-standard terminology (存活时间) and translated empty-state messages.
    • e) Global UI: Localized the Search Bar, Pagination controls (10 条/页), and "Create/Edit" dialog headers.
  5. Phase 4: Locale-Standard Formatting
    Beyond word translation, I updated the data presentation:

    • a) Time Formatting: Replaced English date strings with the zh-CN locale standard (YYYY/MM/DD HH:mm:ss) using toLocaleString().
    • b) Namespace Logic: Implemented smart filtering that translates UI terms like All to 全部 and default to 默认, while strictly preserving protected system namespaces like kube-system and volcano-system for technical accuracy.

III. Technical Challenges & Solutions

  1. The "Status-Color" Conflict

    • Challenge: Standard Material UI Chips often use the status string as a key for color logic. Translating "Running" to "运行中" originally caused badges to lose their green color.
    • Solution: I decoupled the Display Label from the Status Key. The components now use the raw English API string for color logic while rendering the localized Chinese string for the user.
  2. Consistent Date Presentation

    • Challenge: The backend timestamps were inconsistent across the Pods and Jobs tables.
    • Solution: Standardized all timestamp rendering via a shared utility pattern to ensure a unified "Single Pane of Glass" experience.

IV. Learnings

Through this task, I gained a deeper understanding of:

  1. Volcano Resource Hierarchy: How PodGroups act as the bridge between Jobs and the Scheduler.
  2. React Component Reusability: How to refactor shared components like JobStatusChip to support multi-language labels.
  3. Open Source Collaboration: The importance of "Zero-Footprint" changes—making significant UI improvements without bloating the codebase or breaking existing API integrations.

V. Alignment with Project Goals

This PR sets the stage for the proposed Scheduler Observability work. By localizing the core resource views, I have ensured that the upcoming Metrics Tab and Log Explorer can be built upon a foundation that supports internationalization (i18n) from day one. I am particularly excited about the Logs Tab proposal, as I’ve already explored the CoreV1Api during this task to understand how logs are currently fetched.


VI. Visual Evidence (Testing in Cluster)

📷 Main Resource Views (10 Images)
  • Dashboard: [Screenshot 2026-05-19 102348][Screenshot 2026-05-19 105925] - Localized charts and resource cards.
  • Jobs: [Screenshot 2026-05-19 102530][Screenshot 2026-05-19 110017] - "运行中" status badges and native timestamps.
  • Queues: [Screenshot 2026-05-19 103520][Screenshot 2026-05-19 110203] - Allocation units and state localization.
  • Pods: [Screenshot 2026-05-19 103717][Screenshot 2026-05-19 112108] - Namespace filtering and uptime (Age) localization.
  • PodGroups: [Screenshot 2026-05-19 103815][Screenshot 2026-05-19 112246] - Full consistency with Job-level scheduling views.
📝 Creation Dialogs (4 Images)
  • Create Job: [Screenshot 2026-05-19 104714] - Fully translated input fields and form headers.
  • Create Queue: [Screenshot 2026-05-19 104813] - Resource allocation labels in Chinese.
  • Create Pod: [Screenshot 2026-05-19 105619] - Metadata and specification fields localized.
  • Create PodGroup: [Screenshot 2026-05-19 105802] - Scheduling policy fields (MinMember, etc.) translated.
🔍 UI Detail & Logic (In all 10 Images uploaded earlier)
  • Namespace Filter: - Proof of "全部" and "默认" mapping.
  • Status Filter: - Translated status dropdowns.
  • Pagination: - "条/页" and total count localization.
  • Search Bar: - Localized placeholders.
  • Action Buttons: - "刷新列表" and "创建" button localization.

@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 jessestutler 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

@volcano-sh-bot
Copy link
Copy Markdown
Contributor

Welcome @rabbitc0der! It looks like this is your first PR to volcano-sh/dashboard 🎉

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 a centralized translation system for the Volcano Dashboard, enabling support for both English and Simplified Chinese. Hardcoded strings across various components, including charts, tables, and dialogs, have been replaced with localized strings from a new translations.js configuration file. Additionally, minor dependency metadata cleanups were performed in package-lock.json. The review feedback highlights opportunities to further improve the implementation by ensuring all error messages and resource labels consistently utilize the new translation object for better maintainability.

Comment on lines +228 to +230
<Typography color="error" sx={{ mb: 2 }}>
获取 Pods 失败: 请求失败, 状态码 {String(error)}
</Typography>
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 error message is hardcoded in Chinese. Please use the translations object to ensure the application remains localizable and consistent.

Suggested change
<Typography color="error" sx={{ mb: 2 }}>
获取 Pods 失败: 请求失败, 状态码 {String(error)}
</Typography>
<Typography color="error" sx={{ mb: 2 }}>
{translations.zh.errorFetchPods}: {String(error)}
</Typography>

Comment on lines +36 to +40
const allocatedFieldLabelMap = {
cpu: "已分配 CPU",
memory: "已分配 内存",
pods: "已分配 Pod",
};
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 allocatedFieldLabelMap object contains hardcoded Chinese strings. These should be moved to the translations.js file and accessed via the translations object to support multi-language support.

Suggested change
const allocatedFieldLabelMap = {
cpu: "已分配 CPU",
memory: "已分配 内存",
pods: "已分配 Pod",
};
const allocatedFieldLabelMap = {
cpu: translations.zh.cpu,
memory: translations.zh.memory,
pods: translations.zh.pods,
};

Comment on lines +57 to +70
const getResourceDisplayLabel = (resource) => {
switch (resource) {
case "cpu":
return "CPU 资源";
case "memory":
return "内存资源";
case "pods":
return "Pod 资源";
case "nvidia.com/gpu":
return "GPU 资源";
default:
return `${resource.charAt(0).toUpperCase() + resource.slice(1)} 资源`;
}
};
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 getResourceDisplayLabel function contains hardcoded Chinese strings. Please move these to the translations.js file and use the translations object to support dynamic language switching.

const getResourceDisplayLabel = (resource) => {
    return translations.zh[resource] || `${resource.charAt(0).toUpperCase() + resource.slice(1)} 资源`;
};

@rabbitc0der rabbitc0der force-pushed the feat/chinese-localization branch from 5292e39 to 836ec06 Compare May 19, 2026 08:09
…lified Chinese

Signed-off-by: rabbitc0der <vithallomate@gmail.com>
@rabbitc0der rabbitc0der force-pushed the feat/chinese-localization branch from 836ec06 to 9c2653a Compare May 19, 2026 08:16
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