@equinor/fusion-framework-cli
Version:
--- title: Fusion Framework CLI ---
78 lines • 4.14 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useMemo, useRef, useState } from 'react';
import { Subscription } from 'rxjs';
import { last } from 'rxjs/operators';
import { useFramework } from '@equinor/fusion-framework-react';
import { useObservableState } from '@equinor/fusion-observable/react';
import { AppManifestError } from '@equinor/fusion-framework-module-app/errors.js';
import { ErrorViewer } from './ErrorViewer';
import EquinorLoader from './EquinorLoader';
/**
* React Functional Component for handling current application
*
* this component will set the current app by provided appKey.
* when the appKey changes, this component will try to initialize the referred application
* and render it.
*/
export const AppLoader = (props) => {
const { appKey } = props;
const fusion = useFramework();
/** reference of application section/container */
const ref = useRef(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
// TODO change to `useCurrentApp`
/** observe and use the current selected application from framework */
const { value: currentApp } = useObservableState(useMemo(() => fusion.modules.app.current$, [fusion.modules.app]));
useEffect(() => {
/** when appKey property change, assign it to current */
fusion.modules.app.setCurrentApp(appKey);
}, [appKey, fusion]);
useEffect(() => {
/** flag that application is loading */
setLoading(true);
/** clear previous errors */
setError(undefined);
/** create a teardown of load */
const subscription = new Subscription();
/** make sure that initialize is canceled and disposed if current app changes */
subscription.add(currentApp === null || currentApp === void 0 ? void 0 : currentApp.initialize().pipe(last()).subscribe({
next: ({ manifest, script, config }) => {
var _a, _b;
/** generate basename for application */
const [basename] = (_a = window.location.pathname.match(/\/?apps\/[a-z|-]+(\/)?/g)) !== null && _a !== void 0 ? _a : [''];
/** create a 'private' element for the application */
const el = document.createElement('div');
if (!ref.current) {
throw Error('Missing application mounting point');
}
ref.current.appendChild(el);
/** extract render callback function from javascript module */
const render = (_b = script.renderApp) !== null && _b !== void 0 ? _b : script.default;
/** add application teardown to current render effect teardown */
subscription.add(render(el, { fusion, env: { basename, config, manifest } }));
/** remove app element when application unmounts */
subscription.add(() => el.remove());
},
complete: () => {
/** flag that application is no longer loading */
setLoading(false);
},
error: (err) => {
/** set error if initialization of application fails */
setError(err);
},
}));
/** teardown application when hook unmounts */
return () => subscription.unsubscribe();
}, [fusion, currentApp]);
if (error) {
if (error.cause instanceof AppManifestError) {
return (_jsxs("div", { children: [_jsx("h2", { children: "\uD83D\uDD25 Failed to load application manifest \uD83E\uDD2C" }), _jsx("h3", { children: error.cause.type }), _jsx(ErrorViewer, { error: error })] }));
}
return (_jsxs("div", { children: [_jsx("h2", { children: "\uD83D\uDD25 Failed to load application \uD83E\uDD2C" }), _jsx(ErrorViewer, { error: error })] }));
}
return (_jsx("section", { id: "application-content", ref: ref, style: { display: 'contents' }, children: loading && _jsx(EquinorLoader, { text: "Loading Application" }) }));
};
export default AppLoader;
//# sourceMappingURL=AppLoader.js.map