Skip to content

fix: improve tiered pricing number input editing - #4536

Merged
Calcium-Ion merged 2 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/tiered-pricing-number-input
Apr 30, 2026
Merged

fix: improve tiered pricing number input editing#4536
Calcium-Ion merged 2 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/tiered-pricing-number-input

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

⚠️ 提交说明 / PR Notice

Important

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

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)
修复新版 default UI 中阶梯定价数字输入框的编辑体验问题。
此前价格字段直接把输入值转换成 number 保存,导致输入框清空时空字符串会立刻被转换回 0,所以无法删除默认的 0。同时在默认值为 0 时直接输入数字,会变成类似 0111 的追加效果。
本次改动为阶梯定价编辑器的数字输入增加编辑态处理:输入过程中保留用户正在编辑的文本,允许临时清空;当字段为 0 且获得焦点时自动选中原值,使新输入可以直接替换默认 0。最终生成表达式时仍按原有逻辑把空值归一为 0,不改变计费语义。

🚀 变更类型 / 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

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)

iShot_2026-04-29_16.29.46.mp4

Summary by CodeRabbit

  • New Features
    • Label components now display styled asterisks to clearly mark required form fields
    • Tiered pricing editor features improved numeric input handling via new draft-based input component, ensuring consistent and reliable data entry across pricing fields, tier conditions, time values, multipliers, and token-related configurations

@coderabbitai

coderabbitai Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The PR updates the Label component to explicitly render children and detect/style trailing asterisks as required field markers, and refactors tiered pricing numeric inputs to use a new DraftNumberInput component that maintains draft state during editing.

Changes

Cohort / File(s) Summary
Label Component Enhancements
web/default/src/components/ui/label.tsx
Updated Label component to explicitly render children and detect trailing * characters, replacing them with styled <span className='text-destructive'>*</span> to visually indicate required fields.
Tiered Pricing Editor Refactoring
web/default/src/features/system-settings/models/tiered-pricing-editor.tsx
Introduced reusable DraftNumberInput component for managing draft string state during numeric input editing with normalization on blur. Refactored multiple numeric controls (tier conditions, pricing fields, time values, multipliers, cost estimator inputs) to use the new component, replacing ad-hoc onChange handlers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Calcium-Ion

Poem

🐰 A label's child now styles its mark,
With asterisks that glow so stark,
While numbers draft in pristine form,
Each blur and focus keeps them warm! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 describes the main change: introducing a DraftNumberInput component to improve number input editing experience in the tiered pricing editor.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@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: 1

🧹 Nitpick comments (2)
web/default/src/components/ui/label.tsx (1)

46-50: Align Label props handling with repo TSX convention.

This component now destructures props in the signature; the guideline requests using props.xxx directly.

As per coding guidelines: "Do not destructure component props unnecessarily; use props.xxx directly for clarity and to avoid unnecessary code complexity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/default/src/components/ui/label.tsx` around lines 46 - 50, The Label
component should stop destructuring props in its parameter list; change the
function signature to accept a single parameter named props of type
React.ComponentProps<typeof LabelPrimitive.Root> and inside the body reference
props.className, props.children and other props directly (instead of
destructured variables), then pass {...props} to LabelPrimitive.Root and compose
className using props.className; update any references to className/children in
the Label function to use props.xxx.
web/default/src/features/system-settings/models/tiered-pricing-editor.tsx (1)

325-333: Prefer props.xxx access over parameter destructuring in this component.

This new component destructures props in the function signature, which conflicts with the repo convention for TSX components.

