feat: 完成前端重构,采用 Ant Design 5 和完整测试体系
- 采用 Ant Design 5 作为 UI 组件库,替换自定义组件 - 集成 React Router v7 提供路由导航 - 使用 TanStack Query v5 管理数据获取和缓存 - 建立 Vitest + React Testing Library 测试体系 - 添加 Playwright E2E 测试覆盖 - 使用 MSW mock API 响应 - 配置 TypeScript strict 模式 - 采用 SCSS Modules 组织样式 - 更新 OpenSpec 规格以反映前端架构变更 - 归档 frontend-refactor 变更记录
This commit is contained in:
92
frontend/src/pages/Providers/ProviderForm.tsx
Normal file
92
frontend/src/pages/Providers/ProviderForm.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Modal, Form, Input, Switch } from 'antd';
|
||||
import type { Provider } from '@/types';
|
||||
|
||||
interface ProviderFormValues {
|
||||
id: string;
|
||||
name: string;
|
||||
apiKey: string;
|
||||
baseUrl: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
interface ProviderFormProps {
|
||||
open: boolean;
|
||||
provider?: Provider;
|
||||
onSave: (values: ProviderFormValues) => void;
|
||||
onCancel: () => void;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
export function ProviderForm({
|
||||
open,
|
||||
provider,
|
||||
onSave,
|
||||
onCancel,
|
||||
loading,
|
||||
}: ProviderFormProps) {
|
||||
const [form] = Form.useForm<ProviderFormValues>();
|
||||
const isEdit = !!provider;
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
if (provider) {
|
||||
form.setFieldsValue({
|
||||
id: provider.id,
|
||||
name: provider.name,
|
||||
apiKey: '',
|
||||
baseUrl: provider.baseUrl,
|
||||
enabled: provider.enabled,
|
||||
});
|
||||
} else {
|
||||
form.resetFields();
|
||||
}
|
||||
}
|
||||
}, [open, provider, form]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={isEdit ? '编辑供应商' : '添加供应商'}
|
||||
open={open}
|
||||
onOk={() => form.submit()}
|
||||
onCancel={onCancel}
|
||||
confirmLoading={loading}
|
||||
okText="保存"
|
||||
cancelText="取消"
|
||||
destroyOnClose
|
||||
>
|
||||
<Form form={form} layout="vertical" onFinish={onSave} initialValues={{ enabled: true }}>
|
||||
<Form.Item label="ID" name="id" rules={[{ required: true, message: '请输入供应商 ID' }]}>
|
||||
<Input disabled={isEdit} placeholder="例如: openai" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="名称" name="name" rules={[{ required: true, message: '请输入名称' }]}>
|
||||
<Input placeholder="例如: OpenAI" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={isEdit ? 'API Key(留空则不修改)' : 'API Key'}
|
||||
name="apiKey"
|
||||
rules={isEdit ? [] : [{ required: true, message: '请输入 API Key' }]}
|
||||
>
|
||||
<Input.Password placeholder="sk-..." />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label="Base URL"
|
||||
name="baseUrl"
|
||||
rules={[
|
||||
{ required: true, message: '请输入 Base URL' },
|
||||
{ type: 'url', message: '请输入有效的 URL' },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="例如: https://api.openai.com/v1" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="启用" name="enabled" valuePropName="checked">
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user