Skip to content

fix(i18n): translate settings sidebar headings and default workflow name to Chinese#12107

Open
LifetimeVip wants to merge 8 commits intoComfy-Org:mainfrom
LifetimeVip:fix/zh-ui-improvements
Open

fix(i18n): translate settings sidebar headings and default workflow name to Chinese#12107
LifetimeVip wants to merge 8 commits intoComfy-Org:mainfrom
LifetimeVip:fix/zh-ui-improvements

Conversation

@LifetimeVip
Copy link
Copy Markdown
Contributor

@LifetimeVip LifetimeVip commented May 9, 2026

Summary

Translates 3 hardcoded English settings sidebar section headings and the default unsaved workflow filename.

Changes

  • Settings sidebar: Account -> 账户, Application Settings -> 应用设置, Special Settings -> 特殊设置
  • Default unsaved workflow name: Unsaved Workflow -> 未保存的工作流

┆Issue is synchronized with this Notion page by Unito

- EmptyARVideoLatent -> 空AR视频Latent
- CropByBBoxes -> 按边界框裁剪
- EasyCache -> 简易缓存
- FreeU_V2 -> FreeU V2
@LifetimeVip LifetimeVip requested a review from a team May 9, 2026 06:24
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label May 9, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1382f9e8-dfab-47ba-bc24-fdedda6849ae

📥 Commits

Reviewing files that changed from the base of the PR and between 5e00a99 and af5dc9b.

📒 Files selected for processing (5)
  • src/components/common/badge.variants.ts
  • src/components/common/statusBadge.variants.ts
  • src/components/load3d/controls/ExportControls.vue
  • src/components/load3d/controls/viewer/ViewerExportControls.vue
  • src/components/widget/SampleModelSelector.vue
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/components/load3d/controls/ExportControls.vue
  • src/components/common/badge.variants.ts
  • src/components/load3d/controls/viewer/ViewerExportControls.vue
  • src/components/common/statusBadge.variants.ts
  • src/components/widget/SampleModelSelector.vue

📝 Walkthrough

Walkthrough

This PR migrates many hardcoded UI strings to i18n calls, adds/expands English and Chinese translation keys, updates Chinese node display names and model-folder display/description helpers, adjusts a workflow default filename, updates Storybook stories and components to use translations, and removes the .i18nrc.cjs config.

Changes

Comprehensive i18n Migration and Localization Expansion

