Skip to content

perf(json-editor): unify admin JSON editing experience - #6421

Merged
Calcium-Ion merged 4 commits into
mainfrom
perf/json-editor-experience
Jul 25, 2026
Merged

perf(json-editor): unify admin JSON editing experience#6421
Calcium-Ion merged 4 commits into
mainfrom
perf/json-editor-experience

Conversation

@QuentinHsu

@QuentinHsu QuentinHsu commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)

概述

  • 统一管理后台多个配置页面的 JSON 输入体验。

改动说明

  • 引入基于 Yace 的公共 JSON 代码编辑器。
  • 将模型、渠道、内容、支付、限流等页面迁移到公共组件。
  • 支持语法高亮、行号、JSON 校验、格式化、复制和智能编辑行为。
  • 保留原有表单占位文本、字段属性、受控状态同步和失焦处理。
  • 增加 JSON 编辑器工具函数及组件交互测试。

效果

  • 减少重复的 JSON 输入实现。
  • 提升复杂 JSON 配置的可读性和编辑效率。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)
CleanShot 2026-07-23 at 22 23 00
CleanShot 2026-07-23 at 22 23 41

Summary by CodeRabbit

  • New Features
    • Introduced a consistent JSON code editor across configuration and settings screens, replacing basic textareas.
    • Added syntax highlighting, cursor position display, smart indentation, copy-to-clipboard, and synchronized scrolling.
    • Improved JSON validation status and tighter form/ARIA behavior for JSON fields.
  • Bug Fixes
    • Formatting now safely preserves invalid JSON drafts when formatting isn’t possible, preventing accidental data loss.
  • Tests
    • Added unit and component tests covering validation, cursor mapping, smart-enter, scroll sync, and formatting.

- integrate Yace for syntax highlighting, history, indentation, auto-closing, and smart line breaks.
- add copy support, cursor location feedback, and synchronized content and line-number scrolling.
- extract JSON editor utilities and cover key interactions with unit tests.
- replace raw JSON textareas with the shared editor for highlighting, validation, copy, and formatting.
- preserve field-specific examples and make placeholders visible through the transparent editor layer.
- remove duplicate formatting controls while keeping existing form validation and save behavior.
- replace pure JSON textareas with the shared editor across system settings and channel workflows.
- preserve form focus, validation, placeholders, and visual or JSON editing modes.
- add happy-dom component coverage for form bindings, controlled updates, and formatting.
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd5e5222-d66d-4ce5-8b52-c043735fb18f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f9e734 and 8886800.

📒 Files selected for processing (8)
  • web/src/components/json-code-editor.tsx
  • web/src/components/json-editor.tsx
  • web/src/features/channels/components/dialogs/advanced-custom-editor-dialog.tsx
  • web/src/features/channels/components/dialogs/param-override-editor-dialog.tsx
  • web/src/features/channels/components/model-mapping-editor.tsx
  • web/src/features/system-settings/general/channel-affinity/index.tsx
  • web/src/features/system-settings/general/channel-affinity/rule-editor-dialog.tsx
  • web/src/styles/index.css
🚧 Files skipped from review as they are similar to previous changes (7)
  • web/src/components/json-editor.tsx
  • web/src/features/channels/components/model-mapping-editor.tsx
  • web/src/styles/index.css
  • web/src/features/system-settings/general/channel-affinity/index.tsx
  • web/src/features/channels/components/dialogs/param-override-editor-dialog.tsx
  • web/src/features/channels/components/dialogs/advanced-custom-editor-dialog.tsx
  • web/src/components/json-code-editor.tsx

Walkthrough

Changes

Introduces a Yace-based JsonCodeEditor with JSON formatting, validation, cursor tracking, smart-enter behavior, clipboard actions, and form integration. Migrates JSON fields across channel, model, payment, content, and system-settings forms, with new tests and editor styling.

Application integration

