Skip to content

feat: add duplicate key removal function when edit or add new channel - #1683

Closed
HynoR wants to merge 5 commits into
QuantumNous:alphafrom
HynoR:fix/dup
Closed

feat: add duplicate key removal function when edit or add new channel#1683
HynoR wants to merge 5 commits into
QuantumNous:alphafrom
HynoR:fix/dup

Conversation

@HynoR

@HynoR HynoR commented Aug 28, 2025

Copy link
Copy Markdown
Contributor

在批量添加 key 的情况下,可以在前端去重重复的密钥
image

Summary by CodeRabbit

  • New Features
    • Added a “密钥去重” button in batch mode to remove duplicate keys per line while preserving order and show immediate feedback on removals.
  • Refactor
    • Improved multi-key toggle behavior to more robustly update internal inputs when enabling/disabling.
  • Style
    • Improved wrapping/layout of the 密钥 input’s extra text.
  • UI
    • Show the 密钥去重 button only for applicable input types.

@coderabbitai

coderabbitai Bot commented Aug 28, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Added a deduplicateKeys helper and a “密钥去重” button in EditChannelModal to remove duplicate newline-separated keys (preserving order), update form/state, and display success/info messages. The button is shown only when inputs.type !== 41. ExtraText layout now uses flex-wrap.

Changes

Cohort / File(s) Summary
Edit Channel Modal
web/src/components/table/channels/modals/EditChannelModal.jsx
Added deduplicateKeys to read keys from form/local input, trim/split lines, remove duplicates while preserving order, update field/state, and show success/info messages; added a small outline “密钥去重” button next to the batch-mode checkbox (visible only when inputs.type !== 41); refactored multi-key toggle onChange to manage multi_key_mode and internal inputs more robustly; adjusted extraText container to use flex-wrap; no public API/signature changes.

Sequence Diagram(s)

sequenceDiagram
autonumber
actor User
participant Modal as EditChannelModal
participant Form as Form State
participant Msg as Message UI

rect rgba(230,245,255,0.5)
User->>Modal: Click "密钥去重" button
Modal->>Form: Read current key field (or local input)
Modal->>Modal: Split by newline, trim lines, deduplicate (preserve order)
alt Duplicates removed
  Modal->>Form: Update key field and internal state with unique lines
  Modal->>Msg: Show success message with before/after counts
else No duplicates
  Modal->>Msg: Show info message (no duplicates found)
end
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I thump my paws and scrub the pile,
Lines once twin now walk a mile. 🐇
Click the button, watch them fade—
One by one, duplicates laid.
A tidy hop, a cleaner key,
Small changes, neat as can be.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@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 (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)

875-921: Dedup logic works; tighten normalization and avoid redundant state writes

  • Normalize CRLF and only update when there’s an actual change.
  • Rely on handleInputChange once to prevent double form/state writes.
  • Optional: extract the routine to a helper for unit testing.
   // 密钥去重函数
   const deduplicateKeys = () => {
     const currentKey = formApiRef.current?.getValue('key') || inputs.key || '';
     
     if (!currentKey.trim()) {
       showInfo(t('请先输入密钥'));
       return;
     }
 
-    // 按行分割密钥
-    const keyLines = currentKey.split('\n');
+    // 按行分割密钥(兼容 CRLF)
+    const keyLines = currentKey.split(/\r?\n/);
     const beforeCount = keyLines.length;
     
     // 使用哈希表去重,保持原有顺序
     const keySet = new Set();
     const deduplicatedKeys = [];
     
     keyLines.forEach(line => {
       const trimmedLine = line.trim();
       if (trimmedLine && !keySet.has(trimmedLine)) {
         keySet.add(trimmedLine);
         deduplicatedKeys.push(trimmedLine);
       }
     });
     
     const afterCount = deduplicatedKeys.length;
     const deduplicatedKeyText = deduplicatedKeys.join('\n');
     
-    // 更新表单和状态
-    if (formApiRef.current) {
-      formApiRef.current.setValue('key', deduplicatedKeyText);
-    }
-    handleInputChange('key', deduplicatedKeyText);
+    // 仅在有变化时更新
+    if (beforeCount !== afterCount) {
+      handleInputChange('key', deduplicatedKeyText);
+    }
     
     // 显示去重结果
     const message = t('去重完成:去重前 {{before}} 个密钥,去重后 {{after}} 个密钥', {
       before: beforeCount,
       after: afterCount
     });
     
     if (beforeCount === afterCount) {
       showInfo(t('未发现重复密钥'));
     } else {
       showSuccess(message);
     }
   };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fbe7f35 and dba727b.