Suggested refactor
-function DraftNumberInput({
-  value,
-  onValueChange,
-  selectZeroOnFocus = true,
-  onBlur,
-  onFocus,
-  onMouseUp,
-  ...props
-}: DraftNumberInputProps) {
-  const [draft, setDraft] = useState(() => formatNumberDraft(value))
+function DraftNumberInput(props: DraftNumberInputProps) {
+  const {
+    value,
+    onValueChange,
+    selectZeroOnFocus = true,
+    onBlur,
+    onFocus,
+    onMouseUp,
+    ...inputProps
+  } = props
+  const [draft, setDraft] = useState(() => formatNumberDraft(value))
@@
-      {...props}
+      {...inputProps}

As per coding guidelines: "Do not destructure component props unnecessarily; use props.xxx directly for clarity and to avoid unnecessary code complexity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/default/src/features/system-settings/models/tiered-pricing-editor.tsx`
around lines 325 - 333, The DraftNumberInput component currently destructures
props in its function signature; change it to accept a single props parameter
and replace all destructured references (value, onValueChange,
selectZeroOnFocus, onBlur, onFocus, onMouseUp, etc.) with props.value,
props.onValueChange, props.selectZeroOnFocus (defaulting props.selectZeroOnFocus
= true where used), and so on; update the DraftNumberInput function signature
and all internal usages to follow the repository convention of accessing props
via props.xxx rather than parameter destructuring.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/default/src/components/ui/label.tsx`:
- Around line 7-17: The required-marker regex only matches a trailing space
before '*' so labels like "Email*" are missed; update requiredMarkerPattern in
this file to match an optional space before the asterisk (e.g., use /\s*\*$/)
and change renderRequiredMarker to remove the marker robustly (for example,
strip the trailing space+asterisk via replace or trimEnd()+slice) before
rendering the label text and the <span className='text-destructive'>*</span>;
refer to requiredMarkerPattern and renderRequiredMarker to locate and apply the
fix.

---

Nitpick comments:
In `@web/default/src/components/ui/label.tsx`:
- Around line 46-50: The Label component should stop destructuring props in its
parameter list; change the function signature to accept a single parameter named
props of type React.ComponentProps<typeof LabelPrimitive.Root> and inside the
body reference props.className, props.children and other props directly (instead
of destructured variables), then pass {...props} to LabelPrimitive.Root and
compose className using props.className; update any references to
className/children in the Label function to use props.xxx.

In `@web/default/src/features/system-settings/models/tiered-pricing-editor.tsx`:
- Around line 325-333: The DraftNumberInput component currently destructures
props in its function signature; change it to accept a single props parameter
and replace all destructured references (value, onValueChange,
selectZeroOnFocus, onBlur, onFocus, onMouseUp, etc.) with props.value,
props.onValueChange, props.selectZeroOnFocus (defaulting props.selectZeroOnFocus
= true where used), and so on; update the DraftNumberInput function signature
and all internal usages to follow the repository convention of accessing props
via props.xxx rather than parameter destructuring.
🪄 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

Run ID: 3823c448-9b5f-4c0c-995a-07333d84436f

📥 Commits

Reviewing files that changed from the base of the PR and between 3b59289 and 182dd3b.

📒 Files selected for processing (2)
  • web/default/src/components/ui/label.tsx
  • web/default/src/features/system-settings/models/tiered-pricing-editor.tsx

Comment on lines +7 to +17
const requiredMarkerPattern = /\s\*$/

function renderRequiredMarker(text: string, key?: React.Key) {
if (!requiredMarkerPattern.test(text)) {
return text
}

return (
<span key={key}>
{text.slice(0, -1)}
<span className='text-destructive'>*</span>

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

Required-marker detection misses Label* (no-space suffix).

The current regex only matches "<text> *". Labels like Email* won’t be styled.

Suggested fix
-const requiredMarkerPattern = /\s\*$/
+const requiredMarkerPattern = /\s*\*$/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/default/src/components/ui/label.tsx` around lines 7 - 17, The
required-marker regex only matches a trailing space before '*' so labels like
"Email*" are missed; update requiredMarkerPattern in this file to match an
optional space before the asterisk (e.g., use /\s*\*$/) and change
renderRequiredMarker to remove the marker robustly (for example, strip the
trailing space+asterisk via replace or trimEnd()+slice) before rendering the
label text and the <span className='text-destructive'>*</span>; refer to
requiredMarkerPattern and renderRequiredMarker to locate and apply the fix.

@Calcium-Ion
Calcium-Ion merged commit 5f86839 into QuantumNous:main Apr 30, 2026
2 checks passed
Jinxuans referenced this pull request in TokFlux-Org/TokFlux May 9, 2026
* fix: follow required marker styling convention

* fix: improve tiered pricing number input editing
xyfacai pushed a commit to xyfacai/new-api that referenced this pull request May 30, 2026
* fix: follow required marker styling convention

* fix: improve tiered pricing number input editing
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