feat: Improve model group management UI in EditModelsPopup

- Add dynamic group management button that changes based on group's current state
- Simplify group add/remove logic with a single button
- Enhance visual feedback for group-level model management
This commit is contained in:
kangfenmao 2025-03-06 23:27:10 +08:00
parent 3ba16118b4
commit 2d8d478e2c
2 changed files with 70 additions and 57 deletions

View File

@ -169,62 +169,67 @@ const PopupContainer: React.FC<Props> = ({ provider: _provider, resolve }) => {
/> />
</SearchContainer> </SearchContainer>
<ListContainer> <ListContainer>
{Object.keys(modelGroups).map((group) => ( {Object.keys(modelGroups).map((group) => {
<div key={group}> const isAllInProvider = modelGroups[group].every((model) => isModelInProvider(provider, model.id))
<ListHeader key={group}> return (
{group} <div key={group}>
<div> <ListHeader key={group}>
<Button {group}
type="text" <div>
icon={<PlusOutlined />} <Button
title={t(`settings.models.manage.add_whole_group`)} type="text"
onClick={() => { icon={isAllInProvider ? <MinusOutlined /> : <PlusOutlined />}
modelGroups[group].filter((model) => !isModelInProvider(provider, model.id)).forEach(onAddModel) title={
}} isAllInProvider
/> ? t(`settings.models.manage.remove_whole_group`)
<Button : t(`settings.models.manage.add_whole_group`)
type="text" }
icon={<MinusOutlined />} onClick={() => {
title={t(`settings.models.manage.remove_whole_group`)} if (isAllInProvider) {
onClick={() => { modelGroups[group]
modelGroups[group].filter((model) => isModelInProvider(provider, model.id)).forEach(onRemoveModel) .filter((model) => isModelInProvider(provider, model.id))
}} .forEach(onRemoveModel)
/> } else {
</div> modelGroups[group].filter((model) => !isModelInProvider(provider, model.id)).forEach(onAddModel)
</ListHeader> }
{modelGroups[group].map((model) => { }}
return ( />
<ListItem key={model.id}> </div>
<ListItemHeader> </ListHeader>
<Avatar src={getModelLogo(model.id)} size={24}> {modelGroups[group].map((model) => {
{model?.name?.[0]?.toUpperCase()} return (
</Avatar> <ListItem key={model.id}>
<ListItemName> <ListItemHeader>
<Tooltip title={model.id} placement="top"> <Avatar src={getModelLogo(model.id)} size={24}>
<span style={{ cursor: 'help' }}>{model.name}</span> {model?.name?.[0]?.toUpperCase()}
</Tooltip> </Avatar>
<ModelTags model={model} /> <ListItemName>
{!isEmpty(model.description) && ( <Tooltip title={model.id} placement="top">
<Popover <span style={{ cursor: 'help' }}>{model.name}</span>
trigger="click" </Tooltip>
title={model.name} <ModelTags model={model} />
content={model.description} {!isEmpty(model.description) && (
overlayStyle={{ maxWidth: 600 }}> <Popover
<Question /> trigger="click"
</Popover> title={model.name}
)} content={model.description}
</ListItemName> overlayStyle={{ maxWidth: 600 }}>
</ListItemHeader> <Question />
{isModelInProvider(provider, model.id) ? ( </Popover>
<Button type="default" onClick={() => onRemoveModel(model)} icon={<MinusOutlined />} /> )}
) : ( </ListItemName>
<Button type="primary" onClick={() => onAddModel(model)} icon={<PlusOutlined />} /> </ListItemHeader>
)} {isModelInProvider(provider, model.id) ? (
</ListItem> <Button type="default" onClick={() => onRemoveModel(model)} icon={<MinusOutlined />} />
) ) : (
})} <Button type="primary" onClick={() => onAddModel(model)} icon={<PlusOutlined />} />
</div> )}
))} </ListItem>
)
})}
</div>
)
})}
{isEmpty(list) && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={t('settings.models.empty')} />} {isEmpty(list) && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={t('settings.models.empty')} />}
</ListContainer> </ListContainer>
</Modal> </Modal>

View File

@ -317,7 +317,7 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
title={group} title={group}
extra={ extra={
<Tooltip title={t('settings.models.manage.remove_whole_group')}> <Tooltip title={t('settings.models.manage.remove_whole_group')}>
<RemoveIcon <HoveredRemoveIcon
onClick={() => onClick={() =>
modelGroups[group] modelGroups[group]
.filter((model) => provider.models.some((m) => m.id === model.id)) .filter((model) => provider.models.some((m) => m.id === model.id))
@ -409,6 +409,14 @@ const RemoveIcon = styled(MinusCircleOutlined)`
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
` `
const HoveredRemoveIcon = styled(RemoveIcon)`
opacity: 0;
margin-top: 2px;
&:hover {
opacity: 1;
}
`
const SettingIcon = styled(SettingOutlined)` const SettingIcon = styled(SettingOutlined)`
margin-left: 2px; margin-left: 2px;
color: var(--color-text); color: var(--color-text);