import { useEffect, useState } from 'react'; import { useDebounceFn, useUpdateEffect } from 'ahooks'; import { Form, FormInstance } from '@arco-design/web-react'; import { GlobalModuleInfo, MODULE_DEVTOOL_IDENTIFIER, } from '@module-federation/sdk'; import FormComponent from '../Form'; import Dependency from '../Graph'; import { getModuleInfo, getScope, injectScript, isObject, separateType, reloadPage, setChromeStorage, mergeStorage, removeStorageKey, removeStorage, setStorage, FormItemStatus, RootComponentProps, } from '../../utils'; import { defaultModuleData, proxyFormField, FormID, statusInfo, ENABLEHMR, __ENABLE_FAST_REFRESH__, BROWSER_ENV_KEY, __FEDERATION_DEVTOOLS__, } from '../../template/constant'; interface FormItemType { key: string; value: string; checked: boolean; } const Layout = ( props: { moduleInfo: GlobalModuleInfo } & RootComponentProps, ) => { const { moduleInfo, handleSnapshot, versionList, setVersionList, getVersion, handleProxyAddress, } = props; const { producer } = separateType(moduleInfo); const [condition, setCondition] = useState(statusInfo.processing); const [formStatus, setFormStatus] = useState>([]); const [snapshot, setSnapshot] = useState(moduleInfo); const [form] = Form.useForm(); const [enableHMR, setEnalbeHMR] = useState('disable'); const { run } = useDebounceFn( async (formData) => { window.__FEDERATION__.moduleInfo = JSON.parse( JSON.stringify(window.__FEDERATION__.originModuleInfo), ); const filterFormData = formData[proxyFormField].reduce( (memo: Array, current: FormItemType, idx: number) => { if (!formStatus[idx]) { return memo; } const { keyStatus, valueStatus } = formStatus[idx]; if (!keyStatus || !valueStatus || !current.checked) { return memo; } const duplicate = JSON.parse(JSON.stringify(current)); if (handleProxyAddress) { const value = handleProxyAddress(duplicate.value); duplicate.value = value; } return [...memo, duplicate]; }, [], ); try { setCondition(statusInfo.processing); if (!filterFormData.length) { await removeStorage(MODULE_DEVTOOL_IDENTIFIER); await removeStorage(BROWSER_ENV_KEY); await removeStorageKey(__FEDERATION_DEVTOOLS__, 'overrides'); await injectScript(reloadPage, false); setCondition(statusInfo.noProxy); setSnapshot(window.__FEDERATION__.originModuleInfo); return; } const { moduleInfo, status, overrides } = handleSnapshot ? await handleSnapshot(filterFormData) : await getModuleInfo(filterFormData); const snapshotJson = JSON.stringify(moduleInfo); await setStorage(MODULE_DEVTOOL_IDENTIFIER, snapshotJson); await setStorage(BROWSER_ENV_KEY); await mergeStorage(__FEDERATION_DEVTOOLS__, 'overrides', overrides); await injectScript(reloadPage, false); window.__FEDERATION__.moduleInfo = moduleInfo; setSnapshot(moduleInfo); setCondition(statusInfo[status]); } catch (e) { console.log(e); setCondition(statusInfo.error); } }, { wait: 700, }, ); useEffect(() => { setSnapshot(moduleInfo); }, [moduleInfo]); useEffect(() => { getScope().then(async (scope) => { const data = await chrome.storage.sync.get([FormID]); const config = data?.[FormID]?.[scope]; let storeData; if (isObject(config)) { storeData = JSON.parse(JSON.stringify(config)); storeData[proxyFormField] = storeData[proxyFormField]?.filter( (item: { key: string }) => producer.includes(item.key), ); if (!storeData[proxyFormField]?.length) { storeData = defaultModuleData; } } else { storeData = defaultModuleData; } form.setFieldsValue(storeData); }); }, []); useEffect(() => { chrome.storage.sync.get([ENABLEHMR]).then((data) => { const enable = data[ENABLEHMR]; if (typeof enable === 'boolean') { onHMRChange(enable); } }); }, []); useEffect(() => { validateForm(form); }, []); useUpdateEffect(() => { const formData = form.getFieldsValue(); run(formData); }, []); const validateForm = ( form: FormInstance, ) => { // 不能同步检查,添加或者 setFieldsValue 操作此时都未完成导致新增部分没验证 setTimeout(() => { form.validate().catch(() => { console.log('Invalid proxy rules'); }); }, 50); }; const onValuesChange = (target: any, formData: any) => { validateForm(form); setChromeStorage(formData); run(formData); }; const onHMRChange = (on: boolean) => { setEnalbeHMR(on ? 'enable' : 'disable'); chrome.storage.sync.set({ [ENABLEHMR]: on, }); if (on) { mergeStorage(__FEDERATION_DEVTOOLS__, __ENABLE_FAST_REFRESH__, on); } else { removeStorageKey(__FEDERATION_DEVTOOLS__, __ENABLE_FAST_REFRESH__); } injectScript(reloadPage, false); }; return ( <>
onValuesChange(value, formData)} initialValues={defaultModuleData} > validateForm(form)} enableHMR={enableHMR} onHMRChange={onHMRChange} versionList={versionList} setVersionList={setVersionList} getVersion={getVersion} /> ); }; export default Layout;