🎨 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:
@@ -28,7 +28,7 @@ import {
|
|||||||
Col,
|
Col,
|
||||||
Upload,
|
Upload,
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import { getChannelModels, copy, getChannelIcon } from '../../helpers';
|
import { getChannelModels, copy, getChannelIcon, getModelCategories } from '../../helpers';
|
||||||
import {
|
import {
|
||||||
IconSave,
|
IconSave,
|
||||||
IconClose,
|
IconClose,
|
||||||
@@ -349,14 +349,14 @@ const EditChannel = (props) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const modelMap = new Map();
|
const modelMap = new Map();
|
||||||
|
|
||||||
originModelOptions.forEach(option => {
|
originModelOptions.forEach((option) => {
|
||||||
const v = (option.value || '').trim();
|
const v = (option.value || '').trim();
|
||||||
if (!modelMap.has(v)) {
|
if (!modelMap.has(v)) {
|
||||||
modelMap.set(v, option);
|
modelMap.set(v, option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
inputs.models.forEach(model => {
|
inputs.models.forEach((model) => {
|
||||||
const v = (model || '').trim();
|
const v = (model || '').trim();
|
||||||
if (!modelMap.has(v)) {
|
if (!modelMap.has(v)) {
|
||||||
modelMap.set(v, {
|
modelMap.set(v, {
|
||||||
@@ -367,8 +367,29 @@ const EditChannel = (props) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setModelOptions(Array.from(modelMap.values()));
|
const categories = getModelCategories(t);
|
||||||
}, [originModelOptions, inputs.models]);
|
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(() => {
|
useEffect(() => {
|
||||||
fetchModels().then();
|
fetchModels().then();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
timestamp2string,
|
timestamp2string,
|
||||||
renderGroupOption,
|
renderGroupOption,
|
||||||
renderQuotaWithPrompt,
|
renderQuotaWithPrompt,
|
||||||
|
getModelCategories,
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -78,10 +79,25 @@ const EditToken = (props) => {
|
|||||||
let res = await API.get(`/api/user/models`);
|
let res = await API.get(`/api/user/models`);
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
let localModelOptions = data.map((model) => ({
|
const categories = getModelCategories(t);
|
||||||
label: model,
|
let localModelOptions = data.map((model) => {
|
||||||
value: 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);
|
setModels(localModelOptions);
|
||||||
} else {
|
} else {
|
||||||
showError(t(message));
|
showError(t(message));
|
||||||
|
|||||||
Reference in New Issue
Block a user