feat(web): refine model availability states and preserve API key preview placeholder (#2226)

* feat(web): clarify model availability and status display

- Rename model availability field from configured to available across backend API and frontend usage

- Keep status as reason classification (configured/unconfigured/unreachable) and show unreachable in UI

- Preserve API key preview even when local service is unreachable

- Update backend tests to assert both availability and status semantics

* fix(web): clarify unreachable model status and wording

- Show unreachable status in model cards instead of API key preview when service is down

- Keep API key placeholder preview in model settings whenever an API key is already saved

- Rename model status wording from configured to available across backend, frontend, and i18n

- Update backend model status tests to match renamed status semantics

* style(web): standardize formatting in handleListModels function

* refactor(web): enforce status field as required to follow backend behavior
This commit is contained in:
LC
2026-03-31 22:52:04 +08:00
committed by GitHub
parent 2bf842e460
commit 3b3f95c44c
12 changed files with 161 additions and 69 deletions
@@ -10,19 +10,19 @@ import { useTranslation } from "react-i18next"
import { Button } from "@/components/ui/button"
interface ChatEmptyStateProps {
hasConfiguredModels: boolean
hasAvailableModels: boolean
defaultModelName: string
isConnected: boolean
}
export function ChatEmptyState({
hasConfiguredModels,
hasAvailableModels,
defaultModelName,
isConnected,
}: ChatEmptyStateProps) {
const { t } = useTranslation()
if (!hasConfiguredModels) {
if (!hasAvailableModels) {
return (
<div className="flex flex-col items-center justify-center py-20 opacity-70">
<div className="mb-6 flex h-16 w-16 items-center justify-center rounded-2xl bg-amber-500/10 text-amber-500">
@@ -39,7 +39,7 @@ export function ChatPage() {
const {
defaultModelName,
hasConfiguredModels,
hasAvailableModels,
apiKeyModels,
oauthModels,
localModels,
@@ -94,7 +94,7 @@ export function ChatPage() {
hasScrolled ? "shadow-sm" : "shadow-none"
}`}
titleExtra={
hasConfiguredModels && (
hasAvailableModels && (
<ModelSelector
defaultModelName={defaultModelName}
apiKeyModels={apiKeyModels}
@@ -140,7 +140,7 @@ export function ChatPage() {
<div className="mx-auto flex w-full max-w-250 flex-col gap-8 pb-8">
{messages.length === 0 && !isTyping && (
<ChatEmptyState
hasConfiguredModels={hasConfiguredModels}
hasAvailableModels={hasAvailableModels}
defaultModelName={defaultModelName}
isConnected={isGatewayRunning}
/>