📒 Files selected for processing (1)
  • web/src/components/table/channels/modals/EditChannelModal.jsx (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
PR: QuantumNous/new-api#1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the database stores mapped keys (display names) in the models field after applying model mapping transformations. When loading a channel, data.models contains the mapped keys, not the original model names. The filtering logic if (data.models.includes(key)) in the initialization is correct.

Applied to files:

  • web/src/components/table/channels/modals/EditChannelModal.jsx
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
PR: QuantumNous/new-api#1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the applyModelMapping function transforms the models list by replacing original model names (mapping values) with display names (mapping keys). The database stores this transformed list containing mapped keys. On channel load, data.models contains these mapped display names, making the initialization filter if (data.models.includes(key)) correct.

Applied to files:

  • web/src/components/table/channels/modals/EditChannelModal.jsx
🧬 Code graph analysis (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (2)
web/src/components/table/channels/modals/EditTagModal.jsx (3)
  • formApiRef (74-74)
  • inputs (73-73)
  • handleInputChange (77-129)
web/src/helpers/utils.jsx (2)
  • showInfo (152-154)
  • showSuccess (148-150)
🔇 Additional comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)

1222-1222: LGTM: flex-wrap improves responsiveness of extra actions

Wrapping prevents overflow for long button groups on small viewports.

Comment thread web/src/components/table/channels/modals/EditChannelModal.jsx

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

♻️ Duplicate comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)

1015-1042: Gated 去重 for type 41 and fixed toggle closure — LGTM

The button visibility and the state toggle now avoid stale closures and no-op UI. Looks correct.

🧹 Nitpick comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)

875-921: Harden newline handling and remove redundant form update in dedup function

  • Use a CRLF-tolerant splitter.
  • handleInputChange already updates the Form; the explicit setValue is redundant.
-    const keyLines = currentKey.split('\n');
+    const keyLines = currentKey.split(/\r?\n/);
@@
-    // 更新表单和状态
-    if (formApiRef.current) {
-      formApiRef.current.setValue('key', deduplicatedKeyText);
-    }
-    handleInputChange('key', deduplicatedKeyText);
+    // 更新表单和状态
+    handleInputChange('key', deduplicatedKeyText);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between dba727b and c5e8f35.

📒 Files selected for processing (1)
  • web/src/components/table/channels/modals/EditChannelModal.jsx (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
PR: QuantumNous/new-api#1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the database stores mapped keys (display names) in the models field after applying model mapping transformations. When loading a channel, data.models contains the mapped keys, not the original model names. The filtering logic if (data.models.includes(key)) in the initialization is correct.

Applied to files:

  • web/src/components/table/channels/modals/EditChannelModal.jsx
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
PR: QuantumNous/new-api#1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the applyModelMapping function transforms the models list by replacing original model names (mapping values) with display names (mapping keys). The database stores this transformed list containing mapped keys. On channel load, data.models contains these mapped display names, making the initialization filter if (data.models.includes(key)) correct.

Applied to files:

  • web/src/components/table/channels/modals/EditChannelModal.jsx
🧬 Code graph analysis (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (3)
web/src/components/table/tokens/modals/EditTokenModal.jsx (1)
  • formApiRef (62-62)
web/src/components/table/channels/modals/EditTagModal.jsx (3)
  • formApiRef (74-74)
  • inputs (73-73)
  • handleInputChange (77-129)
web/src/helpers/utils.jsx (2)
  • showInfo (152-154)
  • showSuccess (148-150)
🔇 Additional comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)

1227-1227: Flex-wrap on extraText improves layout — LGTM

Prevents button/text overflow in narrow widths.

@seefs001

seefs001 commented Sep 7, 2025

Copy link
Copy Markdown
Collaborator

@HynoR 帮忙改一下conflicts🥺

@HynoR

HynoR commented Sep 19, 2025

Copy link
Copy Markdown
Contributor Author

@HynoR 帮忙改一下conflicts🥺

@seefs001 commit 太多了不好合并,我开新 pr 在新的 alpha 上修改了,麻烦审核一下:#1862

@HynoR HynoR closed this Sep 19, 2025
jiutubaba pushed a commit to jiutubaba/fx-api that referenced this pull request May 17, 2026
fix:修复上游账号为OpenAI API key时Claude Code调用缓存率低的问题
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