Skip to content

Commit a36d0f9

Browse files
authored
Merge pull request #3002 from RedwindA/feat/zeroMatchHint
feat(web): add custom-model create hint and i18n translations
2 parents 176f764 + 144fe67 commit a36d0f9

File tree

9 files changed

+76
-8
lines changed

9 files changed

+76
-8
lines changed

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ const EditChannelModal = (props) => {
191191
const [fullModels, setFullModels] = useState([]);
192192
const [modelGroups, setModelGroups] = useState([]);
193193
const [customModel, setCustomModel] = useState('');
194+
const [modelSearchValue, setModelSearchValue] = useState('');
194195
const [modalImageUrl, setModalImageUrl] = useState('');
195196
const [isModalOpenurl, setIsModalOpenurl] = useState(false);
196197
const [modelModalVisible, setModelModalVisible] = useState(false);
@@ -231,6 +232,25 @@ const EditChannelModal = (props) => {
231232
return [];
232233
}
233234
}, [inputs.model_mapping]);
235+
const modelSearchMatchedCount = useMemo(() => {
236+
const keyword = modelSearchValue.trim();
237+
if (!keyword) {
238+
return modelOptions.length;
239+
}
240+
return modelOptions.reduce(
241+
(count, option) => count + (selectFilter(keyword, option) ? 1 : 0),
242+
0,
243+
);
244+
}, [modelOptions, modelSearchValue]);
245+
const modelSearchHintText = useMemo(() => {
246+
const keyword = modelSearchValue.trim();
247+
if (!keyword || modelSearchMatchedCount !== 0) {
248+
return '';
249+
}
250+
return t('未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加', {
251+
name: keyword,
252+
});
253+
}, [modelSearchMatchedCount, modelSearchValue, t]);
234254
const [isIonetChannel, setIsIonetChannel] = useState(false);
235255
const [ionetMetadata, setIonetMetadata] = useState(null);
236256
const [codexOAuthModalVisible, setCodexOAuthModalVisible] = useState(false);
@@ -1019,6 +1039,7 @@ const EditChannelModal = (props) => {
10191039
}, [inputs]);
10201040

