import { SetStateAction, ReactNode, useEffect } from 'react'; import { flushSync } from 'react-dom'; import { Checkbox, Button, Empty, Tooltip, Badge, Form, Select, Switch, FormInstance, } from '@arco-design/web-react'; import { IconDelete, IconPlus, IconInfoCircle, } from '@arco-design/web-react/icon'; import { defaultDataItem, proxyFormField } from '../../template/constant'; import { validateCustom, validateSemver, validatePort, isObject, separateType, FormItemStatus, RootComponentProps, } from '../../utils'; import styles from './index.module.scss'; const FormItem = Form.Item; const FormList = Form.List; const { Option } = Select; interface FormProps { form: FormInstance; condition: { status: string; message: string; color: string; }; formStatus: Array; setFormStatus: React.Dispatch>; validateForm: any; enableHMR: string; onHMRChange: (on: boolean) => void; } const FormComponent = (props: FormProps & RootComponentProps) => { const { form, condition, formStatus, setFormStatus, validateForm, enableHMR, onHMRChange, versionList, setVersionList, getVersion, } = props; const { moduleInfo } = window.__FEDERATION__; let { producer } = separateType(moduleInfo); const filterDupMap = new Map(); producer = producer.filter((t) => { const [typeOrName, name] = t.split(':'); const marked = filterDupMap.get(name || typeOrName); filterDupMap.set(name || typeOrName, true); return !marked; }); const formatProducer = producer.map((id) => { const hasType = id.includes(':'); if (hasType) { return { label: id.split(':')[1], value: id, }; } else { return { label: id, value: id, }; } }); useEffect(() => { producer.forEach(async (target) => { const version = await getVersion?.(target); const list = [...(versionList || [])]; if (version) { list.push(version); } setVersionList?.(list); }); }, []); const getCheckStatus = (index: number) => { const formData = form.getFieldsValue(); return formData[proxyFormField][index].checked; }; const validateKey = ( key: string, callback: { (error?: ReactNode): void; (arg0: string | undefined): any }, index: number, ) => { const status = getCheckStatus(index); if (!status) { return callback(); } const statusSet = [...formStatus]; if (!isObject(statusSet[index])) { statusSet[index] = { keyStatus: false, valueStatus: false, }; } if (key) { statusSet[index].keyStatus = true; flushSync(() => setFormStatus(statusSet)); return callback(); } statusSet[index].keyStatus = false; flushSync(() => setFormStatus(statusSet)); return callback('Module name can not be empty'); }; const validateValue = ( value: string, callback: { (error?: ReactNode): void; (arg0: string | undefined): any }, index: number, ) => { const status = getCheckStatus(index); if (!status) { return callback(); } const statusSet = [...formStatus]; if (!isObject(statusSet[index])) { statusSet[index] = { keyStatus: false, valueStatus: false, }; } if (validateCustom(value) || validateSemver(value) || validatePort(value)) { statusSet[index].valueStatus = true; flushSync(() => setFormStatus(statusSet)); return callback(); } statusSet[index].valueStatus = false; flushSync(() => setFormStatus(statusSet)); return callback( 'The module information format is incorrect, check the format in the upper left corner', ); }; const onAdd = (add: { (defaultValue?: any, index?: number | undefined): void; (arg0: { key: string; value: string; checked: boolean }): void; }) => { add(defaultDataItem); setVersionList?.([...(versionList || []), []]); validateForm(); }; const onRemove = (remove: (index: number) => void, index: number) => { if (Array.isArray(versionList)) { versionList.splice(index, 1); setVersionList?.(versionList); } remove(index); }; const hmrChange = (on: boolean) => { onHMRChange(on); }; const onKeyChange = async (key: string, index: number) => { const version = await getVersion?.(key); if (version) { const list = [...(versionList || [])]; list.splice(index, 1, version); setVersionList?.(list); } }; return ( {(fields, { add, remove }) => (
Example: Customize the remote module address, which should end with 「.json」, for example key: @module-federation/button, value: http://localhost:3000/mf-manifest.json
} >
Module Proxy
{fields.length ? ( <> {fields.map((item, index) => (
validateKey(value, cb, index), }, ]} >
validateValue(value, cb, index), }, ]} >
))} ) : ( )} )}
); }; export default FormComponent;