Layer / File(s) Summary
Translation Key Additions
src/locales/en/main.json, src/locales/zh/main.json
Adds many new g-namespace keys for workflow actions, canvas controls, menu items, and UI labels in both English and Chinese.
Model Folder Display & Description
src/platform/assets/composables/useModelTypes.ts
Rewrites formatDisplayName to use a Chinese name lookup table and exports getModelFolderDescription(folderName) that returns tooltip descriptions with a generic fallback.
Node Display Names
src/locales/zh/nodeDefs.json
Updates four Chinese node definitions: CropByBBoxes按边界框裁剪, EasyCache简易缓存, EmptyARVideoLatent空AR视频Latent, FreeU_V2FreeU V2.
Workflow Store Configuration
src/platform/workflow/management/stores/workflowStore.ts
Changes fallback unsaved workflow filename from Unsaved Workflow.json to 未保存的工作流.json.
Core Commands Localization
src/composables/useCoreCommands.ts
Replaces hardcoded label and menubarLabel strings with t(...) calls across workflow, canvas, queue, and utility commands.
Vue Component Localization
src/components/..., src/components/load3d/..., src/components/sidebar/..., src/components/widget/...
Adds i18n imports and replaces hardcoded navigation, export-format, axis-direction, and UI labels with t(...) in components and viewer controls.
Storybook Story Localization
src/components/*/*.stories.ts
Updates Storybook stories to import t and replace hardcoded labels and dataset names with translation keys across many stories.
Composables and Menu Options
src/composables/graph/..., src/composables/sidebarTabs/...
Localizes context menu categories, group menu options, and sidebar tab labels by switching to t(...) lookups.
Badge Variant Styles
src/components/common/badge.variants.ts, src/components/common/statusBadge.variants.ts
Changes badge variant label values to use i18n translation key strings for typography/label text tokens.
Extension Command Localization
src/extensions/core/electronAdapter.ts, src/extensions/core/groupNode.ts, src/extensions/core/load3d.ts, src/extensions/core/load3d/exportMenuHelper.ts
Replaces hardcoded command labels with i18n keys for Electron desktop menus, group-node operations, 3D viewer, and export formats.
Configuration Cleanup
.i18nrc.cjs
Removes the i18n-cli configuration file.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A bunny hops through translation keys,

Chinese names and English ease,
Commands now speak in many tongues,
Components hum their localized songs,
Config gone, the strings align—hooray!


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore (reviewers only)

❌ Failed checks (1 error, 1 warning, 1 inconclusive)

Check name Status Explanation Resolution
End-To-End Regression Coverage For Fixes ❌ Error PR title and commit subjects use bug-fix language ("fix(i18n):"), but no browser_tests/ files are modified and PR description lacks explanation for skipping regression tests. Add/update a Playwright regression test under browser_tests/ covering i18n translation fixes, or add concrete explanation in PR description for why e2e tests are not practical.
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description covers the key changes but lacks detail on the broader scope of the PR, which includes 30+ files with i18n translations beyond just sidebar headings. Expand the description to acknowledge the extensive i18n work across multiple components and files, not just the three specific sidebar sections mentioned.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: translating settings sidebar headings and default workflow name to Chinese.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Adr Compliance For Entity/Litegraph Changes ✅ Passed PR does not modify src/lib/litegraph/ or src/ecs/, and contains no graph entity mutations. Changes are exclusively UI text localization. ADR compliance check scope not applicable.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

🎭 Playwright: ⏳ Running...

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

🎨 Storybook: loading Building...

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/platform/settings/composables/useSettingUI.ts (1)

332-356: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use vue-i18n for legacy sidebar group labels.

Lines 332, 350, 356 hardcode Chinese labels, so legacy sidebar titles render in Chinese regardless of the active locale. Wrap groups with translateCategory() and use English labels to enable proper translation lookup:

Suggested fix
-    {
+    translateCategory({
       key: 'account',
-      label: '账户',
+      label: 'Account',
       children: [
         userPanel.node,
         ...(isLoggedIn.value &&
         shouldShowPlanCreditsPanel.value &&
         subscriptionPanel
           ? [subscriptionPanel.node]
           : []),
         ...(shouldShowSecretsPanel.value ? [secretsPanel.node] : []),
         ...(isLoggedIn.value &&
         !(isCloud && window.__CONFIG__?.subscription_required)
           ? [creditsPanel.node]
           : [])
       ].map(translateCategory)
-    },
+    }),
     // Normal settings stored in the settingStore
-    {
+    translateCategory({
       key: 'settings',
-      label: '应用设置',
+      label: 'Application Settings',
       children: settingCategories.value.map(translateCategory)
-    },
+    }),
     // Special settings such as about, keybinding, extension, server-config
-    {
+    translateCategory({
       key: 'specialSettings',
-      label: '特殊设置',
+      label: 'Special Settings',
       children: [
         keybindingPanel.node,
         extensionPanel.node,
         aboutPanel.node,
         ...(isDesktop ? [serverConfigPanel.node] : [])
       ].map(translateCategory)
-    }
+    })

This matches the pattern used in workspaceMenuTreeNodes (lines 287–324), where all top-level groups are wrapped with translateCategory() to enable locale-aware rendering.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/settings/composables/useSettingUI.ts` around lines 332 - 356,
The sidebar group objects with hardcoded Chinese labels ('账户', '应用设置', '特殊设置')
must be switched to English keys and wrapped through translateCategory so
vue-i18n can localize them; update the group definitions that build children
from userPanel.node, subscriptionPanel.node, secretsPanel.node,
creditsPanel.node and the settings group using settingCategories.value.map to
use English label values (e.g., "account", "settings", "specialSettings") and
pass each full group object into translateCategory (same pattern as
workspaceMenuTreeNodes) so titles are looked up by the i18n translator.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/platform/workflow/management/stores/workflowStore.ts`:
- Around line 299-303: The store uses hardcoded default filenames in
createTemporary() and createNewTemporary() ('未保存的工作流.json' and 'Unsaved
Workflow.json') causing inconsistent UX and not using vue-i18n; add a
translation key (e.g., workflow.unsavedFilename) to src/locales/en/main.json and
import/use the vue-i18n API inside the workflow store, then replace the literal
defaults in both createTemporary() and createNewTemporary() with
i18n.t('workflow.unsavedFilename') (or the composition API equivalent) so both
functions consistently use the localized filename.
- Line 301: The createTemporary function contains a stray "..." and
duplicated/partial lines — remove the "..." placeholder, reconstruct the
function to mirror createNewTemporary by: compute fullPath consistently, call
normalizeWorkflowData(workflow) to get normalized data, look up existingWorkflow
by fullPath before creating the temp entry, and avoid duplicate fullPath
assignments; also replace the hardcoded '未保存的工作流.json' with a vue-i18n key (e.g.
use t('main.unsavedWorkflow') and add "Unsaved Workflow.json" to
src/locales/en/main.json) so user-facing text follows i18n. Ensure references to
createTemporary, createNewTemporary, normalizeWorkflowData, fullPath, and
existingWorkflow are used when locating and fixing the code.

---

Outside diff comments:
In `@src/platform/settings/composables/useSettingUI.ts`:
- Around line 332-356: The sidebar group objects with hardcoded Chinese labels
('账户', '应用设置', '特殊设置') must be switched to English keys and wrapped through
translateCategory so vue-i18n can localize them; update the group definitions
that build children from userPanel.node, subscriptionPanel.node,
secretsPanel.node, creditsPanel.node and the settings group using
settingCategories.value.map to use English label values (e.g., "account",
"settings", "specialSettings") and pass each full group object into
translateCategory (same pattern as workspaceMenuTreeNodes) so titles are looked
up by the i18n translator.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 338f913a-642b-4f80-ab5a-e22e8efac1ce

📥 Commits

Reviewing files that changed from the base of the PR and between 8f68be5 and c272de7.

📒 Files selected for processing (5)
  • find-untranslated.cjs
  • src/locales/zh/nodeDefs.json
  • src/platform/settings/composables/useSettingUI.ts
  • src/platform/workflow/management/stores/workflowStore.ts
  • translate-nodes.cjs

Comment on lines +299 to 303
ComfyWorkflow.basePath + (path ?? '未保存的工作流.json')
)
...
ComfyWorkflow.basePath + (path ?? '未保存的工作流.json')
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify mixed defaults and locale-specific hardcoded fallback names
rg -n "Unsaved Workflow\.json|未保存的工作流\.json" src/platform/workflow/management/stores/workflowStore.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 259


🏁 Script executed:

sed -n '290,330p' src/platform/workflow/management/stores/workflowStore.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1234


🏁 Script executed:

head -20 src/locales/en/main.json && echo "..." && tail -20 src/locales/en/main.json

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1330


🏁 Script executed:

rg -n "Unsaved Workflow|未保存的工作流" --type ts src/

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1179


🏁 Script executed:

head -50 src/platform/workflow/management/stores/workflowStore.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2126


🏁 Script executed:

rg -n "import.*i18n|useI18n|t\(" src/platform/workflow/management/stores/workflowStore.ts | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 785


🏁 Script executed:

rg -n "workflow|Unsaved|temporary" src/locales/en/main.json

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 12032


Use vue-i18n for the unsaved workflow filename default and ensure consistency across both functions.

Lines 299, 302, and 326 have hardcoded default workflow filenames with mixed languages: Chinese ('未保存的工作流.json') in createTemporary() and English ('Unsaved Workflow.json') in createNewTemporary(). This creates inconsistent UX across locales and violates the coding guideline requiring all user-facing strings to use vue-i18n.

Add a translation key (e.g., workflow.unsavedFilename) to src/locales/en/main.json and import/use the i18n API in the store to reference it consistently across both functions.

🧰 Tools
🪛 Biome (2.4.14)

[error] 301-301: Expected an expression but instead found '...'.

(parse)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/workflow/management/stores/workflowStore.ts` around lines 299 -
303, The store uses hardcoded default filenames in createTemporary() and
createNewTemporary() ('未保存的工作流.json' and 'Unsaved Workflow.json') causing
inconsistent UX and not using vue-i18n; add a translation key (e.g.,
workflow.unsavedFilename) to src/locales/en/main.json and import/use the
vue-i18n API inside the workflow store, then replace the literal defaults in
both createTemporary() and createNewTemporary() with
i18n.t('workflow.unsavedFilename') (or the composition API equivalent) so both
functions consistently use the localized filename.

ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
ComfyWorkflow.basePath + (path ?? '未保存的工作流.json')
)
...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the parse-blocking placeholder is present
rg -nP '^\s*\.\.\.\s*$' src/platform/workflow/management/stores/workflowStore.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 78


🏁 Script executed:

sed -n '290,335p' src/platform/workflow/management/stores/workflowStore.ts | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1779


🏁 Script executed:

# Check git history to understand what happened at this line
cd src/platform/workflow/management/stores && git log -p --follow -S '...' -- workflowStore.ts | head -100

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

# Get more context around the createTemporary function to understand the full structure
sed -n '295,340p' src/platform/workflow/management/stores/workflowStore.ts | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1850


Fix the syntax error and malformed createTemporary function structure.

Line 301 contains a ... placeholder that prevents parsing. The createTemporary function has incomplete refactoring with duplicate code (lines 300 and 302 both define fullPath assignment separated by ...). Additionally, the hardcoded Chinese filename '未保存的工作流.json' violates the i18n requirement for user-facing strings—use vue-i18n with a translation entry in src/locales/en/main.json instead. This mirrors createNewTemporary's pattern but uses English 'Unsaved Workflow.json' instead, creating inconsistency.

The function requires reconstruction to:

  1. Remove the ... placeholder
  2. Replace duplicate lines with the missing logic (normalizeWorkflowData call and existingWorkflow lookup)
  3. Extract the hardcoded filename to vue-i18n translation keys
🧰 Tools
🪛 Biome (2.4.14)

[error] 301-301: Expected an expression but instead found '...'.

(parse)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/workflow/management/stores/workflowStore.ts` at line 301, The
createTemporary function contains a stray "..." and duplicated/partial lines —
remove the "..." placeholder, reconstruct the function to mirror
createNewTemporary by: compute fullPath consistently, call
normalizeWorkflowData(workflow) to get normalized data, look up existingWorkflow
by fullPath before creating the temp entry, and avoid duplicate fullPath
assignments; also replace the hardcoded '未保存的工作流.json' with a vue-i18n key (e.g.
use t('main.unsavedWorkflow') and add "Unsaved Workflow.json" to
src/locales/en/main.json) so user-facing text follows i18n. Ensure references to
createTemporary, createNewTemporary, normalizeWorkflowData, fullPath, and
existingWorkflow are used when locating and fixing the code.

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels May 9, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/components/widget/layout/BaseModalLayout.stories.ts (1)

93-126: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Imported i18n t is bypassed, so labels render translation keys

At Line 83, the local const t = (k: string) => k shadows the imported t, so Lines 93/101/106/111/121/126 render keys like g.installed instead of localized labels.

Proposed fix
-  setup() {
-    const t = (k: string) => k
+  setup() {
@@
     return {
       args,
-      t,
       tempNavigation,

As per coding guidelines: "Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/widget/layout/BaseModalLayout.stories.ts` around lines 93 -
126, The local placeholder "const t = (k: string) => k" in
BaseModalLayout.stories.ts is shadowing the real i18n translator and causing
labels (e.g. items with label: t('g.installed'), t('g.sd_1_5'), etc.) to render
keys; remove or rename that local const and wire the story to the actual
vue-i18n translator (use the imported t or call useI18n() so the labels call the
real t function), and add any new keys referenced (g.installed, g.sd_1_5,
g.sdxl, g.utility, g.models, g.nodes, etc.) to src/locales/en/main.json per
guidelines.
src/components/ui/chart/ChartBar.stories.ts (1)

25-25: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize remaining ariaLabel strings in this story file.

Line 25 and Line 41 still hardcode English accessibility text. Please wrap them with t(...) and add keys in locale JSON to keep i18n coverage consistent.

Suggested patch
 export const Default: Story = {
   args: {
-    ariaLabel: 'Bar chart example',
+    ariaLabel: t('g.bar_chart_example_aria'),
@@
 export const MultipleDatasets: Story = {
   args: {
-    ariaLabel: 'Bar chart with multiple datasets',
+    ariaLabel: t('g.bar_chart_multiple_datasets_aria'),
// src/locales/en/main.json
{
  "g": {
    "bar_chart_example_aria": "Bar chart example",
    "bar_chart_multiple_datasets_aria": "Bar chart with multiple datasets"
  }
}

As per coding guidelines src/**/*.{ts,vue}: “Use vue-i18n for ALL user-facing strings, configured in src/locales/en/main.json.”