Layer / File(s) Summary
Editor foundation and behavior
web/src/components/json-code-editor/*, web/package.json
Adds editor dependencies and utilities for validation, formatting, cursor mapping, scrolling, and smart-enter behavior.
Yace editor implementation
web/src/components/json-code-editor.tsx, web/src/components/json-editor.tsx, web/src/styles/index.css
Replaces textarea rendering with Yace, controlled updates, form attributes, validation status, cursor position, copy, formatting, and syntax styling.
Application JSON fields
web/src/features/channels/..., web/src/features/models/...
Migrates channel, model-mapping, deployment, and configuration JSON inputs to JsonCodeEditor.
System settings JSON fields
web/src/features/system-settings/...
Migrates JSON-backed settings forms while preserving React Hook Form bindings and validation attributes.
Editor tests
web/src/components/json-code-editor/__tests__/*
Adds utility and component tests for editor behavior, DOM integration, controlled updates, and formatting.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Yace
  participant JsonCodeEditor
  participant Form
  User->>Yace: Edit JSON
  Yace->>JsonCodeEditor: Emit update
  JsonCodeEditor->>Form: Forward value, blur, and ref
  JsonCodeEditor->>User: Show validation and cursor status
Loading

Suggested reviewers: calcium-ion

Poem

I’m a rabbit with JSON dreams,
Hopping through highlighted streams.
Braces nest, cursors glow,
Pretty formatting starts to flow.
Yace keeps every carrot aligned! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: a unified admin JSON editor experience and related performance improvements.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/json-editor-experience

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 4

🧹 Nitpick comments (2)
web/src/components/json-code-editor.tsx (1)

133-140: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Fragile reliance on yace's internal DOM structure for locating the line-number layer, with a silent total failure mode.

Detecting the line-number <pre> by elimination (!== editor.pre) assumes a specific, undocumented internal markup shape. If that assumption ever breaks (library update, edge-case content), the component doesn't degrade gracefully — it destroys the editor and renders nothing, leaving the JSON field completely non-functional with no visible error.

Consider (a) checking whether yace exposes a stable public reference to the line-numbers element instead of DOM-diffing, and (b) rendering a visible fallback/error state instead of silently destroying the editor when the assumption fails.

🤖 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 `@web/src/components/json-code-editor.tsx` around lines 133 - 140, Update the
line-number layer lookup in the editor initialization flow to use a stable
public yace reference or API instead of identifying a second <pre> via
editor.pre. If no valid line-number element can be obtained, preserve a visible
fallback or error state rather than destroying the editor and clearing
editorRef; update the surrounding cleanup logic accordingly.
web/package.json (1)

77-77: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Add an explicit packageManager/Bun lockfile entry for the new yace dependency.

web/package.json adds yace@^1.1.0 to production deps per the frontend guideline, but the package has no packageManager, and the locked dependency surface for this repo still needs to ensure Bun is responsible for installing this new dependency.

🤖 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 `@web/package.json` at line 77, Add an explicit packageManager entry in
web/package.json identifying Bun, and regenerate or update the Bun lockfile so
yace@^1.1.0 is represented in the locked dependency surface. Preserve the
existing dependency declaration and use the repository’s established Bun version
and lockfile conventions.

Source: Coding guidelines

🤖 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 `@web/src/components/json-code-editor/json-code-editor-utils.ts`:
- Around line 168-192: Update jsonSmartEnter to return undefined for IME
composition keydown events before calling applyJsonSmartEnter or preventDefault:
skip events where isComposing is true or the legacy keyCode is 229, while
preserving the existing Enter handling for normal keydowns.

In `@web/src/features/channels/components/dialogs/edit-tag-dialog.tsx`:
- Around line 373-378: Localize all five visible JSON editor placeholders by
passing their existing strings through the component’s useTranslation() t
function, and add the model-mapping placeholder’s flat locale entry. Update
web/src/features/channels/components/dialogs/edit-tag-dialog.tsx lines 373-378,
web/src/features/models/components/dialogs/create-deployment-drawer.tsx lines
705-712 and 729-736, and
web/src/features/models/components/dialogs/update-config-dialog.tsx lines
401-408 and 422-429; preserve each placeholder’s example content while using
translation keys consistently.

In `@web/src/features/system-settings/general/channel-affinity/index.tsx`:
- Around line 665-668: Associate each standalone label with its corresponding
JsonCodeEditor by assigning a stable unique id to the editor and matching it
through the label’s htmlFor: update the Rules JSON editor and label in
web/src/features/system-settings/general/channel-affinity/index.tsx (lines
665-668), and the Parameter Override Template editor and label in
web/src/features/system-settings/general/channel-affinity/rule-editor-dialog.tsx
(lines 442-461).

In
`@web/src/features/system-settings/general/channel-affinity/rule-editor-dialog.tsx`:
- Line 460: Update the user-visible placeholder in the rule editor dialog to use
the existing translation function t(...), ensuring the JSON example remains the
translated placeholder text and follows the i18n requirement.

---

Nitpick comments:
In `@web/package.json`:
- Line 77: Add an explicit packageManager entry in web/package.json identifying
Bun, and regenerate or update the Bun lockfile so yace@^1.1.0 is represented in
the locked dependency surface. Preserve the existing dependency declaration and
use the repository’s established Bun version and lockfile conventions.

In `@web/src/components/json-code-editor.tsx`:
- Around line 133-140: Update the line-number layer lookup in the editor
initialization flow to use a stable public yace reference or API instead of
identifying a second <pre> via editor.pre. If no valid line-number element can
be obtained, preserve a visible fallback or error state rather than destroying
the editor and clearing editorRef; update the surrounding cleanup logic
accordingly.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 78d94631-121d-4042-8a7d-38604ad3f3a1

📥 Commits

Reviewing files that changed from the base of the PR and between 1721144 and 9f9e734.

⛔ Files ignored due to path filters (1)
  • web/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (27)
  • web/package.json
  • web/src/components/json-code-editor.tsx
  • web/src/components/json-code-editor/__tests__/json-code-editor-utils.test.ts
  • web/src/components/json-code-editor/__tests__/json-code-editor.test.tsx
  • web/src/components/json-code-editor/json-code-editor-utils.ts
  • web/src/components/json-editor.tsx
  • web/src/features/channels/components/dialogs/advanced-custom-editor-dialog.tsx
  • web/src/features/channels/components/dialogs/edit-tag-dialog.tsx
  • web/src/features/channels/components/dialogs/param-override-editor-dialog.tsx
  • web/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/src/features/channels/components/model-mapping-editor.tsx
  • web/src/features/models/components/dialogs/create-deployment-drawer.tsx
  • web/src/features/models/components/dialogs/update-config-dialog.tsx
  • web/src/features/system-settings/auth/custom-oauth/components/provider-form-dialog.tsx
  • web/src/features/system-settings/content/chat-settings-section.tsx
  • web/src/features/system-settings/content/json-toggle-section.tsx
  • web/src/features/system-settings/general/channel-affinity/index.tsx
  • web/src/features/system-settings/general/channel-affinity/rule-editor-dialog.tsx
  • web/src/features/system-settings/integrations/payment-settings-section.tsx
  • web/src/features/system-settings/models/claude-settings-card.tsx
  • web/src/features/system-settings/models/gemini-settings-card.tsx
  • web/src/features/system-settings/models/global-settings-card.tsx
  • web/src/features/system-settings/models/group-ratio-form.tsx
  • web/src/features/system-settings/models/model-ratio-form.tsx
  • web/src/features/system-settings/models/tool-price-settings.tsx
  • web/src/features/system-settings/request-limits/rate-limit-section.tsx
  • web/src/styles/index.css

Comment on lines +168 to +192
export function jsonSmartEnter(): Plugin {
return (props, event) => {
if (event.type !== 'keydown') {
return undefined
}

const keyboardEvent = event as KeyboardEvent
if (keyboardEvent.key !== 'Enter') {
return undefined
}

const nextProps = applyJsonSmartEnter(
props.value,
props.selectionStart,
props.selectionEnd
)

if (!nextProps) {
return undefined
}

event.preventDefault()
return nextProps
}
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locate file and relevant plugins/tests"
git ls-files | rg 'json-code-editor-utils|json-code-editor|json-code.*editor|package.json|bun.lockb' || true

echo
fd -a 'json-code-editor-utils\.ts$|json-code-editor.*\.(ts|tsx)$' . | sed 's#^\./##'

echo
if [ -f web/src/components/json-code-editor/json-code-editor-utils.ts ]; then
  wc -l web/src/components/json-code-editor/json-code-editor-utils.ts
  ast-grep outline web/src/components/json-code-editor/json-code-editor-utils.ts || true
  sed -n '130,210p' web/src/components/json-code-editor/json-code-editor-utils.ts
fi

echo
rg -n "isComposing|keyCode === 229|jsonSmartEnter|SmartEnter|IM|IME|compositionStart|compositionEnd" web/src/components json-code-editor-utils.ts tests -S . 2>/dev/null | head -200

Repository: QuantumNous/new-api

Length of output: 23818


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "json-code-editor-utils imports/types/test related lines"
sed -n '1,70p' web/src/components/json-code-editor/json-code-editor-utils.ts
sed -n '1,140p' web/src/components/json-code-editor/__tests__/json-code-editor-utils.test.ts

echo
echo "json-code-editor plugin wiring"
sed -n '1,130p' web/src/components/json-code-editor.tsx

echo
echo "Package typing/runtime for KeyboardEvent isComposing"
sed -n '1,80p' web/package.json
if [ -f web/node_modules/typescript/lib/lib.dom.d.ts ]; then
  rg -n "interface KeyboardEvent|property isComposing|readonly isComposing" web/node_modules/typescript/lib/lib.dom.d.ts || true
else
  echo "web/node_modules/typescript/lib/lib.dom.d.ts not present"
fi

echo
echo "Static behavior probe: simulate jsonSmartEnter decision for IME composition Enter"
node - <<'JS'
function applyJsonSmartEnter(value, selectionStart, selectionEnd) {
  const before = value.slice(0, selectionStart)
  const after = value.slice(selectionEnd)
  const lineStart = value.lastIndexOf('\n', selectionStart - 1) + 1
  const indent = value.slice(lineStart, selectionStart).match(/^\s*/)?.[0] ?? ''
  const previousChar = before.trimEnd().at(-1)
  const nextChar = after.trimStart().at(0)
  const shouldNest = previousChar === '{' || previousChar === '['
  const shouldClose =
    (previousChar === '{' && nextChar === '}') ||
    (previousChar === '[' && nextChar === ']')

  if (shouldNest && shouldClose) {
    const innerIndent = `${indent}  `
    const insert = `\n${innerIndent}\n${indent}`
    const nextSelection = selectionStart + 1 + innerIndent.length
    return {
      value: `${before}${insert}${after}`,
      selectionStart: nextSelection,
      selectionEnd: nextSelection,
    }
  }

  if (!indent && !shouldNest) {
    return undefined
  }

  const nextIndent = shouldNest ? `${indent}  ` : indent
  const insert = `\n${nextIndent}`
  const nextSelection = selectionStart + insert.length

  return {
    value: `${before}${insert}${after}`,
    selectionStart: nextSelection,
    selectionEnd: nextSelection,
  }
}