10211041
useEffect(() => {
1042+
setModelSearchValue('');
10221043
if (props.visible) {
10231044
if (isEdit) {
10241045
loadChannel();
@@ -1073,6 +1094,7 @@ const EditChannelModal = (props) => {
10731094
// 重置豆包隐藏入口状态
10741095
setDoubaoApiEditUnlocked(false);
10751096
doubaoApiClickCountRef.current = 0;
1097+
setModelSearchValue('');
10761098
// 清空表单中的key_mode字段
10771099
if (formApiRef.current) {
10781100
formApiRef.current.setValue('key_mode', undefined);
@@ -2815,9 +2837,18 @@ const EditChannelModal = (props) => {
28152837
rules={[{ required: true, message: t('请选择模型') }]}
28162838
multiple
28172839
filter={selectFilter}
2840+
allowCreate
28182841
autoClearSearchValue={false}
28192842
searchPosition='dropdown'
28202843
optionList={modelOptions}
2844+
onSearch={(value) => setModelSearchValue(value)}
2845+
innerBottomSlot={
2846+
modelSearchHintText ? (
2847+
<Text className='px-3 py-2 block text-xs !text-semi-color-text-2'>
2848+
{modelSearchHintText}
2849+
</Text>
2850+
) : null
2851+
}
28212852
style={{ width: '100%' }}
28222853
onChange={(value) => handleInputChange('models', value)}
28232854
renderSelectedItem={(optionNode) => {

web/src/components/table/channels/modals/EditTagModal.jsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
For commercial licensing, please contact support@quantumnous.com
1818
*/
1919

20-
import React, { useState, useEffect, useRef } from 'react';
20+
import React, { useState, useEffect, useRef, useMemo } from 'react';
2121
import {
2222
API,
2323
showError,
@@ -64,6 +64,7 @@ const EditTagModal = (props) => {
6464
const [modelOptions, setModelOptions] = useState([]);
6565
const [groupOptions, setGroupOptions] = useState([]);
6666
const [customModel, setCustomModel] = useState('');
67+
const [modelSearchValue, setModelSearchValue] = useState('');
6768
const originInputs = {
6869
tag: '',
6970
new_tag: null,
@@ -74,6 +75,25 @@ const EditTagModal = (props) => {
7475
header_override: null,
7576
};
7677
const [inputs, setInputs] = useState(originInputs);
78+
const modelSearchMatchedCount = useMemo(() => {
79+
const keyword = modelSearchValue.trim();
80+
if (!keyword) {
81+
return modelOptions.length;
82+
}
83+
return modelOptions.reduce(
84+
(count, option) => count + (selectFilter(keyword, option) ? 1 : 0),
85+
0,
86+
);
87+
}, [modelOptions, modelSearchValue]);
88+
const modelSearchHintText = useMemo(() => {
89+
const keyword = modelSearchValue.trim();
90+
if (!keyword || modelSearchMatchedCount !== 0) {
91+
return '';
92+
}
93+
return t('未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加', {
94+
name: keyword,
95+
});
96+
}, [modelSearchMatchedCount, modelSearchValue, t]);
7797
const formApiRef = useRef(null);
7898
const getInitValues = () => ({ ...originInputs });
7999

@@ -292,6 +312,7 @@ const EditTagModal = (props) => {
292312
fetchModels().then();
293313
fetchGroups().then();
294314
fetchTagModels().then();
315+
setModelSearchValue('');
295316
if (formApiRef.current) {
296317
formApiRef.current.setValues({
297318
...getInitValues(),
@@ -461,9 +482,18 @@ const EditTagModal = (props) => {
461482
placeholder={t('请选择该渠道所支持的模型,留空则不更改')}
462483
multiple
463484
filter={selectFilter}
485+
allowCreate
464486
autoClearSearchValue={false}
465487
searchPosition='dropdown'
466488
optionList={modelOptions}
489+
onSearch={(value) => setModelSearchValue(value)}
490+
innerBottomSlot={
491+
modelSearchHintText ? (
492+
<Text className='px-3 py-2 block text-xs !text-semi-color-text-2'>
493+
{modelSearchHintText}
494+
</Text>
495+
) : null
496+
}
467497
style={{ width: '100%' }}
468498
onChange={(value) => handleInputChange('models', value)}
469499
/>

web/src/i18n/locales/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2835,6 +2835,7 @@
28352835
"缓存写": "Cache Write",
28362836
"写": "Write",
28372837
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Per Anthropic conventions, /v1/messages input tokens count only non-cached input and exclude cache read/write tokens.",
2838-
"设计版本": "b80c3466cb6feafeb3990c7820e10e50"
2838+
"设计版本": "b80c3466cb6feafeb3990c7820e10e50",
2839+
"未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加": "No matching models. Press Enter to add \"{{name}}\" as a custom model name."
28392840
}
28402841
}

web/src/i18n/locales/fr.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2737,6 +2737,7 @@
27372737
"缓存写": "Écriture cache",
27382738
"写": "Écriture",
27392739
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Selon la convention Anthropic, les tokens d'entrée de /v1/messages ne comptent que les entrées non mises en cache et excluent les tokens de lecture/écriture du cache.",
2740-
"设计版本": "b80c3466cb6feafeb3990c7820e10e50"
2740+
"设计版本": "b80c3466cb6feafeb3990c7820e10e50",
2741+
"未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加": "Aucun modèle correspondant. Appuyez sur Entrée pour ajouter «{{name}}» comme nom de modèle personnalisé."
27412742
}
27422743
}

web/src/i18n/locales/ja.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2720,6 +2720,7 @@
27202720
"缓存写": "キャッシュ書込",
27212721
"写": "書込",
27222722
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Anthropic の仕様により、/v1/messages の入力 tokens は非キャッシュ入力のみを集計し、キャッシュ読み取り/書き込み tokens は含みません。",
2723-
"设计版本": "b80c3466cb6feafeb3990c7820e10e50"
2723+
"设计版本": "b80c3466cb6feafeb3990c7820e10e50",
2724+
"未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加": "一致するモデルが見つかりません。Enterキーで「{{name}}」をカスタムモデル名として追加できます。"
27242725
}
27252726
}

web/src/i18n/locales/ru.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2750,6 +2750,7 @@
27502750
"缓存写": "Запись в кэш",
27512751
"写": "Запись",
27522752
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Согласно соглашению Anthropic, входные токены /v1/messages учитывают только некэшированный ввод и не включают токены чтения/записи кэша.",
2753-
"设计版本": "b80c3466cb6feafeb3990c7820e10e50"
2753+
"设计版本": "b80c3466cb6feafeb3990c7820e10e50",
2754+
"未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加": "Совпадающих моделей не найдено. Нажмите Enter, чтобы добавить «{{name}}» как пользовательское имя модели."
27542755
}
27552756
}

web/src/i18n/locales/vi.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3296,6 +3296,7 @@
32963296
"缓存写": "Ghi bộ nhớ đệm",
32973297
"写": "Ghi",
32983298
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Theo quy ước của Anthropic, input tokens của /v1/messages chỉ tính phần đầu vào không dùng cache và không bao gồm tokens đọc/ghi cache.",
3299-
"设计版本": "b80c3466cb6feafeb3990c7820e10e50"
3299+
"设计版本": "b80c3466cb6feafeb3990c7820e10e50",
3300+
"未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加": "Không tìm thấy mô hình khớp. Nhấn Enter để thêm \"{{name}}\" làm tên mô hình tùy chỉnh."
33003301
}
33013302
}

web/src/i18n/locales/zh-CN.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2812,6 +2812,7 @@
28122812
"缓存读": "缓存读",
28132813
"缓存写": "缓存写",
28142814
"写": "",
2815-
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。"
2815+
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。",
2816+
"未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加": "未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加"
28162817
}
28172818
}

web/src/i18n/locales/zh-TW.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2805,6 +2805,7 @@
28052805
"填写服务器地址后自动生成:": "填寫伺服器位址後自動生成:",
28062806
"自动生成:": "自動生成:",
28072807
"请先填写服务器地址,以自动生成完整的端点 URL": "請先填寫伺服器位址,以自動生成完整的端點 URL",
2808-
"端点 URL 必须是完整地址(以 http:// 或 https:// 开头)": "端點 URL 必須是完整位址(以 http:// 或 https:// 開頭)"
2808+
"端点 URL 必须是完整地址(以 http:// 或 https:// 开头)": "端點 URL 必須是完整位址(以 http:// 或 https:// 開頭)",
2809+
"未匹配到模型,按回车键可将「{{name}}」作为自定义模型名添加": "未匹配到模型,按下 Enter 鍵可將「{{name}}」作為自訂模型名稱新增"
28092810
}
28102811
}

0 commit comments

Comments
 (0)