Also applies to: 41-41

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/chart/ChartBar.stories.ts` at line 25, In
ChartBar.stories.ts replace the hardcoded ariaLabel values with vue-i18n calls
(wrap the existing strings in t(...)) for both occurrences (the ariaLabel
property and the second ariaLabel at line 41), and add matching keys to the
English locale JSON under g (for example g.bar_chart_example_aria and
g.bar_chart_multiple_datasets_aria) so the story uses
t('g.bar_chart_example_aria') and t('g.bar_chart_multiple_datasets_aria')
instead of literal strings.
src/components/ui/chart/ChartLine.stories.ts (1)

25-25: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Also translate the story ariaLabel values.

Line 25 and Line 45 are still English literals. These are user-facing accessibility strings and should be localized too.

Suggested patch
 export const Default: Story = {
   args: {
-    ariaLabel: 'Line chart example',
+    ariaLabel: t('g.line_chart_example_aria'),
@@
 export const MultipleLines: Story = {
   args: {
-    ariaLabel: 'Line chart with multiple lines',
+    ariaLabel: t('g.line_chart_multiple_lines_aria'),
// src/locales/en/main.json
{
  "g": {
    "line_chart_example_aria": "Line chart example",
    "line_chart_multiple_lines_aria": "Line chart with multiple lines"
  }
}

As per coding guidelines src/**/*.{ts,vue}: “Use vue-i18n for ALL user-facing strings, configured in src/locales/en/main.json.”

Also applies to: 45-45

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/chart/ChartLine.stories.ts` at line 25, Replace the
hard-coded English ariaLabel values in the ChartLine.stories.ts story exports
with vue-i18n lookups: add the keys g.line_chart_example_aria and
g.line_chart_multiple_lines_aria to src/locales/en/main.json, import and
initialize i18n in the story (e.g., useI18n / t) and set the story args
ariaLabel to t('g.line_chart_example_aria') and
t('g.line_chart_multiple_lines_aria') respectively (references: ariaLabel in
ChartLine.stories.ts and the new locale keys g.line_chart_example_aria /
g.line_chart_multiple_lines_aria).
🧹 Nitpick comments (2)
src/extensions/core/groupNode.ts (1)

146-146: ⚡ Quick win

Consider translating remaining hardcoded user-facing strings.

Several user-facing strings throughout this file remain hardcoded in English and should be wrapped with t() calls for consistency with this PR's i18n objectives:

  • Error messages (lines 1848-1859): 'No nodes selected', 'Please select multiple nodes to convert to group node', 'Selected nodes contain a subgraph node', 'Selected nodes contain a group node'
  • Toast/alert messages (line 146): Long error message about duplicate group node names
  • Confirmation dialogs (line 152): Group node overwrite confirmation
  • Context menu items (lines 1308, 1320, 1950, 1959, 1977): 'Convert to nodes', 'Manage Group Node', 'Convert to Group Node (Deprecated)', 'Manage Group Nodes'
  • Progress labels (line 1368): Dynamic progress message

