mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-10-05 20:28:23 +00:00
better ui
This commit is contained in:
+6
-11
@@ -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<Model[]>([]);
|
||||
@@ -34,15 +35,7 @@ export default function ModelsPage() {
|
||||
|
||||
const groupedModels = useMemo(() => {
|
||||
if (!models) return {};
|
||||
|
||||
return models.reduce<Record<string, typeof models>>((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
|
||||
</span>
|
||||
)}
|
||||
{groupData?.group_url && (
|
||||
|
||||
@@ -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<Record<string, Model[]>>((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'
|
||||
>
|
||||
<MoreVertical className='h-4 w-4' />
|
||||
<MoreVertical className='text-muted-foreground hover:text-foreground h-4 w-4' />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align='end'>
|
||||
@@ -1181,7 +1178,7 @@ export function ModelSelector({
|
||||
{model.soft_deleted && (
|
||||
<span className='inline-flex items-center rounded-full border border-red-300 bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800'>
|
||||
<Trash2 className='mr-1 h-3 w-3' />
|
||||
Deleted
|
||||
Disabled
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -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<string, Model[]> {
|
||||
const grouped = models.reduce<Record<string, Model[]>>((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;
|
||||
}
|
||||
Reference in New Issue
Block a user