function jsonSmartEnterDecision(props, event) {
  if (event.type !== 'keydown') {
    return { preventDefault: false, nextProps: undefined }
  }

  if (event.key !== 'Enter') {
    return { preventDefault: false, nextProps: undefined }
  }

  const nextProps = applyJsonSmartEnter(props.value, props.selectionStart, props.selectionEnd)

  if (!nextProps) {
    return { preventDefault: false, nextProps: undefined }
  }

  return { preventDefault: true, nextProps }
}

for (const event of [
  { type: 'keydown', key: 'Enter', isComposing: false, keyCode: 13 },
  { type: 'keydown', key: 'Enter', isComposing: true, keyCode: 13 },
  { type: 'keydown', key: 'Enter', isComposing: undefined, keyCode: 229 },
]) {
  const props = { value: '{', selectionStart: 1, selectionEnd: 1 }
  console.log(JSON.stringify(event), '=>', jsonSmartEnterDecision(props, event))
}
JS

Repository: QuantumNous/new-api

Length of output: 12094


Guard jsonSmartEnter against IME composition before intercepting Enter.

The plugin currently handles all native Enter keydowns and calls preventDefault(), including IME composition confirmation events (isComposing === true and legacy keyCode === 229). Those composition events should be skipped to avoid confirming CJK input as a newline plus indentation in the JSON draft.