As per coding guidelines, ALL user-facing strings should use vue-i18n. Given this is a comprehensive i18n integration PR, addressing these would improve completeness and consistency.

Also applies to: 152-152, 1308-1308, 1320-1320, 1368-1368, 1848-1859, 1950-1950, 1959-1959, 1977-1977

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/extensions/core/groupNode.ts` at line 146, Several user-facing strings in
groupNode.ts remain hardcoded and must be wrapped with the i18n t() call; locate
the messages and replace literal strings with t('...') keys. Specifically,
update the long duplicate-name error used when creating a group node, the
overwrite confirmation dialog (overwriteConfirmation/confirmOverwriteGroupNode),
the context-menu labels (menu entries that render 'Convert to nodes', 'Manage
Group Node', 'Convert to Group Node (Deprecated)', 'Manage Group Nodes'), the
dynamic progress label in the createGroupNodeProgress / progress update routine,
and the selection validation errors inside convertToGroupNode /
validateSelection that currently return 'No nodes selected', 'Please select
multiple nodes to convert to group node', 'Selected nodes contain a subgraph
node', and 'Selected nodes contain a group node'; replace each literal with an
appropriate t('...') key and ensure any interpolations use the i18n format used
elsewhere in the file.
src/components/common/Badge.stories.ts (1)

62-62: 💤 Low value

Consider whether numeric labels need translation.

Line 62 wraps the number '3' in t('g.3'). Numbers using Arabic numerals (0-9) are typically universal and don't require translation. Unless there's a specific requirement for locale-specific numeral systems, this may be unnecessary overhead.

💡 Optional: Keep numeric literals as-is
-    label: t('g.3'),
+    label: '3',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/common/Badge.stories.ts` at line 62, The label currently uses
a translation call t('g.3') in Badge.stories (the label property on the story)
even though it is a plain Arabic numeral; change it to use the literal '3'
(i.e., label: '3') unless you have a specific locale-specific numeral
requirement or the translation key 'g.3' carries semantic meaning beyond the
digit, in which case keep the key but document the reason.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/common/badge.variants.ts`:
- Line 16: The badge variant's label property currently wraps a Tailwind class
string in t(...) (the `label: t('h-3.5 px-1 text-3xs font-semibold uppercase')`
usage) which is wrong; change the value to a hardcoded string `'h-3.5 px-1
text-3xs font-semibold uppercase'` (do not translate CSS classes) and remove the
unused `t` import from this module if nothing else uses it so there are no
unused imports.

In `@src/components/common/statusBadge.variants.ts`:
- Line 16: The CSS class string passed to label in statusBadge variants is
incorrectly wrapped in the translation function t (e.g., the label value 'h-3.5
px-1 text-3xs font-semibold uppercase'); remove t() and restore the hardcoded
class string on the label property in statusBadge.variants.ts, and if the t
import is no longer used anywhere in that module remove the t import also.

In `@src/components/load3d/controls/ExportControls.vue`:
- Line 1: The import statement "import { t } from '@/i18n'" is currently placed
before the <template> tag and causes a syntax error; move that import into the
component's <script setup lang="ts"> block (the existing script block in
ExportControls.vue) so it resides alongside other imports used by the component,
ensuring the translation helper "t" is available to the template and script
without breaking SFC structure.

In `@src/components/load3d/controls/viewer/ViewerExportControls.vue`:
- Line 1: The import statement "import { t } from '@/i18n'" is placed outside
the Vue SFC script block causing a syntax error; move that import into the
component's <script setup lang="ts"> block so the symbol t is available at
runtime and compilation succeeds—open ViewerExportControls.vue, remove the
top-level import and add "import { t } from '@/i18n'" inside the existing
<script setup lang="ts"> section that contains the component logic.

In `@src/components/load3d/controls/viewer/ViewerModelControls.vue`:
- Around line 65-70: The axis dropdown labels currently use t('g.x'), t('g.y'),
t('g.z') for both positive and negative options, making entries like value: '-x'
and value: '+x' indistinguishable; update the label generation for the array in
ViewerModelControls.vue (the objects with values '-x','+x','-y','+y','-z','+z')
to produce distinct localized labels (e.g., prefix the sign or use dedicated
keys) — either add/consume translation keys such as
load3d.upDirections.negativeX/positiveX etc., or construct labels by combining a
sign label with t('g.x') (e.g., t('g.sign.negative') + ' ' + t('g.x')) so each
option renders as "-X", "+X", "-Y", "+Y", "-Z", "+Z" (localized) to make
directions unambiguous.

In `@src/components/ui/multi-select/MultiSelect.stories.ts`:
- Line 1: Replace hardcoded label props in the MultiSelect stories with i18n
lookups: update each label="Category", label="Default", label="With Selection",
and label="Disabled" in MultiSelect.stories.ts to call t(...) (e.g.,
t('g.category') style) and add corresponding keys for "Default", "With
Selection", and "Disabled" to the English locale JSON used by the app (the main
locale file) so t('<your.key>') resolves; ensure the file still imports t and
that the story template label props reference the new keys instead of literal
strings.

In `@src/components/ui/single-select/SingleSelect.stories.ts`:
- Line 1: The stories use hardcoded labels; update SingleSelect.stories.ts to
replace all literal user-facing strings ("Category", "Sorting Type", "Default",
"Disabled", "Invalid", "Loading") with i18n calls (use the same pattern as
meta.args.label, e.g. t('g.category') for Category) and add corresponding keys
to your English locale JSON (main.json) such as g.category, g.sortingType,
state.default, state.disabled, state.invalid, state.loading so the story
templates call t('<key>') instead of inline text; ensure you update every story
variant that currently uses those literals and keep meta.args.label as-is.

