/* * @Author: ZhaoYing * @Date: 2026-02-03 17:49:09 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-25 11:45:54 */ /** * Space Modal Component * Two-step modal for creating workspace with basic info and model configuration */ import { forwardRef, useImperativeHandle, useState } from 'react'; import { Form, Input, App, Steps, Button } from 'antd'; import { useTranslation } from 'react-i18next'; import type { SpaceModalData, SpaceModalRef, Space, StorageType } from '../types' import RbModal from '@/components/RbModal' import { createWorkspace } from '@/api/workspaces' import RadioGroupCard from '@/components/RadioGroupCard' import UploadImages from '@/components/Upload/UploadImages' import { getFileLink } from '@/api/fileStorage' import ragIcon from '@/assets/images/space/rag.png' import neo4jIcon from '@/assets/images/space/neo4j.png' import { stringRegExp } from '@/utils/validator'; import ModelSelect from '@/components/ModelSelect'; const FormItem = Form.Item; /** * Component props */ interface SpaceModalProps { refresh: () => void; } /** Storage types */ const types: StorageType[] = [ 'neo4j', 'rag', ] /** Type icons mapping */ const typeIcons: Record = { rag: ragIcon, neo4j: neo4jIcon } const SpaceModal = forwardRef(({ refresh }, ref) => { const { t } = useTranslation(); const { message } = App.useApp(); const [visible, setVisible] = useState(false); const [form] = Form.useForm(); const [loading, setLoading] = useState(false) const [editVo, setEditVo] = useState(null) const [currentStep, setCurrentStep] = useState(0) const values = Form.useWatch([], form); /** Close modal and reset form */ const handleClose = () => { setVisible(false); form.resetFields(); setLoading(false) setEditVo(null) setCurrentStep(0) }; /** Go to previous step */ const handlePrevStep = () => { setCurrentStep(prev => prev - 1) } /** Open modal with optional data */ const handleOpen = (space?: Space) => { if (space) { setEditVo(space || null) form.setFieldsValue({ name: space.name, icon: space.icon }) } else { form.resetFields(); } setVisible(true); }; /** Save or proceed to next step */ const handleSave = () => { form .validateFields() .then(() => { if (currentStep === 0) { setCurrentStep(1) } else { const { icon, ...rest } = values const formData: SpaceModalData = { ...rest } if (icon?.response?.data.file_id) { getFileLink(icon?.response?.data.file_id).then(res => { const logoRes = res as { url: string } formData.icon = logoRes.url formData.iconType = 'remote' handleUpdate(formData) }).catch(() => { handleUpdate(formData) }) } else { handleUpdate(formData) } } }) .catch((err) => { console.log('err', err) }); } /** Update workspace */ const handleUpdate = (formData: SpaceModalData) => { setLoading(true) createWorkspace(formData) .then(() => { setLoading(false) refresh() handleClose() message.success(t('common.createSuccess')) }) .catch(() => { setLoading(false) }); } /** Expose methods to parent component */ useImperativeHandle(ref, () => ({ handleOpen, handleClose })); return ( {t(currentStep === 0 ? 'common.cancel' : 'common.prevStep')}, , ]} confirmLoading={loading} > ({ title: t(`space.${key}`) } ))} className="rb:mb-6!" />
{currentStep === 1 && <> }
); }); export default SpaceModal;