Add platform status switch
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useState, type FormEvent, type ReactNode } from 'react';
|
||||
import { Boxes, CheckCircle2, Globe2, KeyRound, Pencil, Plus, RotateCcw, Search, ServerCog, ShieldCheck, SlidersHorizontal, Trash2, X } from 'lucide-react';
|
||||
import type { BaseModelCatalogItem, CatalogProvider, IntegrationPlatform, PlatformModel, PricingRuleSet } from '@easyai-ai-gateway/contracts';
|
||||
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, ConfirmDialog, EmptyState, FormDialog, Input, Label, ScreenMessage, Select, Table, TableCell, TableHead, TableRow } from '../../components/ui';
|
||||
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, ConfirmDialog, EmptyState, FormDialog, Input, Label, ScreenMessage, Select, Switch, Table, TableCell, TableHead, TableRow } from '../../components/ui';
|
||||
import type { LoadState, PlatformWithModelsInput } from '../../types';
|
||||
import {
|
||||
authTypes,
|
||||
@@ -31,6 +31,7 @@ export function PlatformManagementPanel(props: {
|
||||
state: LoadState;
|
||||
onDeletePlatform: (platformId: string) => Promise<void>;
|
||||
onSavePlatform: (input: PlatformWithModelsInput) => Promise<void>;
|
||||
onTogglePlatformStatus: (platform: IntegrationPlatform, status: 'enabled' | 'disabled') => Promise<void>;
|
||||
}) {
|
||||
const defaultProvider = props.providers[0]?.providerKey ?? props.baseModels[0]?.providerKey ?? '';
|
||||
const [now, setNow] = useState(() => Date.now());
|
||||
@@ -42,6 +43,7 @@ export function PlatformManagementPanel(props: {
|
||||
const [globalProxyNoticeOpen, setGlobalProxyNoticeOpen] = useState(false);
|
||||
const [editingPlatform, setEditingPlatform] = useState<IntegrationPlatform | null>(null);
|
||||
const [pendingDeletePlatform, setPendingDeletePlatform] = useState<IntegrationPlatform | null>(null);
|
||||
const [togglingPlatformId, setTogglingPlatformId] = useState('');
|
||||
const providerMap = useMemo(() => new Map(props.providers.map((item) => [item.providerKey, item])), [props.providers]);
|
||||
const platformMap = useMemo(() => new Map(props.platforms.map((item) => [item.id, item])), [props.platforms]);
|
||||
const [form, setForm] = useState<PlatformWizardForm>(() => createEmptyPlatformForm(defaultProvider, providerDefaults(providerMap.get(defaultProvider))));
|
||||
@@ -157,6 +159,18 @@ export function PlatformManagementPanel(props: {
|
||||
}
|
||||
}
|
||||
|
||||
async function togglePlatformStatus(platform: IntegrationPlatform, status: 'enabled' | 'disabled') {
|
||||
setTogglingPlatformId(platform.id);
|
||||
setValidationMessage('');
|
||||
try {
|
||||
await props.onTogglePlatformStatus(platform, status);
|
||||
} catch (err) {
|
||||
setValidationMessage(err instanceof Error ? err.message : '切换平台状态失败');
|
||||
} finally {
|
||||
setTogglingPlatformId('');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="pageStack">
|
||||
<ScreenMessage message={validationMessage} variant="error" onClose={() => setValidationMessage('')} />
|
||||
@@ -183,9 +197,11 @@ export function PlatformManagementPanel(props: {
|
||||
platforms={props.platforms}
|
||||
providerMap={providerMap}
|
||||
pricingRuleSets={props.pricingRuleSets}
|
||||
togglingPlatformId={togglingPlatformId}
|
||||
onDelete={setPendingDeletePlatform}
|
||||
onCreate={openCreateDialog}
|
||||
onEdit={openEditDialog}
|
||||
onToggleStatus={togglePlatformStatus}
|
||||
/>
|
||||
) : (
|
||||
<PlatformModelTable
|
||||
@@ -404,9 +420,11 @@ function PlatformTable(props: {
|
||||
platforms: IntegrationPlatform[];
|
||||
providerMap: Map<string, CatalogProvider>;
|
||||
pricingRuleSets: PricingRuleSet[];
|
||||
togglingPlatformId: string;
|
||||
onCreate: () => void;
|
||||
onDelete: (platform: IntegrationPlatform) => void;
|
||||
onEdit: (platform: IntegrationPlatform) => void;
|
||||
onToggleStatus: (platform: IntegrationPlatform, status: 'enabled' | 'disabled') => void;
|
||||
}) {
|
||||
if (!props.platforms.length) {
|
||||
return (
|
||||
@@ -438,6 +456,8 @@ function PlatformTable(props: {
|
||||
const rateLimit = platformRateLimitSummary(platform.rateLimitPolicy);
|
||||
const runtime = platformRuntimeSummary(platform);
|
||||
const platformCooldownMs = cooldownRemainingMs(platform.cooldownUntil, props.now);
|
||||
const isEnabled = platform.status === 'enabled';
|
||||
const isToggling = props.togglingPlatformId === platform.id;
|
||||
return (
|
||||
<TableRow key={platform.id}>
|
||||
<TableCell>
|
||||
@@ -467,12 +487,21 @@ function PlatformTable(props: {
|
||||
</TableCell>
|
||||
<TableCell>{props.platformModelCount.get(platform.id) ?? 0}</TableCell>
|
||||
<TableCell>
|
||||
<span className="platformTableName">
|
||||
<span className="platformStatusCell">
|
||||
<span className="platformStatusToggle">
|
||||
<Switch
|
||||
aria-label={`${platformDisplayName(platform)} ${isEnabled ? '禁用' : '启用'}平台`}
|
||||
checked={isEnabled}
|
||||
disabled={isToggling}
|
||||
onCheckedChange={(checked) => props.onToggleStatus(platform, checked ? 'enabled' : 'disabled')}
|
||||
/>
|
||||
<span>{isEnabled ? '启用' : '禁用'}</span>
|
||||
</span>
|
||||
<strong>
|
||||
{platformCooldownMs > 0 ? (
|
||||
<Badge variant="warning">冷却中</Badge>
|
||||
) : (
|
||||
<Badge variant={platform.status === 'enabled' ? 'success' : 'secondary'}>{platform.status}</Badge>
|
||||
<Badge variant={isEnabled ? 'success' : 'destructive'}>{isEnabled ? '已启用' : '已禁用'}</Badge>
|
||||
)}
|
||||
</strong>
|
||||
<small>{platformCooldownMs > 0 ? `剩余 ${formatCooldownRemaining(platformCooldownMs)}` : runtime}</small>
|
||||
|
||||
Reference in New Issue
Block a user