/* * @Author: ZhaoYing * @Date: 2026-02-28 14:08:14 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-06 12:05:46 */ /** * UploadWorkflowModal Component * * This component provides a modal for uploading workflow files with a multi-step process: * 1. Upload - Select platform and file * 2. Complex - Show warnings and errors if any * 3. SureInfo - Confirm and edit workflow information * 4. Completed - Show success message and options */ import { forwardRef, useImperativeHandle, useState, useMemo } from 'react'; import { Form, Select, Steps, Flex, Alert, Input, Button, Result, message } from 'antd'; import { useTranslation } from 'react-i18next'; import type { UploadWorkflowModalData, UploadData, UploadWorkflowModalRef } from '../types' import RbModal from '@/components/RbModal' import UploadFiles from '@/components/Upload/UploadFiles' import { importWorkflow, completeImportWorkflow } from '@/api/application' /** * Props for UploadWorkflowModal component */ interface UploadWorkflowModalProps { /** Function to refresh the parent component after workflow import */ refresh: () => void; } /** * Steps definition for the upload process */ const steps = [ 'upload', // Step 1: File upload 'complex', // Step 2: Error/warning display 'sureInfo', // Step 3: Information confirmation 'completed' // Step 4: Success message ] /** * UploadWorkflowModal component * * @param {UploadWorkflowModalProps} props - Component props * @param {React.Ref} ref - Ref for imperative methods */ const UploadWorkflowModal = forwardRef(({ refresh }, ref) => { const { t } = useTranslation(); // State management const [visible, setVisible] = useState(false); // Modal visibility const [form] = Form.useForm(); // Form instance const [loading, setLoading] = useState(false); // Loading state const [current, setCurrent] = useState(0); // Current step const [data, setData] = useState(null); // Upload response data const [firstFormData, setFirstFormData] = useState(null); // First step form data const [appId, setAppId] = useState(null); // Imported application ID /** * Handle modal close * Resets all states and form fields */ const handleClose = () => { setVisible(false); form.resetFields(); setData(null); setCurrent(0); setFirstFormData(null); setAppId(null); setLoading(false); }; /** * Handle modal open * Resets form fields and shows modal */ const handleOpen = () => { form.resetFields(); setVisible(true); }; /** * Handle save/submit action * Processes different logic based on current step */ const handleSave = () => { const values = form.getFieldsValue(); switch(current) { case 0: // Step 1: Upload file if (!values.file || values.file.length === 0) { message.warning(t('application.pleaseUploadFile')); return; } const formData = new FormData(); setFirstFormData(values); formData.append('platform', values.platform); formData.append('file', values.file[0]); // Call import workflow API importWorkflow(formData) .then(res => { const response = res as UploadData; const { errors, warnings } = response; setData(response); // Navigate to error/warning step if any, otherwise go to confirmation if (errors.length || warnings.length) { setCurrent(1); } else { setCurrent(2); // Pre-fill form with file information form.setFieldsValue({ name: values.file[0].name.split('.')[0], platform: values.platform, fileName: values.file[0].name, fileSize: values.file[0].size, }); } }); break; case 1: // Step 2: Error/warning display if (firstFormData) { const { file, platform } = firstFormData; // Pre-fill form with file information form.setFieldsValue({ name: file[0].name.split('.')[0], platform: platform, fileName: file[0].name, fileSize: file[0].size, }); } setCurrent(2); break; case 2: // Step 3: Confirm information if (data) { // Complete import workflow completeImportWorkflow({ temp_id: data.temp_id, name: values.name, description: values.description, }) .then((res) => { const response = res as { id: string }; setCurrent(3); setAppId(response.id); }); } break; default: setCurrent(prev => prev + 1); break; } }; // Expose methods to parent component via ref useImperativeHandle(ref, () => ({ handleOpen, handleClose })); /** * Handle navigation to previous step * Adjusts step based on whether there were errors/warnings */ const handleLastStep = () => { let newStep = current - 1; // If no errors or warnings, skip the error/warning step if (!data?.warnings?.length && !data?.errors?.length) { newStep = current - 2; } // Reset form if not going back to error/warning step if (newStep !== 1) { form.resetFields(); } setCurrent(newStep); }; /** * Handle navigation after successful import * @param {string} type - Navigation type ('detail' or 'list') */ const handleJump = (type: string) => { handleClose(); refresh(); setTimeout(() => { switch (type) { case 'detail': // Open application detail page in new tab window.open(`/#/application/config/${appId}`, '_blank'); break; } }, 100) }; /** * Generate modal footer based on current step */ const getFooter = useMemo(() => { switch(current) { case 0: // Step 1: Upload return [ , ]; case 3: // Step 4: Completed return null; default: // Steps 1-2 return [ , , ]; } }, [current]); return ( {/* Steps indicator */}
({ title: t(`application.${key}`) }))} />
{/* Step 1: File upload */} {current === 0 &&
} {/* Step 4: Success message */} {current === 3 && handleJump('list')}> {t('application.gotoList')} , ]} /> }
); }); export default UploadWorkflowModal;