@equinor/fusion-framework-react-app 6.1.6-next.0 → 6.2.0-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +96 -5
- package/dist/esm/fusion-apploader/FusionApploader.js +35 -0
- package/dist/esm/fusion-apploader/FusionApploader.js.map +1 -0
- package/dist/esm/fusion-apploader/index.js +3 -0
- package/dist/esm/fusion-apploader/index.js.map +1 -0
- package/dist/esm/fusion-apploader/useFusionApploader.js +89 -0
- package/dist/esm/fusion-apploader/useFusionApploader.js.map +1 -0
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/fusion-apploader/FusionApploader.d.ts +18 -0
- package/dist/types/fusion-apploader/index.d.ts +2 -0
- package/dist/types/fusion-apploader/useFusionApploader.d.ts +33 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +23 -16
- package/src/fusion-apploader/FusionApploader.tsx +47 -0
- package/src/fusion-apploader/README.md +78 -0
- package/src/fusion-apploader/index.ts +2 -0
- package/src/fusion-apploader/useFusionApploader.ts +104 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,105 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## 6.
|
|
3
|
+
## 6.2.0-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#3039](https://github.com/equinor/fusion-framework/pull/3039) [`4c7c39a`](https://github.com/equinor/fusion-framework/commit/4c7c39a75513b2c0f6c630aeb058dc98ff4b21f6) Thanks [@eikeland](https://github.com/eikeland)! - `@equinor/fusion-framework-react-app/fusion-apploader`
|
|
8
|
+
|
|
9
|
+
[FusionApploader](#fusionapploader) component and [useFusionApploader](#usefusionapploader) is intended to be used to embed Fusion applications inside other Fusion application.
|
|
10
|
+
|
|
11
|
+
> [!WARNING] > `FusionApploader` is an experimental poc.
|
|
12
|
+
>
|
|
13
|
+
> The embedded application will likely have issues with routing, context and other framework functionality, so use with care.
|
|
14
|
+
>
|
|
15
|
+
> Should only be used to embed 'simple' applications like **PowerBI** and **PowerApps**.
|
|
16
|
+
|
|
17
|
+
## FusionApploader
|
|
18
|
+
|
|
19
|
+
React component for embeding a Fusion child application inside a parent Fusion application.
|
|
20
|
+
|
|
21
|
+
Handles loading and error states, and mounts the child app's DOM element into a container div.
|
|
22
|
+
|
|
23
|
+
If you need to customise the error and loading messages, then use the hook `useFusionApploader` and create your own component.
|
|
24
|
+
|
|
25
|
+
### Example usage
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
<FusionApploader appKey="my-app" />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## useFusionApploader
|
|
32
|
+
|
|
33
|
+
A React hook for dynamically loading and mounting a Fusion child app inside a parent Fusion app. Handles loading state, error reporting, and provides a reference to the mounted app’s DOM element.
|
|
34
|
+
|
|
35
|
+
### Signature
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
useFusionApploader({ appKey }: { appKey: string }): {
|
|
39
|
+
loading: boolean;
|
|
40
|
+
error: Error | undefined;
|
|
41
|
+
appRef: React.RefObject<HTMLDivElement | null>;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Parameters
|
|
46
|
+
|
|
47
|
+
`appKey (string)`: The key of the Fusion app to load and mount.
|
|
48
|
+
|
|
49
|
+
### Returns
|
|
50
|
+
|
|
51
|
+
- **loading** `(boolean)`: true while the app is loading.
|
|
52
|
+
- **error** `(Error | undefined)`: Error object if loading fails, otherwise undefined.
|
|
53
|
+
- **appRef** `(React.RefObject<HTMLDivElement | null>)`: Ref to the DOM element where the child app is mounted.
|
|
54
|
+
|
|
55
|
+
### Usage Example
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import React, { useEffect, useRef } from "react";
|
|
59
|
+
import { useFusionApploader } from "./useFusionAppLoader";
|
|
60
|
+
|
|
61
|
+
const MyAppLoader = ({ appKey }: { appKey: string }) => {
|
|
62
|
+
const wrapperRef = useRef<HTMLDivElement | null>(null);
|
|
63
|
+
const { loading, error, appRef } = useFusionApploader({ appKey });
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (wrapperRef.current && appRef.current) {
|
|
67
|
+
wrapperRef.current.appendChild(appRef.current);
|
|
68
|
+
}
|
|
69
|
+
}, [appRef.current]);
|
|
70
|
+
|
|
71
|
+
if (loading) return <div>Loading {appKey}...</div>;
|
|
72
|
+
if (error)
|
|
73
|
+
return (
|
|
74
|
+
<div>
|
|
75
|
+
Error loading {appKey}: {error.message}
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return <div ref={wrapperRef} />;
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Notes
|
|
84
|
+
|
|
85
|
+
- The hook is designed to be used in a parent Fusion app context.
|
|
86
|
+
- The returned appRef should be appended to a container element in your component.
|
|
87
|
+
- Handles subscription and cleanup automatically.
|
|
88
|
+
- Useful for micro-frontend scenarios where apps are loaded dynamically.
|
|
4
89
|
|
|
5
90
|
### Patch Changes
|
|
6
91
|
|
|
92
|
+
- pre-release changeset for tag **apploader**, all public packages are patched
|
|
93
|
+
|
|
7
94
|
- Updated dependencies []:
|
|
8
|
-
- @equinor/fusion-framework-app@9.3.15-
|
|
9
|
-
- @equinor/fusion-framework-module-app@6.1.
|
|
10
|
-
- @equinor/fusion-framework-
|
|
11
|
-
- @equinor/fusion-framework-
|
|
95
|
+
- @equinor/fusion-framework-app@9.3.15-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
96
|
+
- @equinor/fusion-framework-module-app@6.1.14-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
97
|
+
- @equinor/fusion-framework-module@4.4.3-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
98
|
+
- @equinor/fusion-framework-module-msal@4.0.7-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
99
|
+
- @equinor/fusion-framework-module-navigation@5.0.3-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
100
|
+
- @equinor/fusion-framework-react@7.4.13-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
101
|
+
- @equinor/fusion-framework-react-module-http@9.0.3-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
102
|
+
- @equinor/fusion-framework-react-module@3.1.13-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9
|
|
12
103
|
|
|
13
104
|
## 6.1.5
|
|
14
105
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { useFusionApploader } from './useFusionApploader';
|
|
4
|
+
/**
|
|
5
|
+
* FusionApploader component
|
|
6
|
+
*
|
|
7
|
+
* Embeds a Fusion child application inside a parent Fusion application.
|
|
8
|
+
* Handles loading and error states, and mounts the child app's DOM element into a container div.
|
|
9
|
+
*
|
|
10
|
+
* @param { FusionApploaderProps } props - The props for the component.
|
|
11
|
+
* @param { string } props.appKey - The key of the Fusion app to load and mount.
|
|
12
|
+
* @returns { JSX.Element } The rendered component, which displays loading, error, or the embedded app.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* <FusionApploader appKey="my-app" />
|
|
16
|
+
*/
|
|
17
|
+
export const FusionApploader = ({ appKey }) => {
|
|
18
|
+
const refWrapp = useRef(null);
|
|
19
|
+
const { loading, error, appRef } = useFusionApploader({ appKey });
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!refWrapp.current || !appRef.current) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
refWrapp.current.appendChild(appRef.current);
|
|
25
|
+
}, [appRef.current]);
|
|
26
|
+
if (loading) {
|
|
27
|
+
return _jsxs("div", { children: ["Loading ", appKey] });
|
|
28
|
+
}
|
|
29
|
+
if (error) {
|
|
30
|
+
return (_jsxs("div", { children: ["Error loading ", appKey, ". Error: ", error.message] }));
|
|
31
|
+
}
|
|
32
|
+
return _jsx("div", { ref: refWrapp });
|
|
33
|
+
};
|
|
34
|
+
export default FusionApploader;
|
|
35
|
+
//# sourceMappingURL=FusionApploader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FusionApploader.js","sourceRoot":"","sources":["../../../src/fusion-apploader/FusionApploader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAM1D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAAE,MAAM,EAAwB,EAAe,EAAE;IAC/E,MAAM,QAAQ,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACrD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAElE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzC,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAErB,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,sCAAc,MAAM,IAAO,CAAC;IACrC,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CACL,4CACiB,MAAM,eAAW,KAAK,CAAC,OAAO,IACzC,CACP,CAAC;IACJ,CAAC;IAED,OAAO,cAAK,GAAG,EAAE,QAAQ,GAAI,CAAC;AAChC,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/fusion-apploader/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAA6B,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { useFramework } from '@equinor/fusion-framework-react';
|
|
3
|
+
/**
|
|
4
|
+
* React hook for dynamically loading and mounting a Fusion child app inside a parent Fusion app.
|
|
5
|
+
* Handles loading state, error reporting, and provides a reference to the mounted app’s DOM element.
|
|
6
|
+
*
|
|
7
|
+
* @param { Object } params
|
|
8
|
+
* @param { string } params.appKey - The key of the Fusion app to load and mount.
|
|
9
|
+
* @returns {{
|
|
10
|
+
* loading: boolean,
|
|
11
|
+
* error: Error | undefined,
|
|
12
|
+
* appRef: React.RefObject<HTMLDivElement | null>
|
|
13
|
+
* }} An object containing loading state, error, and a ref to the mounted app element.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const { loading, error, appRef } = useFusionApploader({ appKey: 'my-app' });
|
|
18
|
+
*
|
|
19
|
+
* useEffect(() => {
|
|
20
|
+
* if (containerRef.current && appRef.current) {
|
|
21
|
+
* containerRef.current.appendChild(appRef.current);
|
|
22
|
+
* }
|
|
23
|
+
* }, [appRef.current]);
|
|
24
|
+
*
|
|
25
|
+
* if (loading) return <div>Loading...</div>;
|
|
26
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
27
|
+
* return <div ref={containerRef} />;
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const useFusionApploader = ({ appKey, }) => {
|
|
31
|
+
const [loading, setLoading] = useState(true);
|
|
32
|
+
const [error, setError] = useState();
|
|
33
|
+
const appRef = useRef(null);
|
|
34
|
+
const fusion = useFramework();
|
|
35
|
+
/**
|
|
36
|
+
* The current fusion app.
|
|
37
|
+
* aka the parent app that is loading the child app.
|
|
38
|
+
*/
|
|
39
|
+
const fusionApp = useMemo(() => fusion.modules.app.current, [fusion]);
|
|
40
|
+
/**
|
|
41
|
+
* The app to be mounted
|
|
42
|
+
* aka the child app that is being loaded.
|
|
43
|
+
*/
|
|
44
|
+
const loadedApp = useMemo(() => fusion.modules.app.createApp({ appKey }), [fusion, appKey]);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
setLoading(true);
|
|
47
|
+
setError(undefined);
|
|
48
|
+
const subscription$ = loadedApp?.initialize().subscribe({
|
|
49
|
+
next: ({ manifest, script, config }) => {
|
|
50
|
+
/* Application Element for mounting */
|
|
51
|
+
appRef.current = document.createElement('div');
|
|
52
|
+
appRef.current.id = manifest.appKey;
|
|
53
|
+
appRef.current.style.display = 'contents';
|
|
54
|
+
/* Use basename of current fusionApp */
|
|
55
|
+
const basename = `/apps/${fusionApp?.appKey}`;
|
|
56
|
+
try {
|
|
57
|
+
const render = script.renderApp ?? script.default;
|
|
58
|
+
if (render) {
|
|
59
|
+
return render(appRef.current, {
|
|
60
|
+
fusion,
|
|
61
|
+
env: { basename, config, manifest, props: {} },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
throw Error('Application is not supported, no render function provided');
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error('App loading Error: ', error);
|
|
68
|
+
setError(error);
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
complete: () => {
|
|
72
|
+
setLoading(false);
|
|
73
|
+
},
|
|
74
|
+
error: (error) => {
|
|
75
|
+
setError(error);
|
|
76
|
+
setLoading(false);
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
return () => {
|
|
80
|
+
subscription$.unsubscribe();
|
|
81
|
+
};
|
|
82
|
+
}, [fusionApp, loadedApp, fusion]);
|
|
83
|
+
return {
|
|
84
|
+
loading,
|
|
85
|
+
error,
|
|
86
|
+
appRef,
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=useFusionApploader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFusionApploader.js","sourceRoot":"","sources":["../../../src/fusion-apploader/useFusionApploader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAK/D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EACjC,MAAM,GACS,EAIf,EAAE;IACF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAqB,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,YAAY,EAAe,CAAC;IAE3C;;;OAGG;IACH,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEtE;;;OAGG;IACH,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAE5F,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,aAAa,GAAG,SAAS,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC;YACtD,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;gBACrC,sCAAsC;gBACtC,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC/C,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC;gBACpC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC;gBAE1C,uCAAuC;gBACvC,MAAM,QAAQ,GAAG,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC;gBAE9C,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC;oBAClD,IAAI,MAAM,EAAE,CAAC;wBACX,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE;4BAC5B,MAAM;4BACN,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;yBAC/C,CAAC,CAAC;oBACL,CAAC;oBACD,MAAM,KAAK,CAAC,2DAA2D,CAAC,CAAC;gBAC3E,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;oBAC5C,QAAQ,CAAC,KAAc,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;gBACb,UAAU,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;YACD,KAAK,EAAE,CAAC,KAAY,EAAE,EAAE;gBACtB,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAChB,UAAU,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;SACF,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,aAAa,CAAC,WAAW,EAAE,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnC,OAAO;QACL,OAAO;QACP,KAAK;QACL,MAAM;KACP,CAAC;AACJ,CAAC,CAAC"}
|
package/dist/esm/version.js
CHANGED
package/dist/esm/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|