import { PageAction } from '@/config'; import { EditOutlined } from '@ant-design/icons'; import { AutoTooltip, Input as CInput } from '@gpustack/core-ui'; import { Button, Flex, Form, message } from 'antd'; import { useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import { createGPUServiceTemplate, updateGPUServiceTemplate } from '../../templates/apis'; import AddTemplateModal from '../../templates/components/add-modal'; import { mockTemplateData } from '../../templates/config/mock-data'; import { FormData as TemplateFormData, ListItem as TemplateListItem } from '../../templates/config/types'; import useCreateTemplate from '../../templates/hooks/use-create-template'; import { FormData } from '../config/types'; import TemplateOverlay from './template-overlay'; const FieldBlock = styled.div` margin-bottom: 24px; `; const SelectedCard = styled.div` display: grid; grid-template-columns: minmax(0, 1fr) max-content; align-items: center; gap: 12px; padding: 14px; border: 1px solid var(--ant-color-border); border-radius: var(--ant-border-radius-lg); background: var(--ant-color-bg-container); `; const SummaryTitle = styled.div` display: flex; align-items: center; gap: 8px; margin-bottom: 8px; color: var(--ant-color-text); font-weight: 500; `; const SummaryMeta = styled.div` display: grid; gap: 4px; color: var(--ant-color-text-secondary); font-size: 13px; `; interface TemplateSelectorProps { value?: number; onChange?: (value: number) => void; onCreate?: () => void; onEdit?: (row: TemplateListItem) => void; } const TemplatePicker: React.FC = ({ value, onChange, onCreate, onEdit }) => { const [open, setOpen] = useState(false); const selected = useMemo(() => { return mockTemplateData.find((item) => item.id === value); }, [value]); return ( <>
{selected?.name || '请选择实例模板'} 镜像: {selected?.image || '-'} 挂载: {selected?.volumeMount || '-'}
setOpen(false)} onChange={onChange} onCreate={() => { onCreate?.(); }} /> ); }; const TemplateFormItem = () => { const form = Form.useFormInstance(); const templateId = Form.useWatch('template_id', form) as number | undefined; const { openTemplateModalStatus, openTemplateModal, closeTemplateModal } = useCreateTemplate(); const selectedTemplate = useMemo(() => { return mockTemplateData.find((item) => item.id === templateId); }, [templateId]); useEffect(() => { if (!templateId && mockTemplateData[0]) { form.setFieldValue('template_id', mockTemplateData[0].id); return; } if (selectedTemplate) { form.setFieldValue(['spec', 'image'], selectedTemplate.image); form.setFieldValue(['spec', 'command'], selectedTemplate.command || []); form.setFieldValue(['spec', 'ports'], selectedTemplate.ports || []); form.setFieldValue(['spec', 'env'], selectedTemplate.env || []); form.setFieldValue(['spec', 'volumeMount'], selectedTemplate.volumeMount); const currentResources = form.getFieldValue(['spec', 'resources']) || {}; form.setFieldValue(['spec', 'resources'], { ...currentResources, cpu: selectedTemplate.resources?.cpu, ram: selectedTemplate.resources?.ram }); } }, [form, selectedTemplate, templateId]); const handleAddTemplate = () => { openTemplateModal(PageAction.CREATE, '添加实例模板'); }; const handleEditTemplate = (row: TemplateListItem) => { openTemplateModal(PageAction.EDIT, '编辑实例模板', row); }; const handleTemplateModalOk = async (data: TemplateFormData) => { try { if (openTemplateModalStatus.action === PageAction.EDIT) { await updateGPUServiceTemplate({ id: openTemplateModalStatus.currentData!.id, data }); } else { await createGPUServiceTemplate({ data }); } closeTemplateModal(); message.success('操作成功'); } catch (error) { message.error('操作失败'); } }; return (
name={['spec', 'image']} hidden>
); }; export default TemplateFormItem;