🌐 Proposed fix to skip IME composition events
 export function jsonSmartEnter(): Plugin {
   return (props, event) => {
     if (event.type !== 'keydown') {
       return undefined
     }
 
     const keyboardEvent = event as KeyboardEvent
     if (keyboardEvent.key !== 'Enter') {
       return undefined
     }
+
+    if (keyboardEvent.isComposing || keyboardEvent.keyCode === 229) {
+      return undefined
+    }
 
     const nextProps = applyJsonSmartEnter(
📝 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
export function jsonSmartEnter(): Plugin {
return (props, event) => {
if (event.type !== 'keydown') {
return undefined
}
const keyboardEvent = event as KeyboardEvent
if (keyboardEvent.key !== 'Enter') {
return undefined
}
const nextProps = applyJsonSmartEnter(
props.value,
props.selectionStart,
props.selectionEnd
)
if (!nextProps) {
return undefined
}
event.preventDefault()
return nextProps
}
}
export function jsonSmartEnter(): Plugin {
return (props, event) => {
if (event.type !== 'keydown') {
return undefined
}
const keyboardEvent = event as KeyboardEvent
if (keyboardEvent.key !== 'Enter') {
return undefined
}
if (keyboardEvent.isComposing || keyboardEvent.keyCode === 229) {
return undefined
}
const nextProps = applyJsonSmartEnter(
props.value,
props.selectionStart,
props.selectionEnd
)
if (!nextProps) {
return undefined
}
event.preventDefault()
return nextProps
}
}
🤖 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 `@web/src/components/json-code-editor/json-code-editor-utils.ts` around lines
168 - 192, Update jsonSmartEnter to return undefined for IME composition keydown
events before calling applyJsonSmartEnter or preventDefault: skip events where
isComposing is true or the legacy keyCode is 229, while preserving the existing
Enter handling for normal keydowns.

Comment on lines +373 to +378
<JsonCodeEditor
id='model-mapping'
value={modelMapping}
onChange={(e) => setModelMapping(e.target.value)}
onChange={setModelMapping}
placeholder={'{\n "gpt-3.5-turbo": "gpt-3.5-turbo-0125"\n}'}
rows={4}
className='font-mono text-sm'
heightClassName='h-40 min-h-40 max-h-40'

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Localize the new editor placeholders.

These visible placeholder examples bypass t(), so they cannot be localized.

  • web/src/features/channels/components/dialogs/edit-tag-dialog.tsx#L373-L378: wrap the model-mapping placeholder in t() and add its flat locale entry.
  • web/src/features/models/components/dialogs/create-deployment-drawer.tsx#L705-L712: localize the environment JSON placeholder.
  • web/src/features/models/components/dialogs/create-deployment-drawer.tsx#L729-L736: localize the secret-environment JSON placeholder.
  • web/src/features/models/components/dialogs/update-config-dialog.tsx#L401-L408: localize the environment JSON placeholder.
  • web/src/features/models/components/dialogs/update-config-dialog.tsx#L422-L429: localize the secret-environment JSON placeholder.

As per coding guidelines, all user-facing React UI text under web/src must use useTranslation() and t(...).

📍 Affects 3 files
  • web/src/features/channels/components/dialogs/edit-tag-dialog.tsx#L373-L378 (this comment)
  • web/src/features/models/components/dialogs/create-deployment-drawer.tsx#L705-L712
  • web/src/features/models/components/dialogs/create-deployment-drawer.tsx#L729-L736
  • web/src/features/models/components/dialogs/update-config-dialog.tsx#L401-L408
  • web/src/features/models/components/dialogs/update-config-dialog.tsx#L422-L429
🤖 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 `@web/src/features/channels/components/dialogs/edit-tag-dialog.tsx` around
lines 373 - 378, Localize all five visible JSON editor placeholders by passing
their existing strings through the component’s useTranslation() t function, and
add the model-mapping placeholder’s flat locale entry. Update
web/src/features/channels/components/dialogs/edit-tag-dialog.tsx lines 373-378,
web/src/features/models/components/dialogs/create-deployment-drawer.tsx lines
705-712 and 729-736, and
web/src/features/models/components/dialogs/update-config-dialog.tsx lines
401-408 and 422-429; preserve each placeholder’s example content while using
translation keys consistently.

Source: Coding guidelines

Comment thread web/src/features/system-settings/general/channel-affinity/index.tsx
})
}}
textareaRef={paramOverrideTemplateField.ref}
placeholder='{"operations": [...]}'

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Translate the JSON placeholder.

