Просмотр исходного кода

🔍 fix: select search filter

Summary
• Introduced a unified `selectFilter` helper that matches both `option.value` and `option.label`, ensuring all `<Select>` components support intuitive search (fixes channel “type” dropdown not filtering).
• Replaced all usages of the old `modelSelectFilter` with `selectFilter` in:
  • `EditChannelModal.jsx`
  • `SettingsPanel.js`
  • `EditTokenModal.jsx`
  • `EditTagModal.jsx`
• Removed the deprecated `modelSelectFilter` export from `utils.js` (no backward-compat alias).
• Updated documentation comments accordingly.

Why
The old filter only inspected `option.value`, causing searches to fail when `label` carried the meaningful text (e.g., numeric IDs for channel types). The new helper searches both fields, covering all scenarios and unifying the API across the codebase.

Notes
No functional regressions expected; all components have been migrated.
t0ng7u 7 месяцев назад
Родитель
Сommit
c5d97597c4

+ 2 - 2
web/src/components/playground/SettingsPanel.js

@@ -33,7 +33,7 @@ import {
   Settings,
   Settings,
 } from 'lucide-react';
 } from 'lucide-react';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
-import { renderGroupOption, modelSelectFilter } from '../../helpers';
+import { renderGroupOption, selectFilter } from '../../helpers';
 import ParameterControl from './ParameterControl';
 import ParameterControl from './ParameterControl';
 import ImageUrlInput from './ImageUrlInput';
 import ImageUrlInput from './ImageUrlInput';
 import ConfigManager from './ConfigManager';
 import ConfigManager from './ConfigManager';
@@ -173,7 +173,7 @@ const SettingsPanel = ({
             name='model'
             name='model'
             required
             required
             selection
             selection
-            filter={modelSelectFilter}
+            filter={selectFilter}
             autoClearSearchValue={false}
             autoClearSearchValue={false}
             onChange={(value) => onInputChange('model', value)}
             onChange={(value) => onInputChange('model', value)}
             value={inputs.model}
             value={inputs.model}

+ 3 - 3
web/src/components/table/channels/modals/EditChannelModal.jsx

@@ -46,7 +46,7 @@ import {
   Col,
   Col,
   Highlight,
   Highlight,
 } from '@douyinfe/semi-ui';
 } from '@douyinfe/semi-ui';
-import { getChannelModels, copy, getChannelIcon, getModelCategories, modelSelectFilter } from '../../../../helpers';
+import { getChannelModels, copy, getChannelIcon, getModelCategories, selectFilter } from '../../../../helpers';
 import {
 import {
   IconSave,
   IconSave,
   IconClose,
   IconClose,
@@ -979,7 +979,7 @@ const EditChannelModal = (props) => {
                     rules={[{ required: true, message: t('请选择渠道类型') }]}
                     rules={[{ required: true, message: t('请选择渠道类型') }]}
                     optionList={channelOptionList}
                     optionList={channelOptionList}
                     style={{ width: '100%' }}
                     style={{ width: '100%' }}
-                    filter={modelSelectFilter}
+                    filter={selectFilter}
                     autoClearSearchValue={false}
                     autoClearSearchValue={false}
                     searchPosition='dropdown'
                     searchPosition='dropdown'
                     onSearch={(value) => setChannelSearchValue(value)}
                     onSearch={(value) => setChannelSearchValue(value)}
@@ -1380,7 +1380,7 @@ const EditChannelModal = (props) => {
                     placeholder={t('请选择该渠道所支持的模型')}
                     placeholder={t('请选择该渠道所支持的模型')}
                     rules={[{ required: true, message: t('请选择模型') }]}
                     rules={[{ required: true, message: t('请选择模型') }]}
                     multiple
                     multiple
-                    filter={modelSelectFilter}
+                    filter={selectFilter}
                     autoClearSearchValue={false}
                     autoClearSearchValue={false}
                     searchPosition='dropdown'
                     searchPosition='dropdown'
                     optionList={modelOptions}
                     optionList={modelOptions}

+ 2 - 2
web/src/components/table/channels/modals/EditTagModal.jsx

@@ -25,7 +25,7 @@ import {
   showSuccess,
   showSuccess,
   showWarning,
   showWarning,
   verifyJSON,
   verifyJSON,
-  modelSelectFilter,
+  selectFilter,
 } from '../../../../helpers';
 } from '../../../../helpers';
 import {
 import {
   SideSheet,
   SideSheet,
@@ -395,7 +395,7 @@ const EditTagModal = (props) => {
                     label={t('模型')}
                     label={t('模型')}
                     placeholder={t('请选择该渠道所支持的模型,留空则不更改')}
                     placeholder={t('请选择该渠道所支持的模型,留空则不更改')}
                     multiple
                     multiple
-                    filter={modelSelectFilter}
+                    filter={selectFilter}
                     autoClearSearchValue={false}
                     autoClearSearchValue={false}
                     searchPosition='dropdown'
                     searchPosition='dropdown'
                     optionList={modelOptions}
                     optionList={modelOptions}

+ 2 - 2
web/src/components/table/tokens/modals/EditTokenModal.jsx

@@ -26,7 +26,7 @@ import {
   renderGroupOption,
   renderGroupOption,
   renderQuotaWithPrompt,
   renderQuotaWithPrompt,
   getModelCategories,
   getModelCategories,
-  modelSelectFilter,
+  selectFilter,
 } from '../../../../helpers';
 } from '../../../../helpers';
 import { useIsMobile } from '../../../../hooks/common/useIsMobile.js';
 import { useIsMobile } from '../../../../hooks/common/useIsMobile.js';
 import {
 import {
@@ -514,7 +514,7 @@ const EditTokenModal = (props) => {
                       multiple
                       multiple
                       optionList={models}
                       optionList={models}
                       extraText={t('非必要,不建议启用模型限制')}
                       extraText={t('非必要,不建议启用模型限制')}
-                      filter={modelSelectFilter}
+                      filter={selectFilter}
                       autoClearSearchValue={false}
                       autoClearSearchValue={false}
                       searchPosition='dropdown'
                       searchPosition='dropdown'
                       showClear
                       showClear

+ 9 - 5
web/src/helpers/utils.js

@@ -560,12 +560,16 @@ export function setTableCompactMode(compact, tableKey = 'global') {
 
 
 // -------------------------------
 // -------------------------------
 // Select 组件统一过滤逻辑
 // Select 组件统一过滤逻辑
-// 解决 label 为 ReactNode(带图标等)时无法用内置 filter 搜索的问题。
-// 使用方式: <Select filter={modelSelectFilter} ... />
-export const modelSelectFilter = (input, option) => {
+// 使用方式: <Select filter={selectFilter} ... />
+// 统一的 Select 搜索过滤逻辑 -- 支持同时匹配 option.value 与 option.label
+export const selectFilter = (input, option) => {
   if (!input) return true;
   if (!input) return true;
-  const val = (option?.value || '').toString().toLowerCase();
-  return val.includes(input.trim().toLowerCase());
+
+  const keyword = input.trim().toLowerCase();
+  const valueText = (option?.value ?? '').toString().toLowerCase();
+  const labelText = (option?.label ?? '').toString().toLowerCase();
+
+  return valueText.includes(keyword) || labelText.includes(keyword);
 };
 };
 
 
 // -------------------------------
 // -------------------------------