feat(ui): migrate model_group_alias_settings to shadcn

- @tremor Card/Title/Text/Table* + @heroicons icons \u2192 shadcn Card/
  Table + lucide ChevronDown/ChevronRight/PlusCircle/Pencil/Trash2.
- Replace 'bg-gray-300/text-gray-500/bg-green-600/text-blue-600/...' raw
  classes with semantic tokens. Add Alias button uses bg-emerald-600
  (categorical 'create' color) \u2014 added to .eslintrc.json overrides.
- Native input/button preserved for the inline editing UX.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
Cursor Agent 2026-04-23 09:14:20 +00:00
parent 31c3be292a
commit 2e4b3929d1
No known key found for this signature in database
2 changed files with 92 additions and 50 deletions

View file

@ -32,7 +32,8 @@
"src/components/GuardrailSettingsView.tsx",
"src/components/DebugWarningBanner.tsx",
"src/components/SCIM.tsx",
"src/components/logging_settings_view.tsx"
"src/components/logging_settings_view.tsx",
"src/components/model_group_alias_settings.tsx"
],
"rules": {
"litellm-ui/no-banned-ui-imports": "off",

View file

@ -1,7 +1,21 @@
import React, { useState, useEffect } from "react";
import { PlusCircleIcon, PencilIcon, TrashIcon, ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/outline";
import {
ChevronDown,
ChevronRight,
PlusCircle,
Pencil,
Trash2,
} from "lucide-react";
import { setCallbacksCall } from "./networking";
import { Card, Title, Text, Table, TableHead, TableHeaderCell, TableBody, TableRow, TableCell } from "@tremor/react";
import { Card } from "@/components/ui/card";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import NotificationsManager from "./molecules/notifications_manager";
type ModelGroupAliasValue = string | { model: string; hidden?: boolean };
@ -149,20 +163,26 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
);
return (
<Card className="mb-6">
<div className="flex items-center justify-between cursor-pointer" onClick={() => setIsExpanded(!isExpanded)}>
<Card className="mb-6 p-6">
<div
className="flex items-center justify-between cursor-pointer"
onClick={() => setIsExpanded(!isExpanded)}
>
<div className="flex flex-col">
<Title className="mb-0">Model Group Alias Settings</Title>
<p className="text-sm text-gray-500">
Create aliases for your model groups to simplify API calls. For example, you can create an alias
&apos;gpt-4o&apos; that points to &apos;gpt-4o-mini-openai&apos; model group.
<h3 className="text-lg font-semibold mb-0">
Model Group Alias Settings
</h3>
<p className="text-sm text-muted-foreground">
Create aliases for your model groups to simplify API calls. For
example, you can create an alias &apos;gpt-4o&apos; that points
to &apos;gpt-4o-mini-openai&apos; model group.
</p>
</div>
<div className="flex items-center">
{isExpanded ? (
<ChevronDownIcon className="w-5 h-5 text-gray-500" />
<ChevronDown className="w-5 h-5 text-muted-foreground" />
) : (
<ChevronRightIcon className="w-5 h-5 text-gray-500" />
<ChevronRight className="w-5 h-5 text-muted-foreground" />
)}
</div>
</div>
@ -170,25 +190,28 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
{isExpanded && (
<div className="mt-4">
<div className="mb-6">
<Text className="text-sm font-medium text-gray-700 mb-2">Add New Alias</Text>
<span className="block text-sm font-medium text-foreground mb-2">
Add New Alias
</span>
<div className="grid grid-cols-3 gap-4">
<div>
<label className="block text-xs text-gray-500 mb-1">Alias Name</label>
<label className="block text-xs text-muted-foreground mb-1">
Alias Name
</label>
<input
type="text"
value={newAlias.aliasName}
onChange={(e) =>
setNewAlias({
...newAlias,
aliasName: e.target.value,
})
setNewAlias({ ...newAlias, aliasName: e.target.value })
}
placeholder="e.g., gpt-4o"
className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm"
className="w-full px-3 py-2 border border-input bg-background rounded-md text-sm"
/>
</div>
<div>
<label className="block text-xs text-gray-500 mb-1">Target Model Group</label>
<label className="block text-xs text-muted-foreground mb-1">
Target Model Group
</label>
<input
type="text"
value={newAlias.targetModelGroup}
@ -199,33 +222,41 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
})
}
placeholder="e.g., gpt-4o-mini-openai"
className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm"
className="w-full px-3 py-2 border border-input bg-background rounded-md text-sm"
/>
</div>
<div className="flex items-end">
<button
onClick={handleAddAlias}
disabled={!newAlias.aliasName || !newAlias.targetModelGroup}
className={`flex items-center px-4 py-2 rounded-md text-sm ${!newAlias.aliasName || !newAlias.targetModelGroup ? "bg-gray-300 text-gray-500 cursor-not-allowed" : "bg-green-600 text-white hover:bg-green-700"}`}
disabled={
!newAlias.aliasName || !newAlias.targetModelGroup
}
className={`flex items-center px-4 py-2 rounded-md text-sm ${
!newAlias.aliasName || !newAlias.targetModelGroup
? "bg-muted text-muted-foreground cursor-not-allowed"
: "bg-emerald-600 text-white hover:bg-emerald-700"
}`}
>
<PlusCircleIcon className="w-4 h-4 mr-1" />
<PlusCircle className="w-4 h-4 mr-1" />
Add Alias
</button>
</div>
</div>
</div>
<Text className="text-sm font-medium text-gray-700 mb-2">Manage Existing Aliases</Text>
<span className="block text-sm font-medium text-foreground mb-2">
Manage Existing Aliases
</span>
<div className="rounded-lg custom-border relative mb-6">
<div className="overflow-x-auto">
<Table className="[&_td]:py-0.5 [&_th]:py-1">
<TableHead>
<TableHeader>
<TableRow>
<TableHeaderCell className="py-1 h-8">Alias Name</TableHeaderCell>
<TableHeaderCell className="py-1 h-8">Target Model Group</TableHeaderCell>
<TableHeaderCell className="py-1 h-8">Actions</TableHeaderCell>
<TableHead className="py-1 h-8">Alias Name</TableHead>
<TableHead className="py-1 h-8">Target Model Group</TableHead>
<TableHead className="py-1 h-8">Actions</TableHead>
</TableRow>
</TableHead>
</TableHeader>
<TableBody>
{aliases.map((alias) => (
<TableRow key={alias.id} className="h-8">
@ -241,7 +272,7 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
aliasName: e.target.value,
})
}
className="w-full px-2 py-1 border border-gray-300 rounded-md text-sm"
className="w-full px-2 py-1 border border-input bg-background rounded-md text-sm"
/>
</TableCell>
<TableCell className="py-0.5">
@ -254,20 +285,20 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
targetModelGroup: e.target.value,
})
}
className="w-full px-2 py-1 border border-gray-300 rounded-md text-sm"
className="w-full px-2 py-1 border border-input bg-background rounded-md text-sm"
/>
</TableCell>
<TableCell className="py-0.5 whitespace-nowrap">
<div className="flex space-x-2">
<button
onClick={handleUpdateAlias}
className="text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded hover:bg-blue-100"
className="text-xs bg-primary/10 text-primary px-2 py-1 rounded hover:bg-primary/20"
>
Save
</button>
<button
onClick={handleCancelEdit}
className="text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded hover:bg-gray-100"
className="text-xs bg-muted text-muted-foreground px-2 py-1 rounded hover:bg-muted/80"
>
Cancel
</button>
@ -276,21 +307,27 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
</>
) : (
<>
<TableCell className="py-0.5 text-sm text-gray-900">{alias.aliasName}</TableCell>
<TableCell className="py-0.5 text-sm text-gray-500">{alias.targetModelGroup}</TableCell>
<TableCell className="py-0.5 text-sm text-foreground">
{alias.aliasName}
</TableCell>
<TableCell className="py-0.5 text-sm text-muted-foreground">
{alias.targetModelGroup}
</TableCell>
<TableCell className="py-0.5 whitespace-nowrap">
<div className="flex space-x-2">
<button
onClick={() => handleEditAlias(alias)}
className="text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded hover:bg-blue-100"
className="text-xs bg-primary/10 text-primary px-2 py-1 rounded hover:bg-primary/20"
aria-label="Edit alias"
>
<PencilIcon className="w-3 h-3" />
<Pencil className="w-3 h-3" />
</button>
<button
onClick={() => deleteAlias(alias.id)}
className="text-xs bg-red-50 text-red-600 px-2 py-1 rounded hover:bg-red-100"
className="text-xs bg-destructive/10 text-destructive px-2 py-1 rounded hover:bg-destructive/20"
aria-label="Delete alias"
>
<TrashIcon className="w-3 h-3" />
<Trash2 className="w-3 h-3" />
</button>
</div>
</TableCell>
@ -300,7 +337,10 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
))}
{aliases.length === 0 && (
<TableRow>
<TableCell colSpan={3} className="py-0.5 text-sm text-gray-500 text-center">
<TableCell
colSpan={3}
className="py-0.5 text-sm text-muted-foreground text-center"
>
No aliases added yet. Add a new alias above.
</TableCell>
</TableRow>
@ -310,19 +350,19 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
</div>
</div>
{/* Configuration Example */}
<Card>
<Title className="mb-4">Configuration Example</Title>
<Text className="text-gray-600 mb-4">
Here&apos;s how your current aliases would look in the config.yaml:
</Text>
<div className="bg-gray-100 rounded-lg p-4 font-mono text-sm">
<div className="text-gray-700">
<Card className="p-6">
<h4 className="text-base font-semibold mb-4">Configuration Example</h4>
<p className="text-muted-foreground mb-4 text-sm">
Here&apos;s how your current aliases would look in the
config.yaml:
</p>
<div className="bg-muted rounded-lg p-4 font-mono text-sm">
<div className="text-foreground">
router_settings:
<br />
&nbsp;&nbsp;model_group_alias:
{Object.keys(aliasObject).length === 0 ? (
<span className="text-gray-500">
<span className="text-muted-foreground">
<br />
&nbsp;&nbsp;&nbsp;&nbsp;# No aliases configured yet
</span>
@ -330,7 +370,8 @@ const ModelGroupAliasSettings: React.FC<ModelGroupAliasSettingsProps> = ({
Object.entries(aliasObject).map(([key, value]) => (
<span key={key}>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&quot;{key}&quot;: &quot;{value}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&quot;{key}&quot;: &quot;{value}
&quot;
</span>
))
)}