From 8c08be9e11049c69d09e879ad5b0b2b3d705ec2f Mon Sep 17 00:00:00 2001 From: 9qeklajc <9qeklajc> Date: Wed, 5 Nov 2025 00:12:23 +0100 Subject: [PATCH] better ui --- ui/app/model/page.tsx | 17 ++++++---------- ui/components/ModelSelector.tsx | 23 +++++++++------------ ui/lib/utils/modelSort.ts | 36 +++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 24 deletions(-) create mode 100644 ui/lib/utils/modelSort.ts diff --git a/ui/app/model/page.tsx b/ui/app/model/page.tsx index 6382b53f..edd6b20f 100644 --- a/ui/app/model/page.tsx +++ b/ui/app/model/page.tsx @@ -16,6 +16,7 @@ import { Alert, AlertDescription } from '@/components/ui/alert'; import { Badge } from '@/components/ui/badge'; import { useMemo, useState } from 'react'; import type { Model } from '@/lib/api/schemas/models'; +import { groupAndSortModelsByProvider } from '@/lib/utils/modelSort'; export default function ModelsPage() { const [filteredModels, setFilteredModels] = useState([]); @@ -34,15 +35,7 @@ export default function ModelsPage() { const groupedModels = useMemo(() => { if (!models) return {}; - - return models.reduce>((acc, model) => { - const provider = model.provider; - if (!acc[provider]) { - acc[provider] = []; - } - acc[provider].push(model); - return acc; - }, {}); + return groupAndSortModelsByProvider(models); }, [models]); const groupDataMap = useMemo(() => { @@ -52,7 +45,9 @@ export default function ModelsPage() { const providerInfo = useMemo(() => { return Object.entries(groupedModels).map(([provider, providerModels]) => { const groupData = groupDataMap.get(provider); - const activeModels = providerModels.filter((m) => !m.soft_deleted).length; + const activeModels = providerModels.filter( + (m) => m.isEnabled && !m.soft_deleted + ).length; const totalModels = providerModels.length; return { @@ -186,7 +181,7 @@ export default function ModelsPage() { (m) => m.soft_deleted ).length }{' '} - soft deleted + disabled )} {groupData?.group_url && ( diff --git a/ui/components/ModelSelector.tsx b/ui/components/ModelSelector.tsx index 7f7e24a9..914cd850 100644 --- a/ui/components/ModelSelector.tsx +++ b/ui/components/ModelSelector.tsx @@ -59,6 +59,10 @@ import { } from 'lucide-react'; import { toast } from 'sonner'; import { cn } from '@/lib/utils'; +import { + sortModels, + groupAndSortModelsByProvider, +} from '@/lib/utils/modelSort'; interface ModelSelectorProps { filterProvider?: string; @@ -424,20 +428,13 @@ export function ModelSelector({ : providerFilteredModels; if (filterProvider) { - // If filtering by provider, return single group - return { [filterProvider]: modelsToGroup }; + const sortedModels = sortModels(modelsToGroup); + return { [filterProvider]: sortedModels }; } if (!modelsToGroup) return {}; - return modelsToGroup.reduce>((acc, model) => { - const provider = model.provider; - if (!acc[provider]) { - acc[provider] = []; - } - acc[provider].push(model); - return acc; - }, {}); + return groupAndSortModelsByProvider(modelsToGroup); }, [ providerFilteredModels, filteredModels, @@ -1077,9 +1074,9 @@ export function ModelSelector({ variant='ghost' size='sm' onClick={(e) => e.stopPropagation()} - className='h-8 w-8 p-0' + className='hover:bg-muted/50 dark:hover:bg-muted/80 h-8 w-8 p-0' > - + @@ -1181,7 +1178,7 @@ export function ModelSelector({ {model.soft_deleted && ( - Deleted + Disabled )} diff --git a/ui/lib/utils/modelSort.ts b/ui/lib/utils/modelSort.ts new file mode 100644 index 00000000..932cccc1 --- /dev/null +++ b/ui/lib/utils/modelSort.ts @@ -0,0 +1,36 @@ +import { type Model } from '@/lib/api/schemas/models'; + +export function sortModelsByStatus(a: Model, b: Model): number { + if (a.isEnabled && !b.isEnabled) return -1; + if (!a.isEnabled && b.isEnabled) return 1; + + if (a.isEnabled === b.isEnabled) { + if (!a.soft_deleted && b.soft_deleted) return -1; + if (a.soft_deleted && !b.soft_deleted) return 1; + } + + return 0; +} + +export function sortModels(models: Model[]): Model[] { + return [...models].sort(sortModelsByStatus); +} + +export function groupAndSortModelsByProvider( + models: Model[] +): Record { + const grouped = models.reduce>((acc, model) => { + const provider = model.provider; + if (!acc[provider]) { + acc[provider] = []; + } + acc[provider].push(model); + return acc; + }, {}); + + Object.keys(grouped).forEach((provider) => { + grouped[provider].sort(sortModelsByStatus); + }); + + return grouped; +}