refactor(web): simplify models page header

This commit is contained in:
wangbo 2026-05-11 11:02:08 +08:00
parent 9243db2787
commit ec87816c95
2 changed files with 27 additions and 54 deletions

View File

@ -1,5 +1,5 @@
import { useMemo, useState } from 'react';
import { Boxes, Search, Sparkles } from 'lucide-react';
import { Boxes, Search } from 'lucide-react';
import type {
BaseModelCatalogItem,
BillingConfig,
@ -7,7 +7,6 @@ import type {
PlatformModel,
} from '@easyai-ai-gateway/contracts';
import type { ConsoleData } from '../app-state';
import { PageHeader } from '../components/PageHeader';
import { Badge, Card, CardContent, Input } from '../components/ui';
import { stableModelAlias } from './admin/platform-form';
@ -146,15 +145,12 @@ export function ModelsPage(props: { data: ConsoleData }) {
const filteredModels = useMemo(() => {
const normalizedQuery = query.trim().toLowerCase();
return sourceModels.filter((model) => {
const providerInfo = providerMap.get(model.providerKey);
const matchedProvider = provider === 'all' || model.providerKey === provider;
const matchedCapability = modelMatchesCapability(model.modelType, capability);
const matchedQuery = [
model.modelName,
model.modelAlias,
model.displayName,
providerInfo?.displayName,
providerInfo?.code,
]
.filter(Boolean)
.join(' ')
@ -162,9 +158,7 @@ export function ModelsPage(props: { data: ConsoleData }) {
.includes(normalizedQuery);
return matchedProvider && matchedCapability && matchedQuery;
});
}, [capability, provider, providerMap, query, sourceModels]);
const selectedProvider = provider === 'all' ? undefined : providerMap.get(provider);
}, [capability, provider, query, sourceModels]);
return (
<div className="modelsPage">
@ -184,31 +178,14 @@ export function ModelsPage(props: { data: ConsoleData }) {
</aside>
<main className="modelsContent">
<PageHeader
eyebrow="Models"
title="模型"
description={`${sourceModels.length} 个模型,当前显示 ${filteredModels.length}`}
/>
<div className="modelSearchBar">
<div className="searchField">
<div className="modelsToolbar">
<p> {sourceModels.length} {filteredModels.length} </p>
<div className="searchField modelHeaderSearch">
<Search size={16} />
<Input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="模型名称模糊搜索" />
</div>
</div>
<section className="providerHero">
{selectedProvider ? <ProviderIcon provider={selectedProvider} /> : (
<div className="providerLogo">
<Sparkles size={22} />
</div>
)}
<div>
<strong>{selectedProvider?.displayName ?? '全部模型厂商'}</strong>
<span>{selectedProvider ? `${selectedProvider.code} · ${selectedProvider.providerType}` : `${sourceProviders.length} 个厂商来自 integration-platform 目录`}</span>
</div>
<Badge variant="success">{filteredModels.length} </Badge>
</section>
<section className="modelCards">
{filteredModels.map((model) => (
<ModelCard model={model} provider={providerMap.get(model.providerKey)} key={model.id} />

View File

@ -79,9 +79,17 @@
gap: 14px;
}
.modelSearchBar {
.modelsToolbar {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 16px;
}
.modelsToolbar p {
margin-right: auto;
color: var(--text-soft);
font-size: var(--font-size-base);
}
.searchField {
@ -95,6 +103,10 @@
color: var(--muted-foreground);
}
.searchField.modelHeaderSearch {
width: min(520px, 42vw);
}
.searchField svg {
margin-left: 12px;
}
@ -105,27 +117,6 @@
box-shadow: none;
}
.providerHero {
display: flex;
min-height: 86px;
align-items: center;
gap: 14px;
padding: 18px;
border: 1px solid var(--border);
border-radius: 10px;
background: #fff;
}
.providerHero strong {
display: block;
font-size: 18px;
}
.providerHero span {
color: var(--muted-foreground);
font-size: 13px;
}
.providerLogo,
.modelIcon {
display: grid;
@ -149,10 +140,6 @@
object-fit: contain;
}
.providerHero .shBadge {
margin-left: auto;
}
.modelCards {
display: grid;
grid-template-columns: repeat(3, minmax(260px, 1fr));
@ -1423,6 +1410,15 @@
flex-direction: column;
}
.modelsToolbar {
align-items: flex-start;
flex-direction: column;
}
.searchField.modelHeaderSearch {
width: 100%;
}
.providerCatalogActions {
grid-column: 1 / -1;
justify-content: flex-start;