refactor(setting): split model dialogs into separate components

This commit is contained in:
2025-10-24 11:41:44 +08:00
parent cdc0a466b4
commit a9b47f776b
10 changed files with 1103 additions and 897 deletions

View File

@@ -0,0 +1,203 @@
import React, { useEffect } from 'react';
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
TextField,
Box,
Typography,
IconButton,
InputAdornment,
FormControl,
InputLabel,
Select,
MenuItem,
CircularProgress,
} from '@mui/material';
import { Visibility, VisibilityOff } from '@mui/icons-material';
import { Controller, useForm } from 'react-hook-form';
// AWS Bedrock 支持的区域列表
export const BEDROCK_REGIONS = [
{ value: 'us-east-1', label: 'US East (N. Virginia)' },
{ value: 'us-west-2', label: 'US West (Oregon)' },
{ value: 'ap-southeast-2', label: 'Asia Pacific (Sydney)' },
{ value: 'ap-northeast-1', label: 'Asia Pacific (Tokyo)' },
{ value: 'eu-central-1', label: 'Europe (Frankfurt)' },
{ value: 'eu-west-3', label: 'Europe (Paris)' },
];
// 表单数据接口
export interface BedrockFormData {
access_key_id: string;
secret_access_key: string;
region: string;
}
// 对话框 Props 接口
export interface BedrockDialogProps {
open: boolean;
onClose: () => void;
onSubmit: (data: BedrockFormData) => void;
loading: boolean;
initialData?: BedrockFormData;
editMode?: boolean;
}
/**
* AWS Bedrock 配置对话框
*/
function BedrockDialog ({
open,
onClose,
onSubmit,
loading,
initialData,
editMode = false,
}: BedrockDialogProps) {
const [showAccessKey, setShowAccessKey] = React.useState(false);
const [showSecretKey, setShowSecretKey] = React.useState(false);
const {
control,
handleSubmit,
reset,
formState: { errors },
} = useForm<BedrockFormData>({
defaultValues: {
access_key_id: '',
secret_access_key: '',
region: 'us-east-1',
},
});
// 当对话框打开或初始数据变化时重置表单
useEffect(() => {
if (open) {
reset(initialData || { access_key_id: '', secret_access_key: '', region: 'us-east-1' });
}
}, [open, initialData, reset]);
const handleFormSubmit = (data: BedrockFormData) => {
onSubmit(data);
};
const toggleShowAccessKey = () => {
setShowAccessKey(!showAccessKey);
};
const toggleShowSecretKey = () => {
setShowSecretKey(!showSecretKey);
};
return (
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
<DialogTitle>
{editMode ? '编辑' : '配置'} AWS Bedrock
</DialogTitle>
<DialogContent>
<Box component="form" sx={{ mt: 2 }}>
<Controller
name="access_key_id"
control={control}
rules={{ required: 'Access Key ID 是必填项' }}
render={({ field }) => (
<TextField
{...field}
fullWidth
label="Access Key ID"
type={showAccessKey ? 'text' : 'password'}
margin="normal"
error={!!errors.access_key_id}
helperText={errors.access_key_id?.message}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="toggle access key visibility"
onClick={toggleShowAccessKey}
edge="end"
>
{showAccessKey ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}}
/>
)}
/>
<Controller
name="secret_access_key"
control={control}
rules={{ required: 'Secret Access Key 是必填项' }}
render={({ field }) => (
<TextField
{...field}
fullWidth
label="Secret Access Key"
type={showSecretKey ? 'text' : 'password'}
margin="normal"
error={!!errors.secret_access_key}
helperText={errors.secret_access_key?.message}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="toggle secret key visibility"
onClick={toggleShowSecretKey}
edge="end"
>
{showSecretKey ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}}
/>
)}
/>
<Controller
name="region"
control={control}
rules={{ required: 'Region 是必填项' }}
render={({ field }) => (
<FormControl fullWidth margin="normal" error={!!errors.region}>
<InputLabel>Region</InputLabel>
<Select {...field} label="Region">
{BEDROCK_REGIONS.map((region) => (
<MenuItem key={region.value} value={region.value}>
{region.label}
</MenuItem>
))}
</Select>
{errors.region && (
<Typography variant="caption" color="error" sx={{ mt: 1, ml: 2 }}>
{errors.region.message}
</Typography>
)}
</FormControl>
)}
/>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={onClose} disabled={loading}>
</Button>
<Button
onClick={handleSubmit(handleFormSubmit)}
variant="contained"
disabled={loading}
startIcon={loading ? <CircularProgress size={20} /> : null}
>
</Button>
</DialogActions>
</Dialog>
);
};
export default BedrockDialog;