Wrap this user-visible placeholder with t(...).

As per coding guidelines, “所有面向用户的文案必须支持 i18n”.

🤖 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
`@web/src/features/system-settings/general/channel-affinity/rule-editor-dialog.tsx`
at line 460, Update the user-visible placeholder in the rule editor dialog to
use the existing translation function t(...), ensuring the JSON example remains
the translated placeholder text and follows the i18n requirement.

Source: Coding guidelines

- Drop the unconditional aria-label that overrode every field's
  label-derived accessible name; add an optional ariaLabel prop and
  set it at call sites without an associated label
- Associate standalone Labels via htmlFor/id in channel-affinity views
- Hide the highlight mirror and line-number layers from the
  accessibility tree (aria-hidden)
- Give the line-number gutter an opaque background so horizontally
  scrolled code no longer slides under it
- Degrade to no scroll sync instead of destroying the editor when the
  line-number layer is not found
@Calcium-Ion
Calcium-Ion merged commit eb4a1bd into main Jul 25, 2026
1 check was pending
@QuentinHsu
QuentinHsu deleted the perf/json-editor-experience branch July 25, 2026 12:29
agogo233 pushed a commit to agogo233/new-api that referenced this pull request Jul 27, 2026
)

* perf(json-editor): improve JSON editing experience

