🎨 feat(ui): Enhance model dropdowns with icons in Token & Channel editors

Summary
• Added visual model icons to dropdown options in both Token (`EditToken.js`) and Channel (`EditChannel.js`) editors.

Details
1. Token Editor
   - Imported `getModelCategories` from helpers.
   - Re-built Model Limits option list to prepend the matching icon to each model label.

2. Channel Editor
   - Imported `getModelCategories`.
   - Extended model‐option construction to include icons, unifying behaviour with Token editor.
   - Maintained existing logic for merging origin options and user-selected models.

Benefits
• Provides immediate visual identification of model vendors.
• Aligns UX with existing icon usage across the application, improving consistency and clarity.
• No functional changes to data handling; purely UI/UX enhancement.

Co-authored-by: [Your Name]
This commit is contained in:
t0ng7u
2025-07-13 19:32:01 +08:00
parent a203e98689
commit e3ef3ace29
2 changed files with 46 additions and 9 deletions

View File

@@ -28,7 +28,7 @@ import {
Col,
Upload,
} from '@douyinfe/semi-ui';
import { getChannelModels, copy, getChannelIcon } from '../../helpers';
import { getChannelModels, copy, getChannelIcon, getModelCategories } from '../../helpers';
import {
IconSave,
IconClose,
@@ -349,14 +349,14 @@ const EditChannel = (props) => {
useEffect(() => {
const modelMap = new Map();
originModelOptions.forEach(option => {
originModelOptions.forEach((option) => {
const v = (option.value || '').trim();
if (!modelMap.has(v)) {
modelMap.set(v, option);
}
});
inputs.models.forEach(model => {
inputs.models.forEach((model) => {
const v = (model || '').trim();
if (!modelMap.has(v)) {
modelMap.set(v, {
@@ -367,8 +367,29 @@ const EditChannel = (props) => {
}
});
setModelOptions(Array.from(modelMap.values()));
}, [originModelOptions, inputs.models]);
const categories = getModelCategories(t);
const optionsWithIcon = Array.from(modelMap.values()).map((opt) => {
const modelName = opt.value;
let icon = null;
for (const [key, category] of Object.entries(categories)) {
if (key !== 'all' && category.filter({ model_name: modelName })) {
icon = category.icon;
break;
}
}
return {
...opt,
label: (
<span className="flex items-center gap-1">
{icon}
{modelName}
</span>
),
};
});
setModelOptions(optionsWithIcon);
}, [originModelOptions, inputs.models, t]);
useEffect(() => {
fetchModels().then();

View File

@@ -7,6 +7,7 @@ import {
timestamp2string,
renderGroupOption,
renderQuotaWithPrompt,
getModelCategories,
} from '../../helpers';
import {
Button,
@@ -78,10 +79,25 @@ const EditToken = (props) => {
let res = await API.get(`/api/user/models`);
const { success, message, data } = res.data;
if (success) {
let localModelOptions = data.map((model) => ({
label: model,
value: model,
}));
const categories = getModelCategories(t);
let localModelOptions = data.map((model) => {
let icon = null;
for (const [key, category] of Object.entries(categories)) {
if (key !== 'all' && category.filter({ model_name: model })) {
icon = category.icon;
break;
}
}
return {
label: (
<span className="flex items-center gap-1">
{icon}
{model}
</span>
),
value: model,
};
});
setModels(localModelOptions);
} else {
showError(t(message));