In `@src/components/widget/panel/LeftSidePanel.stories.ts`:
- Line 65: The hardcoded Storybook UI strings ('TAGS', 'CATEGORIES', 'ADVANCED
OPTIONS', 'Selected:') must be replaced with vue-i18n calls; update the
navItems[].label and any story/title or arg labels in LeftSidePanel.stories (the
places emitting 'TAGS' at navItems[], 'CATEGORIES', 'ADVANCED OPTIONS', and the
"Selected:" label) to call t('...') with appropriate keys (add entries in
src/locales/en/main.json) and import/use the i18n instance or composition API
(useI18n()/t) so the story file renders localized strings instead of hardcoded
text. Ensure keys match project naming conventions and add translations to
main.json.

In `@src/components/widget/SampleModelSelector.vue`:
- Line 1: The top-level ES import "import { t } from '@/i18n'" is outside the
SFC and must be moved into the component's <script setup lang="ts"> block; open
the existing <script setup lang="ts"> (or add one if missing) and place the
import there so the Vue SFC parses correctly and the t function is available
inside the component.

---

Outside diff comments:
In `@src/components/ui/chart/ChartBar.stories.ts`:
- Line 25: In ChartBar.stories.ts replace the hardcoded ariaLabel values with
vue-i18n calls (wrap the existing strings in t(...)) for both occurrences (the
ariaLabel property and the second ariaLabel at line 41), and add matching keys
to the English locale JSON under g (for example g.bar_chart_example_aria and
g.bar_chart_multiple_datasets_aria) so the story uses
t('g.bar_chart_example_aria') and t('g.bar_chart_multiple_datasets_aria')
instead of literal strings.

In `@src/components/ui/chart/ChartLine.stories.ts`:
- Line 25: Replace the hard-coded English ariaLabel values in the
ChartLine.stories.ts story exports with vue-i18n lookups: add the keys
g.line_chart_example_aria and g.line_chart_multiple_lines_aria to
src/locales/en/main.json, import and initialize i18n in the story (e.g., useI18n
/ t) and set the story args ariaLabel to t('g.line_chart_example_aria') and
t('g.line_chart_multiple_lines_aria') respectively (references: ariaLabel in
ChartLine.stories.ts and the new locale keys g.line_chart_example_aria /
g.line_chart_multiple_lines_aria).

In `@src/components/widget/layout/BaseModalLayout.stories.ts`:
- Around line 93-126: The local placeholder "const t = (k: string) => k" in
BaseModalLayout.stories.ts is shadowing the real i18n translator and causing
labels (e.g. items with label: t('g.installed'), t('g.sd_1_5'), etc.) to render
keys; remove or rename that local const and wire the story to the actual
vue-i18n translator (use the imported t or call useI18n() so the labels call the
real t function), and add any new keys referenced (g.installed, g.sd_1_5,
g.sdxl, g.utility, g.models, g.nodes, etc.) to src/locales/en/main.json per
guidelines.

---

Nitpick comments:
In `@src/components/common/Badge.stories.ts`:
- Line 62: The label currently uses a translation call t('g.3') in Badge.stories
(the label property on the story) even though it is a plain Arabic numeral;
change it to use the literal '3' (i.e., label: '3') unless you have a specific
locale-specific numeral requirement or the translation key 'g.3' carries
semantic meaning beyond the digit, in which case keep the key but document the
reason.

In `@src/extensions/core/groupNode.ts`:
- Line 146: Several user-facing strings in groupNode.ts remain hardcoded and
must be wrapped with the i18n t() call; locate the messages and replace literal
strings with t('...') keys. Specifically, update the long duplicate-name error
used when creating a group node, the overwrite confirmation dialog
(overwriteConfirmation/confirmOverwriteGroupNode), the context-menu labels (menu
entries that render 'Convert to nodes', 'Manage Group Node', 'Convert to Group
Node (Deprecated)', 'Manage Group Nodes'), the dynamic progress label in the
createGroupNodeProgress / progress update routine, and the selection validation
errors inside convertToGroupNode / validateSelection that currently return 'No
nodes selected', 'Please select multiple nodes to convert to group node',
'Selected nodes contain a subgraph node', and 'Selected nodes contain a group
node'; replace each literal with an appropriate t('...') key and ensure any
interpolations use the i18n format used elsewhere in the file.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ce0e116e-0bba-4260-8db2-8386ce0f6650

📥 Commits

Reviewing files that changed from the base of the PR and between 05eed16 and 54aef31.

📒 Files selected for processing (33)
  • .i18nrc.cjs
  • src/components/chip/Tag.stories.ts
  • src/components/common/Badge.stories.ts
  • src/components/common/badge.variants.ts
  • src/components/common/statusBadge.variants.ts
  • src/components/custom/widget/WorkflowTemplateSelectorDialog.vue
  • src/components/helpcenter/HelpCenterMenuContent.vue
  • src/components/load3d/controls/ExportControls.vue
  • src/components/load3d/controls/viewer/ViewerExportControls.vue
  • src/components/load3d/controls/viewer/ViewerModelControls.vue
  • src/components/sidebar/ComfyMenuButton.vue
  • src/components/sidebar/tabs/AssetsSidebarListView.stories.ts
  • src/components/sidebar/tabs/nodeLibrary/NodeBookmarkTreeExplorer.vue
  • src/components/ui/chart/ChartBar.stories.ts
  • src/components/ui/chart/ChartLine.stories.ts
  • src/components/ui/multi-select/MultiSelect.stories.ts
  • src/components/ui/single-select/SingleSelect.stories.ts
  • src/components/widget/SampleModelSelector.vue
  • src/components/widget/layout/BaseModalLayout.stories.ts
  • src/components/widget/nav/NavItem.stories.ts
  • src/components/widget/panel/LeftSidePanel.stories.ts
  • src/composables/graph/contextMenuConverter.ts
  • src/composables/graph/useGroupMenuOptions.ts
  • src/composables/sidebarTabs/useAssetsSidebarTab.ts
  • src/composables/sidebarTabs/useJobHistorySidebarTab.ts
  • src/composables/sidebarTabs/useModelLibrarySidebarTab.ts
  • src/composables/sidebarTabs/useNodeLibrarySidebarTab.ts
  • src/extensions/core/electronAdapter.ts
  • src/extensions/core/groupNode.ts
  • src/extensions/core/load3d.ts
  • src/extensions/core/load3d/exportMenuHelper.ts
  • src/locales/en/main.json
  • src/locales/zh/main.json
💤 Files with no reviewable changes (1)
  • .i18nrc.cjs
✅ Files skipped from review due to trivial changes (11)
  • src/composables/sidebarTabs/useAssetsSidebarTab.ts
  • src/composables/sidebarTabs/useModelLibrarySidebarTab.ts
  • src/composables/graph/contextMenuConverter.ts
  • src/components/sidebar/ComfyMenuButton.vue
  • src/components/helpcenter/HelpCenterMenuContent.vue
  • src/composables/graph/useGroupMenuOptions.ts
  • src/extensions/core/electronAdapter.ts
  • src/components/sidebar/tabs/nodeLibrary/NodeBookmarkTreeExplorer.vue
  • src/extensions/core/load3d.ts
  • src/components/custom/widget/WorkflowTemplateSelectorDialog.vue
  • src/locales/zh/main.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/locales/en/main.json

Comment thread src/components/common/badge.variants.ts Outdated
},
variant: {
label: 'h-3.5 px-1 text-3xs font-semibold uppercase',
label: t('g.h_3_5_px_1_text_3xs_font_semibold_uppercase'),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

CSS classes must not be translated.

Line 16 wraps a Tailwind CSS class string in t(), which is incorrect. The value 'h-3.5 px-1 text-3xs font-semibold uppercase' is a technical CSS identifier, not user-facing text. Translating CSS classes will break styling if the translation differs across locales and adds unnecessary runtime overhead.

CSS classes should remain hardcoded strings. The i18n guideline applies to user-facing strings, not technical identifiers.

🔧 Revert to hardcoded CSS class
-      label: t('g.h_3_5_px_1_text_3xs_font_semibold_uppercase'),
+      label: 'h-3.5 px-1 text-3xs font-semibold uppercase',

And remove the t import if it's no longer used:

-import { t } from '@/i18n'
 import type { VariantProps } from 'cva'

As per coding guidelines, use vue-i18n for user-facing string literals, not for technical identifiers like CSS classes.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
label: t('g.h_3_5_px_1_text_3xs_font_semibold_uppercase'),
label: 'h-3.5 px-1 text-3xs font-semibold uppercase',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/common/badge.variants.ts` at line 16, The badge variant's
label property currently wraps a Tailwind class string in t(...) (the `label:
t('h-3.5 px-1 text-3xs font-semibold uppercase')` usage) which is wrong; change
the value to a hardcoded string `'h-3.5 px-1 text-3xs font-semibold uppercase'`
(do not translate CSS classes) and remove the unused `t` import from this module
if nothing else uses it so there are no unused imports.

Comment thread src/components/common/statusBadge.variants.ts Outdated
Comment thread src/components/load3d/controls/ExportControls.vue Outdated
Comment thread src/components/load3d/controls/viewer/ViewerExportControls.vue Outdated
Comment on lines +65 to +70
{ label: t('g.x'), value: '-x' },
{ label: t('g.x'), value: '+x' },
{ label: t('g.y'), value: '-y' },
{ label: t('g.y'), value: '+y' },
{ label: t('g.z'), value: '-z' },
{ label: t('g.z'), value: '+z' }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Axis direction labels are ambiguous and indistinguishable.

The six axis direction options now all use generic axis labels (t('g.x'), t('g.y'), t('g.z')), meaning both positive and negative directions for each axis display the same text. For example, both the -x and +x values will render as "X" (or whatever t('g.x') returns), making it impossible for users to distinguish between them in the dropdown.

Users need to see distinct labels like "-X", "+X", "-Y", "+Y", "-Z", "+Z" (or localized equivalents) to select the correct up direction.

🔧 Proposed fix with distinct direction labels
 const upDirectionOptions = [
   { label: t('load3d.upDirections.original'), value: 'original' },
-  { label: t('g.x'), value: '-x' },
-  { label: t('g.x'), value: '+x' },
-  { label: t('g.y'), value: '-y' },
-  { label: t('g.y'), value: '+y' },
-  { label: t('g.z'), value: '-z' },
-  { label: t('g.z'), value: '+z' }
+  { label: '-' + t('g.x'), value: '-x' },
+  { label: '+' + t('g.x'), value: '+x' },
+  { label: '-' + t('g.y'), value: '-y' },
+  { label: '+' + t('g.y'), value: '+y' },
+  { label: '-' + t('g.z'), value: '-z' },
+  { label: '+' + t('g.z'), value: '+z' }
 ]

Alternatively, add dedicated translation keys for each direction (e.g., t('load3d.upDirections.negativeX')) if the format needs to vary by locale.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{ label: t('g.x'), value: '-x' },
{ label: t('g.x'), value: '+x' },
{ label: t('g.y'), value: '-y' },
{ label: t('g.y'), value: '+y' },
{ label: t('g.z'), value: '-z' },
{ label: t('g.z'), value: '+z' }
const upDirectionOptions = [
{ label: t('load3d.upDirections.original'), value: 'original' },
{ label: '-' + t('g.x'), value: '-x' },
{ label: '+' + t('g.x'), value: '+x' },
{ label: '-' + t('g.y'), value: '-y' },
{ label: '+' + t('g.y'), value: '+y' },
{ label: '-' + t('g.z'), value: '-z' },
{ label: '+' + t('g.z'), value: '+z' }
]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/load3d/controls/viewer/ViewerModelControls.vue` around lines
65 - 70, The axis dropdown labels currently use t('g.x'), t('g.y'), t('g.z') for
both positive and negative options, making entries like value: '-x' and value:
'+x' indistinguishable; update the label generation for the array in
ViewerModelControls.vue (the objects with values '-x','+x','-y','+y','-z','+z')
to produce distinct localized labels (e.g., prefix the sign or use dedicated
keys) — either add/consume translation keys such as
load3d.upDirections.negativeX/positiveX etc., or construct labels by combining a
sign label with t('g.x') (e.g., t('g.sign.negative') + ' ' + t('g.x')) so each
option renders as "-X", "+X", "-Y", "+Y", "-Z", "+Z" (localized) to make
directions unambiguous.

@@ -1,3 +1,4 @@
import { t } from '@/i18n'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify locale key 'g.category' exists
rg -n "category" src/locales/en/main.json

# Find all hardcoded label strings in this story file
rg -n 'label="[^"]+"' src/components/ui/multi-select/MultiSelect.stories.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1896


🏁 Script executed:

cat -n src/components/ui/multi-select/MultiSelect.stories.ts | head -160

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 6204


🏁 Script executed:

sed -n '220,260p' src/locales/en/main.json

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1598


🏁 Script executed:

rg -B2 -A2 '"category"' src/locales/en/main.json | head -40

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 581


🏁 Script executed:

sed -n '1,10p' src/locales/en/main.json && echo "..." && sed -n '220,240p' src/locales/en/main.json

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1240


🏁 Script executed:

rg -B5 '"category":\s*"Category"' src/locales/en/main.json | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 422


Localize all hardcoded label strings to comply with i18n guidelines.

Multiple label prop values remain hardcoded in story templates when they should use vue-i18n. Lines 70, 83, 96, 110, 127 use label="Category", and lines 145–155 use label="Default", label="With Selection", and label="Disabled". These are user-facing component labels and must be localized per coding guidelines requiring vue-i18n for ALL user-facing strings in src/**/*.{ts,tsx,vue} files. Add locale entries for "Default", "With Selection", and "Disabled" to src/locales/en/main.json and update the templates to use t() for consistency with line 31's label: t('g.category').

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/multi-select/MultiSelect.stories.ts` at line 1, Replace
hardcoded label props in the MultiSelect stories with i18n lookups: update each
label="Category", label="Default", label="With Selection", and label="Disabled"
in MultiSelect.stories.ts to call t(...) (e.g., t('g.category') style) and add
corresponding keys for "Default", "With Selection", and "Disabled" to the
English locale JSON used by the app (the main locale file) so t('<your.key>')
resolves; ensure the file still imports t and that the story template label
props reference the new keys instead of literal strings.

@@ -1,3 +1,4 @@
import { t } from '@/i18n'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all hardcoded label strings in this story file
rg -n 'label="[^"]+"' src/components/ui/single-select/SingleSelect.stories.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1490


🏁 Script executed:

head -40 src/components/ui/single-select/SingleSelect.stories.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1062


🏁 Script executed:

# Check other story files to see if they use hardcoded labels or i18n
find src -name "*.stories.ts" -type f | head -10 | xargs -I {} sh -c 'echo "=== {} ===" && head -5 {} && grep -n "label=" {} | head -3'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2524


🏁 Script executed:

# Check MultiSelect.stories.ts mentioned in scratchpad
head -40 src/components/ui/multi-select/MultiSelect.stories.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1065


Localize all user-facing strings in story templates to match the i18n usage in meta.args.

The meta.args.label correctly uses t('g.category'), but hardcoded label strings remain scattered throughout individual story templates (lines 73, 86, 104, 117, 130, and 151–163). Per coding guidelines, all user-facing strings should use vue-i18n. Localize "Category", "Sorting Type", and state labels ("Default", "Disabled", "Invalid", "Loading") by adding entries to src/locales/en/main.json and replacing hardcoded values with corresponding t() calls.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/single-select/SingleSelect.stories.ts` at line 1, The
stories use hardcoded labels; update SingleSelect.stories.ts to replace all
literal user-facing strings ("Category", "Sorting Type", "Default", "Disabled",
"Invalid", "Loading") with i18n calls (use the same pattern as meta.args.label,
e.g. t('g.category') for Category) and add corresponding keys to your English
locale JSON (main.json) such as g.category, g.sortingType, state.default,
state.disabled, state.invalid, state.loading so the story templates call
t('<key>') instead of inline text; ensure you update every story variant that
currently uses those literals and keep meta.args.label as-is.

icon: 'icon-[lucide--download]'
},
{
title: 'TAGS',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the remaining hardcoded Storybook UI strings

Nice progress on navItems[].label, but these visible strings are still hardcoded: 'TAGS', 'CATEGORIES', 'ADVANCED OPTIONS', and 'Selected:'. To keep this file fully locale-safe, switch them to t(...) keys too.

Suggested patch
       {
-        title: 'TAGS',
+        title: t('g.tags'),
         items: [
@@
       {
-        title: 'CATEGORIES',
+        title: t('g.categories'),
         items: [
@@
         <div class="mt-4 p-2 text-sm">
-          Selected: {{ selectedItem }}
+          {{ t('g.selected') }}: {{ selectedItem }}
         </div>
@@
       {
-        title: 'ADVANCED OPTIONS',
+        title: t('g.advanced_options'),
         items: [

As per coding guidelines, "Use vue-i18n for ALL user-facing strings, configured in src/locales/en/main.json."

Also applies to: 85-85, 111-111, 173-173

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/widget/panel/LeftSidePanel.stories.ts` at line 65, The
hardcoded Storybook UI strings ('TAGS', 'CATEGORIES', 'ADVANCED OPTIONS',
'Selected:') must be replaced with vue-i18n calls; update the navItems[].label
and any story/title or arg labels in LeftSidePanel.stories (the places emitting
'TAGS' at navItems[], 'CATEGORIES', 'ADVANCED OPTIONS', and the "Selected:"
label) to call t('...') with appropriate keys (add entries in
src/locales/en/main.json) and import/use the i18n instance or composition API
(useI18n()/t) so the story file renders localized strings instead of hardcoded
text. Ensure keys match project naming conventions and add translations to
main.json.

Comment thread src/components/widget/SampleModelSelector.vue Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/platform/assets/composables/useModelTypes.ts`:
- Around line 11-73: The composable currently hardcodes user-facing Chinese
labels and descriptions (see chineseNames and descriptions objects in
formatDisplayName and getModelFolderDescription); replace these hardcoded
strings with vue-i18n translation keys resolved via t(...) calls: move each
label and description into src/locales/en/main.json with clear keys (e.g.,
modelTypes.checkpoints, modelDescriptions.checkpoints), update formatDisplayName
to call t('modelTypes.' + folderName) with a safe fallback that uses
t('modelTypes.defaultFormat', { name: formatDisplayNameFallback(folderName) })
or similar, and update getModelFolderDescription to return
t('modelDescriptions.' + folderName, { default: t('modelDescriptions.default', {
name: formatDisplayName(folderName) }) }); ensure you keep the existing function
names (formatDisplayName, getModelFolderDescription) and the logic for the
underscore-to-title fallback but move all user strings into the locale JSON.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0d846eef-77e4-4a15-8a35-0092bb0d903b

📥 Commits

Reviewing files that changed from the base of the PR and between 54aef31 and 5e00a99.

📒 Files selected for processing (1)
  • src/platform/assets/composables/useModelTypes.ts

Comment on lines +11 to +73
// Chinese display names
const chineseNames: Record<string, string> = {
checkpoints: '基础模型 (Checkpoints)',
loras: '微调模型 (LoRA)',
vae: '编解码器 (VAE)',
text_encoders: '文本编码器',
diffusion_models: '扩散模型',
clip_vision: '视觉理解 (CLIP Vision)',
style_models: '风格模型',
embeddings: '嵌入向量',
diffusers: '扩散器',
vae_approx: 'VAE 近似',
controlnet: '控制网络 (ControlNet)',
gligen: '定位生成 (GLIGEN)',
upscale_models: '超分模型 (Upscale)',
latent_upscale_models: 'Latent 超分模型',
hypernetworks: '超网络',
photomaker: '照片生成器',
classifiers: '分类器',
model_patches: '模型补丁',
audio_encoders: '音频编码器',
frame_interpolation: '帧插值',
download_model_base: '模型下载目录',
ipadapter: '图像适配器 (IP-Adapter)',
sams: '分割模型 (SAM)',
animatediff_motion_lora: '动画差分运动 LoRA',
animatediff_models: '动画差分模型',
sam2: '分割模型 2 (SAM 2)',
insightface: '人脸识别 (InsightFace)',
unet: 'UNet',
configs: '配置文件',
}
if (chineseNames[folderName]) return chineseNames[folderName]

// Fallback: format from underscore to title case
return folderName
.split('_')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')
}

/**
* Descriptions for model folders - shown as tooltips
*/
export function getModelFolderDescription(folderName: string): string {
const descriptions: Record<string, string> = {
checkpoints: '主模型文件,存放 Stable Diffusion 等基础模型,是图像生成的核心',
loras: '低秩适配模型,用于微调风格、角色、姿势等特定效果',
vae: '变分自编码器,负责图像编解码,影响色彩和细节',
text_encoders: '文本编码器模型,将文字提示转换为 AI 能理解的向量',
diffusion_models: '扩散模型文件,用于扩散过程的模型参数',
clip_vision: '视觉理解模型,用于图像反推提示词和风格参考',
style_models: '风格模型,用于控制生成图像的风格和画风',
embeddings: '文本嵌入向量,存放 Textual Inversion 等嵌入文件',
controlnet: '控制网络模型,用于精确控制图像构图、姿势、深度等',
upscale_models: '图像超分放大模型,用于提升图像分辨率',
vae_approx: 'VAE 近似模型,用于快速预览时的临时编解码',
hypernetworks: '超网络模型,一种轻量级的模型微调方式',
gligen: '空间定位生成模型,可根据边界框控制物体位置',
unet: 'UNet 架构模型,扩散模型的核心去噪网络',
}
return descriptions[folderName] || '存放 ' + formatDisplayName(folderName) + ' 相关模型文件'
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify user-facing hardcoded literals in this file and check for i18n usage.
# Expected: hardcoded Chinese strings are present; no t(...) calls in this file.
rg -n --pcre2 "[\x{4E00}-\x{9FFF}]" src/platform/assets/composables/useModelTypes.ts
rg -n "\bt\s*\(" src/platform/assets/composables/useModelTypes.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1745


Use vue-i18n for model type labels and descriptions

Lines 11-49 and 52-72 contain hardcoded Chinese strings for model type labels and folder descriptions. These should be externalized as translation keys in src/locales/en/main.json and resolved via t(...) calls, not hardcoded in the composable. This includes the chineseNames object, the descriptions object, and the fallback string on line 72.

Per coding guidelines: "Use vue-i18n for ALL user-facing strings, configured in src/locales/en/main.json."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/assets/composables/useModelTypes.ts` around lines 11 - 73, The
composable currently hardcodes user-facing Chinese labels and descriptions (see
chineseNames and descriptions objects in formatDisplayName and
getModelFolderDescription); replace these hardcoded strings with vue-i18n
translation keys resolved via t(...) calls: move each label and description into
src/locales/en/main.json with clear keys (e.g., modelTypes.checkpoints,
modelDescriptions.checkpoints), update formatDisplayName to call t('modelTypes.'
+ folderName) with a safe fallback that uses t('modelTypes.defaultFormat', {
name: formatDisplayNameFallback(folderName) }) or similar, and update
getModelFolderDescription to return t('modelDescriptions.' + folderName, {
default: t('modelDescriptions.default', { name: formatDisplayName(folderName) })
}); ensure you keep the existing function names (formatDisplayName,
getModelFolderDescription) and the logic for the underscore-to-title fallback
but move all user strings into the locale JSON.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
src/components/common/statusBadge.variants.ts (1)

1-1: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore Tailwind class utilities for variant.label (current value breaks styling).

Line 16 sets label to a translation-key-like token (g.h_...) instead of actual utility classes, so the label variant will not receive the intended styles.

🔧 Suggested fix
-import { t } from '@/i18n'
 import type { VariantProps } from 'cva'
 import { cva } from 'cva'
@@
-      label: 'g.h_3_5_px_1_text_3xs_font_semibold_uppercase',
+      label: 'h-3.5 px-1 text-3xs font-semibold uppercase',

As per coding guidelines, use vue-i18n for user-facing strings, not technical style tokens/classes.

Also applies to: 16-16

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/common/statusBadge.variants.ts` at line 1, The variant
definition sets variant.label to a translation-key-like token instead of
Tailwind utility classes, breaking styling; update the variant object (the label
property on the relevant variant in statusBadge.variants.ts) to contain the
intended Tailwind utility class string(s) (e.g., spacing/typography/bg/text
classes) instead of that token, and ensure only user-facing text uses the i18n
helper t(...) (do not wrap CSS classes with t). Locate the variant.label
property in the exported variants object and replace the token with the actual
utility classes so styling is restored.
src/components/common/badge.variants.ts (1)

1-1: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

badgeVariants.variant.label should remain a concrete utility-class string.

Line 16 uses a key-like value (g.h_...) instead of Tailwind classes, which breaks the label variant’s styling output.

🔧 Suggested fix
-import { t } from '@/i18n'
 import type { VariantProps } from 'cva'
 import { cva } from 'cva'
@@
-      label: 'g.h_3_5_px_1_text_3xs_font_semibold_uppercase',
+      label: 'h-3.5 px-1 text-3xs font-semibold uppercase',

As per coding guidelines, use vue-i18n for user-facing strings, not technical style tokens/classes.

Also applies to: 16-16

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/common/badge.variants.ts` at line 1,
badgeVariants.variant.label is using a key-like token (e.g. "g.h_...") instead
of concrete Tailwind utility classes which breaks styling; update the
badgeVariants.variant.label entry to be a proper utility-class string (compose
the expected Tailwind classes for the label, e.g. sizing, padding, typography,
colors) rather than a translation key or token, and remove any use of t(...) or
vue-i18n for style tokens—keep i18n only for user-facing text and ensure the
label value is a plain utility-class string so rendering uses real CSS classes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/components/common/badge.variants.ts`:
- Line 1: badgeVariants.variant.label is using a key-like token (e.g. "g.h_...")
instead of concrete Tailwind utility classes which breaks styling; update the
badgeVariants.variant.label entry to be a proper utility-class string (compose
the expected Tailwind classes for the label, e.g. sizing, padding, typography,
colors) rather than a translation key or token, and remove any use of t(...) or
vue-i18n for style tokens—keep i18n only for user-facing text and ensure the
label value is a plain utility-class string so rendering uses real CSS classes.

In `@src/components/common/statusBadge.variants.ts`:
- Line 1: The variant definition sets variant.label to a translation-key-like
token instead of Tailwind utility classes, breaking styling; update the variant
object (the label property on the relevant variant in statusBadge.variants.ts)
to contain the intended Tailwind utility class string(s) (e.g.,
spacing/typography/bg/text classes) instead of that token, and ensure only
user-facing text uses the i18n helper t(...) (do not wrap CSS classes with t).
Locate the variant.label property in the exported variants object and replace
the token with the actual utility classes so styling is restored.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3d264d62-eded-4c40-8176-bf164d044d1b

📥 Commits

Reviewing files that changed from the base of the PR and between 5e00a99 and af5dc9b.

📒 Files selected for processing (5)
  • src/components/common/badge.variants.ts
  • src/components/common/statusBadge.variants.ts
  • src/components/load3d/controls/ExportControls.vue
  • src/components/load3d/controls/viewer/ViewerExportControls.vue
  • src/components/widget/SampleModelSelector.vue
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/load3d/controls/ExportControls.vue
  • src/components/load3d/controls/viewer/ViewerExportControls.vue
  • src/components/widget/SampleModelSelector.vue

@LifetimeVip
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant