|
|
|
|
@ -5,8 +5,16 @@ import { |
|
|
|
|
ParentCallbacks, |
|
|
|
|
} from "../../utils/types.ts"; |
|
|
|
|
import { ReactComponentContext } from "@ng-org/frontend/react/context"; |
|
|
|
|
import { useCallback, useContext, useEffect, useMemo } from "react"; |
|
|
|
|
import { JSX, useContext, useEffect, useMemo, useState } from "react"; |
|
|
|
|
import { deepSignal } from "@ng-org/alien-deepsignals"; |
|
|
|
|
import { ParcelConfig } from "single-spa"; |
|
|
|
|
|
|
|
|
|
type ReactNgComponentProps = ParcelProps & { |
|
|
|
|
/** Props specific to single-spa-react/parcel */ |
|
|
|
|
reactParcelProps?: ParcelCompProps; |
|
|
|
|
/** Component to show while the NgComponent is not loaded. E.g. a spinner. Default is empty. */ |
|
|
|
|
loadingIndicator?: JSX.Element; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* React element to mount NG components. |
|
|
|
|
@ -17,11 +25,10 @@ export default function NgComponent({ |
|
|
|
|
applicationId, |
|
|
|
|
initialPathName, |
|
|
|
|
component: componentFactory, |
|
|
|
|
/** The props to be passed to the NG component. Those are reactive. */ |
|
|
|
|
props, |
|
|
|
|
/** Specific props for single-spa-react */ |
|
|
|
|
reactParcelProps, |
|
|
|
|
}: ParcelProps & { reactParcelProps?: ParcelCompProps }) { |
|
|
|
|
loadingIndicator = <></>, |
|
|
|
|
}: ReactNgComponentProps) { |
|
|
|
|
const componentContext = useContext(ReactComponentContext); |
|
|
|
|
if (!componentContext) |
|
|
|
|
throw new Error( |
|
|
|
|
@ -60,20 +67,32 @@ export default function NgComponent({ |
|
|
|
|
componentContext.parentCallbacks.unRegisterChild([applicationId]); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const lifecycles = useCallback(async () => { |
|
|
|
|
let lifecycleHooks: any = await componentFactory; |
|
|
|
|
if (typeof lifecycleHooks === "function") { |
|
|
|
|
lifecycleHooks = await lifecycleHooks(componentFactoryParams); |
|
|
|
|
} |
|
|
|
|
if (typeof lifecycleHooks === "function") { |
|
|
|
|
lifecycleHooks = await lifecycleHooks(componentFactoryParams); |
|
|
|
|
} |
|
|
|
|
const [resolvedLifecycles, setResolvedLifecycles] = useState< |
|
|
|
|
ParcelConfig | undefined |
|
|
|
|
>(undefined); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
if (!componentFactory) return; |
|
|
|
|
|
|
|
|
|
Promise.try(async () => { |
|
|
|
|
let lifecycleHooks: any = await componentFactory; |
|
|
|
|
if (typeof lifecycleHooks === "function") { |
|
|
|
|
lifecycleHooks = await lifecycleHooks(componentFactoryParams); |
|
|
|
|
} |
|
|
|
|
if (typeof lifecycleHooks === "function") { |
|
|
|
|
lifecycleHooks = await lifecycleHooks(componentFactoryParams); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
name: applicationId, |
|
|
|
|
...lifecycleHooks, |
|
|
|
|
}; |
|
|
|
|
setResolvedLifecycles({ |
|
|
|
|
name: applicationId, |
|
|
|
|
...lifecycleHooks, |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}, [applicationId, componentFactory]); |
|
|
|
|
|
|
|
|
|
return <Parcel {...props} {...reactParcelProps} config={lifecycles} />; |
|
|
|
|
if (!resolvedLifecycles) return loadingIndicator; |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<Parcel {...props} {...reactParcelProps} config={resolvedLifecycles} /> |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|