- integrate Yace for syntax highlighting, history, indentation, auto-closing, and smart line breaks.
- add copy support, cursor location feedback, and synchronized content and line-number scrolling.
- extract JSON editor utilities and cover key interactions with unit tests.

* perf(system-settings): improve JSON configuration editing

- replace raw JSON textareas with the shared editor for highlighting, validation, copy, and formatting.
- preserve field-specific examples and make placeholders visible through the transparent editor layer.
- remove duplicate formatting controls while keeping existing form validation and save behavior.

* perf(json-editor): standardize JSON inputs across admin settings

- replace pure JSON textareas with the shared editor across system settings and channel workflows.
- preserve form focus, validation, placeholders, and visual or JSON editing modes.
- add happy-dom component coverage for form bindings, controlled updates, and formatting.

* fix(json-code-editor): address accessibility review findings

- Drop the unconditional aria-label that overrode every field's
  label-derived accessible name; add an optional ariaLabel prop and
  set it at call sites without an associated label
- Associate standalone Labels via htmlFor/id in channel-affinity views
- Hide the highlight mirror and line-number layers from the
  accessibility tree (aria-hidden)
- Give the line-number gutter an opaque background so horizontally
  scrolled code no longer slides under it
- Degrade to no scroll sync instead of destroying the editor when the
  line-number layer is not found
zhaodechao2008 pushed a commit to zhaodechao2008/new-api that referenced this pull request Jul 27, 2026
)

* perf(json-editor): improve JSON editing experience

- integrate Yace for syntax highlighting, history, indentation, auto-closing, and smart line breaks.
- add copy support, cursor location feedback, and synchronized content and line-number scrolling.
- extract JSON editor utilities and cover key interactions with unit tests.

* perf(system-settings): improve JSON configuration editing

- replace raw JSON textareas with the shared editor for highlighting, validation, copy, and formatting.
- preserve field-specific examples and make placeholders visible through the transparent editor layer.
- remove duplicate formatting controls while keeping existing form validation and save behavior.

* perf(json-editor): standardize JSON inputs across admin settings

- replace pure JSON textareas with the shared editor across system settings and channel workflows.
- preserve form focus, validation, placeholders, and visual or JSON editing modes.
- add happy-dom component coverage for form bindings, controlled updates, and formatting.

* fix(json-code-editor): address accessibility review findings

- Drop the unconditional aria-label that overrode every field's
  label-derived accessible name; add an optional ariaLabel prop and
  set it at call sites without an associated label
- Associate standalone Labels via htmlFor/id in channel-affinity views
- Hide the highlight mirror and line-number layers from the
  accessibility tree (aria-hidden)
- Give the line-number gutter an opaque background so horizontally
  scrolled code no longer slides under it
- Degrade to no scroll sync instead of destroying the editor when the
  line-number layer is not found
@coderabbitai coderabbitai Bot mentioned this pull request Jul 29, 2026
11 tasks
IQZZ020501 pushed a commit to IQZZ020501/new-api that referenced this pull request Jul 30, 2026
)

* perf(json-editor): improve JSON editing experience

- integrate Yace for syntax highlighting, history, indentation, auto-closing, and smart line breaks.
- add copy support, cursor location feedback, and synchronized content and line-number scrolling.
- extract JSON editor utilities and cover key interactions with unit tests.

* perf(system-settings): improve JSON configuration editing

- replace raw JSON textareas with the shared editor for highlighting, validation, copy, and formatting.
- preserve field-specific examples and make placeholders visible through the transparent editor layer.
- remove duplicate formatting controls while keeping existing form validation and save behavior.

* perf(json-editor): standardize JSON inputs across admin settings

- replace pure JSON textareas with the shared editor across system settings and channel workflows.
- preserve form focus, validation, placeholders, and visual or JSON editing modes.
- add happy-dom component coverage for form bindings, controlled updates, and formatting.

* fix(json-code-editor): address accessibility review findings

- Drop the unconditional aria-label that overrode every field's
  label-derived accessible name; add an optional ariaLabel prop and
  set it at call sites without an associated label
- Associate standalone Labels via htmlFor/id in channel-affinity views
- Hide the highlight mirror and line-number layers from the
  accessibility tree (aria-hidden)
- Give the line-number gutter an opaque background so horizontally
  scrolled code no longer slides under it
- Degrade to no scroll sync instead of destroying the editor when the
  line-number layer is not found
330079598 pushed a commit to 330079598/new-api that referenced this pull request Aug 19, 2026
)

* perf(json-editor): improve JSON editing experience

- integrate Yace for syntax highlighting, history, indentation, auto-closing, and smart line breaks.
- add copy support, cursor location feedback, and synchronized content and line-number scrolling.
- extract JSON editor utilities and cover key interactions with unit tests.

* perf(system-settings): improve JSON configuration editing

- replace raw JSON textareas with the shared editor for highlighting, validation, copy, and formatting.
- preserve field-specific examples and make placeholders visible through the transparent editor layer.
- remove duplicate formatting controls while keeping existing form validation and save behavior.

* perf(json-editor): standardize JSON inputs across admin settings

- replace pure JSON textareas with the shared editor across system settings and channel workflows.
- preserve form focus, validation, placeholders, and visual or JSON editing modes.
- add happy-dom component coverage for form bindings, controlled updates, and formatting.

* fix(json-code-editor): address accessibility review findings

- Drop the unconditional aria-label that overrode every field's
  label-derived accessible name; add an optional ariaLabel prop and
  set it at call sites without an associated label
- Associate standalone Labels via htmlFor/id in channel-affinity views
- Hide the highlight mirror and line-number layers from the
  accessibility tree (aria-hidden)
- Give the line-number gutter an opaque background so horizontally
  scrolled code no longer slides under it
- Degrade to no scroll sync instead of destroying the editor when the
  line-number layer is not found
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants