@equinor/fusion-framework-react-app 9.0.8 → 10.0.0
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 +85 -14
- package/README.md +176 -99
- package/dist/esm/ag-grid/useTheme.js +7 -0
- package/dist/esm/ag-grid/useTheme.js.map +1 -1
- package/dist/esm/analytics/index.js +8 -0
- package/dist/esm/analytics/index.js.map +1 -1
- package/dist/esm/analytics/useTrackFeature.js +17 -1
- package/dist/esm/analytics/useTrackFeature.js.map +1 -1
- package/dist/esm/apploader/Apploader.js +1 -1
- package/dist/esm/apploader/Apploader.js.map +1 -1
- package/dist/esm/apploader/index.js +8 -0
- package/dist/esm/apploader/index.js.map +1 -1
- package/dist/esm/bookmark/index.js +8 -0
- package/dist/esm/bookmark/index.js.map +1 -1
- package/dist/esm/context/index.js +8 -0
- package/dist/esm/context/index.js.map +1 -1
- package/dist/esm/context/useContextProvider.js +6 -0
- package/dist/esm/context/useContextProvider.js.map +1 -1
- package/dist/esm/context/useCurrentContext.js +14 -0
- package/dist/esm/context/useCurrentContext.js.map +1 -1
- package/dist/esm/create-legacy-app.js +13 -0
- package/dist/esm/create-legacy-app.js.map +1 -1
- package/dist/esm/feature-flag/index.js.map +1 -1
- package/dist/esm/feature-flag/useFeature.js +20 -4
- package/dist/esm/feature-flag/useFeature.js.map +1 -1
- package/dist/esm/framework/index.js +8 -1
- package/dist/esm/framework/index.js.map +1 -1
- package/dist/esm/framework/useFrameworkCurrentContext.js +9 -0
- package/dist/esm/framework/useFrameworkCurrentContext.js.map +1 -1
- package/dist/esm/help-center/useHelpCenter.js +12 -1
- package/dist/esm/help-center/useHelpCenter.js.map +1 -1
- package/dist/esm/http/index.js +9 -0
- package/dist/esm/http/index.js.map +1 -1
- package/dist/esm/http/selectors.js +10 -0
- package/dist/esm/http/selectors.js.map +1 -0
- package/dist/esm/index.js +16 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/make-component.js +1 -1
- package/dist/esm/make-component.js.map +1 -1
- package/dist/esm/msal/index.js +13 -0
- package/dist/esm/msal/index.js.map +1 -1
- package/dist/esm/msal/useAccessToken.js +15 -3
- package/dist/esm/msal/useAccessToken.js.map +1 -1
- package/dist/esm/msal/useCurrentAccount.js +12 -2
- package/dist/esm/msal/useCurrentAccount.js.map +1 -1
- package/dist/esm/msal/useToken.js +19 -3
- package/dist/esm/msal/useToken.js.map +1 -1
- package/dist/esm/navigation/index.js +8 -0
- package/dist/esm/navigation/index.js.map +1 -1
- package/dist/esm/navigation/useNavigationModule.js +6 -1
- package/dist/esm/navigation/useNavigationModule.js.map +1 -1
- package/dist/esm/navigation/useRouter.js +23 -4
- package/dist/esm/navigation/useRouter.js.map +1 -1
- package/dist/esm/render-app.js +22 -1
- package/dist/esm/render-app.js.map +1 -1
- package/dist/esm/render-component.js +30 -23
- package/dist/esm/render-component.js.map +1 -1
- package/dist/esm/settings/index.js +8 -0
- package/dist/esm/settings/index.js.map +1 -1
- package/dist/esm/useAppModule.js +13 -5
- package/dist/esm/useAppModule.js.map +1 -1
- package/dist/esm/useAppModules.js +9 -3
- package/dist/esm/useAppModules.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/ag-grid/useTheme.d.ts +7 -0
- package/dist/types/analytics/index.d.ts +8 -0
- package/dist/types/analytics/useTrackFeature.d.ts +17 -1
- package/dist/types/apploader/Apploader.d.ts +3 -2
- package/dist/types/apploader/index.d.ts +8 -0
- package/dist/types/bookmark/index.d.ts +8 -0
- package/dist/types/context/index.d.ts +8 -0
- package/dist/types/context/useContextProvider.d.ts +6 -0
- package/dist/types/context/useCurrentContext.d.ts +14 -0
- package/dist/types/create-legacy-app.d.ts +13 -0
- package/dist/types/feature-flag/index.d.ts +8 -0
- package/dist/types/feature-flag/useFeature.d.ts +20 -4
- package/dist/types/framework/index.d.ts +8 -0
- package/dist/types/framework/useFrameworkCurrentContext.d.ts +9 -0
- package/dist/types/help-center/useHelpCenter.d.ts +12 -1
- package/dist/types/http/index.d.ts +9 -0
- package/dist/types/http/selectors.d.ts +9 -0
- package/dist/types/index.d.ts +18 -1
- package/dist/types/make-component.d.ts +15 -0
- package/dist/types/msal/index.d.ts +13 -0
- package/dist/types/msal/useAccessToken.d.ts +15 -3
- package/dist/types/msal/useCurrentAccount.d.ts +12 -2
- package/dist/types/msal/useToken.d.ts +19 -3
- package/dist/types/navigation/index.d.ts +8 -0
- package/dist/types/navigation/useNavigationModule.d.ts +6 -1
- package/dist/types/navigation/useRouter.d.ts +23 -4
- package/dist/types/render-app.d.ts +22 -1
- package/dist/types/render-component.d.ts +16 -1
- package/dist/types/settings/index.d.ts +8 -0
- package/dist/types/useAppModule.d.ts +13 -5
- package/dist/types/useAppModules.d.ts +9 -3
- package/dist/types/version.d.ts +1 -1
- package/package.json +35 -27
- package/src/__tests__/render-app.test.tsx +113 -0
- package/src/ag-grid/useTheme.ts +7 -0
- package/src/analytics/index.ts +8 -0
- package/src/analytics/useTrackFeature.ts +17 -1
- package/src/apploader/Apploader.tsx +3 -3
- package/src/apploader/index.ts +8 -0
- package/src/bookmark/index.ts +8 -0
- package/src/context/index.ts +8 -0
- package/src/context/useContextProvider.ts +6 -0
- package/src/context/useCurrentContext.ts +14 -0
- package/src/create-legacy-app.tsx +13 -0
- package/src/feature-flag/index.ts +8 -0
- package/src/feature-flag/useFeature.ts +20 -4
- package/src/framework/index.ts +8 -1
- package/src/framework/useFrameworkCurrentContext.ts +9 -0
- package/src/help-center/useHelpCenter.ts +12 -1
- package/src/http/index.ts +9 -0
- package/src/http/selectors.ts +9 -0
- package/src/index.ts +20 -2
- package/src/make-component.tsx +16 -1
- package/src/msal/index.ts +13 -0
- package/src/msal/useAccessToken.ts +15 -3
- package/src/msal/useCurrentAccount.ts +12 -2
- package/src/msal/useToken.ts +19 -3
- package/src/navigation/index.ts +8 -0
- package/src/navigation/useNavigationModule.ts +6 -1
- package/src/navigation/useRouter.ts +23 -4
- package/src/render-app.ts +22 -1
- package/src/render-component.tsx +36 -27
- package/src/settings/index.ts +8 -0
- package/src/useAppModule.ts +13 -5
- package/src/useAppModules.ts +11 -5
- package/src/version.ts +1 -1
- package/tsconfig.json +1 -1
- package/vitest.config.ts +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/fusion-framework-react-app",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -41,6 +41,10 @@
|
|
|
41
41
|
"types": "./dist/types/http/index.d.ts",
|
|
42
42
|
"import": "./dist/esm/http/index.js"
|
|
43
43
|
},
|
|
44
|
+
"./http/selectors": {
|
|
45
|
+
"types": "./dist/types/http/selectors.d.ts",
|
|
46
|
+
"import": "./dist/esm/http/selectors.js"
|
|
47
|
+
},
|
|
44
48
|
"./msal": {
|
|
45
49
|
"types": "./dist/types/msal/index.d.ts",
|
|
46
50
|
"import": "./dist/esm/msal/index.js"
|
|
@@ -113,36 +117,39 @@
|
|
|
113
117
|
"directory": "packages/react"
|
|
114
118
|
},
|
|
115
119
|
"dependencies": {
|
|
116
|
-
"@equinor/fusion-framework-app": "
|
|
117
|
-
"@equinor/fusion-framework-module": "
|
|
118
|
-
"@equinor/fusion-framework-module
|
|
119
|
-
"@equinor/fusion-framework-
|
|
120
|
-
"@equinor/fusion-framework-
|
|
121
|
-
"@equinor/fusion-framework-react-module": "
|
|
122
|
-
"@equinor/fusion-framework-react-module-http": "
|
|
120
|
+
"@equinor/fusion-framework-app": "11.0.0",
|
|
121
|
+
"@equinor/fusion-framework-module-app": "8.0.0",
|
|
122
|
+
"@equinor/fusion-framework-module": "6.0.0",
|
|
123
|
+
"@equinor/fusion-framework-react": "8.0.0",
|
|
124
|
+
"@equinor/fusion-framework-module-http": "8.0.0",
|
|
125
|
+
"@equinor/fusion-framework-react-module": "4.0.0",
|
|
126
|
+
"@equinor/fusion-framework-react-module-http": "11.0.0",
|
|
127
|
+
"@equinor/fusion-framework-module-navigation": "7.0.0"
|
|
123
128
|
},
|
|
124
129
|
"devDependencies": {
|
|
125
|
-
"@types/react": "^
|
|
126
|
-
"@types/react-dom": "^
|
|
127
|
-
"
|
|
128
|
-
"react
|
|
130
|
+
"@types/react": "^19.2.7",
|
|
131
|
+
"@types/react-dom": "^19.2.3",
|
|
132
|
+
"happy-dom": "^20.8.4",
|
|
133
|
+
"react": "^19.2.1",
|
|
134
|
+
"react-dom": "^19.2.1",
|
|
129
135
|
"rxjs": "^7.8.1",
|
|
130
|
-
"typescript": "^5.
|
|
131
|
-
"
|
|
132
|
-
"@equinor/fusion-framework-module-
|
|
133
|
-
"@equinor/fusion-framework-module-
|
|
134
|
-
"@equinor/fusion-framework-module-
|
|
135
|
-
"@equinor/fusion-framework-
|
|
136
|
-
"@equinor/fusion-framework-module-msal": "
|
|
137
|
-
"@equinor/fusion-framework-react-module-context": "
|
|
138
|
-
"@equinor/fusion-observable": "
|
|
136
|
+
"typescript": "^5.9.3",
|
|
137
|
+
"vitest": "^4.1.0",
|
|
138
|
+
"@equinor/fusion-framework-module-ag-grid": "36.0.0",
|
|
139
|
+
"@equinor/fusion-framework-module-event": "6.0.0",
|
|
140
|
+
"@equinor/fusion-framework-module-analytics": "2.0.0",
|
|
141
|
+
"@equinor/fusion-framework-module-feature-flag": "2.0.0",
|
|
142
|
+
"@equinor/fusion-framework-module-msal": "8.0.0",
|
|
143
|
+
"@equinor/fusion-framework-react-module-context": "7.0.0",
|
|
144
|
+
"@equinor/fusion-observable": "9.0.0",
|
|
145
|
+
"@equinor/fusion-framework-react-module-bookmark": "6.0.0"
|
|
139
146
|
},
|
|
140
147
|
"peerDependencies": {
|
|
141
|
-
"@types/react": "^
|
|
142
|
-
"react": "^
|
|
143
|
-
"react-dom": "^
|
|
144
|
-
"rxjs": "^7.
|
|
145
|
-
"@equinor/fusion-framework-module-msal": "^
|
|
148
|
+
"@types/react": "^18.0.0 || ^19.0.0",
|
|
149
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
150
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
151
|
+
"rxjs": "^7.0.0",
|
|
152
|
+
"@equinor/fusion-framework-module-msal": "^8.0.0"
|
|
146
153
|
},
|
|
147
154
|
"peerDependenciesMeta": {
|
|
148
155
|
"@equinor/fusion-framework-react-module-ag-grid": {
|
|
@@ -174,6 +181,7 @@
|
|
|
174
181
|
}
|
|
175
182
|
},
|
|
176
183
|
"scripts": {
|
|
177
|
-
"build": "tsc -b"
|
|
184
|
+
"build": "tsc -b",
|
|
185
|
+
"test": "vitest --run"
|
|
178
186
|
}
|
|
179
187
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import type { ComponentRenderArgs } from '../create-component';
|
|
3
|
+
import type { Fusion } from '@equinor/fusion-framework-react';
|
|
4
|
+
import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
5
|
+
|
|
6
|
+
// Mock dependencies before importing
|
|
7
|
+
vi.mock('../create-component', () => ({
|
|
8
|
+
createComponent: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
vi.mock('../render-component', () => ({
|
|
12
|
+
renderComponent: vi.fn(),
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
import { renderApp } from '../render-app';
|
|
16
|
+
import { createComponent } from '../create-component';
|
|
17
|
+
import { renderComponent } from '../render-component';
|
|
18
|
+
|
|
19
|
+
describe('renderApp', () => {
|
|
20
|
+
let mockFusion: Fusion;
|
|
21
|
+
let mockEnv: AppEnv;
|
|
22
|
+
let mockElement: HTMLElement;
|
|
23
|
+
let mockTeardown: () => void;
|
|
24
|
+
let mockComponentRenderer: ReturnType<typeof createComponent>;
|
|
25
|
+
let mockRenderFunction: ReturnType<typeof renderComponent>;
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
// Setup mock data
|
|
29
|
+
mockFusion = {} as Fusion;
|
|
30
|
+
mockEnv = {} as AppEnv;
|
|
31
|
+
mockElement = document.createElement('div');
|
|
32
|
+
mockTeardown = vi.fn();
|
|
33
|
+
|
|
34
|
+
// Create a mock component renderer
|
|
35
|
+
// createComponent returns a ComponentRenderer function: (fusion, env) => React.LazyExoticComponent
|
|
36
|
+
mockComponentRenderer = vi.fn() as unknown as ReturnType<typeof createComponent>;
|
|
37
|
+
|
|
38
|
+
// Create a mock render function
|
|
39
|
+
mockRenderFunction = vi.fn(() => mockTeardown) as unknown as ReturnType<typeof renderComponent>;
|
|
40
|
+
|
|
41
|
+
// Mock renderComponent to return our mock render function
|
|
42
|
+
vi.mocked(renderComponent).mockReturnValue(mockRenderFunction);
|
|
43
|
+
|
|
44
|
+
// Mock createComponent to return our mock component renderer
|
|
45
|
+
vi.mocked(createComponent).mockReturnValue(mockComponentRenderer);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should create a render function that calls createComponent with provided arguments', () => {
|
|
49
|
+
const TestComponent = () => <div>Test</div>;
|
|
50
|
+
const mockConfigure = vi.fn();
|
|
51
|
+
|
|
52
|
+
renderApp(TestComponent, mockConfigure);
|
|
53
|
+
|
|
54
|
+
expect(createComponent).toHaveBeenCalledWith(TestComponent, mockConfigure);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should create a render function that uses renderComponent with the component renderer', () => {
|
|
58
|
+
const TestComponent = () => <div>Test</div>;
|
|
59
|
+
const appRender = renderApp(TestComponent);
|
|
60
|
+
|
|
61
|
+
// Call the render function
|
|
62
|
+
const teardown = appRender(mockElement, { fusion: mockFusion, env: mockEnv });
|
|
63
|
+
|
|
64
|
+
expect(renderComponent).toHaveBeenCalledWith(mockComponentRenderer);
|
|
65
|
+
expect(mockRenderFunction).toHaveBeenCalledWith(mockElement, {
|
|
66
|
+
fusion: mockFusion,
|
|
67
|
+
env: mockEnv,
|
|
68
|
+
});
|
|
69
|
+
expect(teardown).toBe(mockTeardown);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should return a teardown function that unmounts the component', () => {
|
|
73
|
+
const TestComponent = () => <div>Test</div>;
|
|
74
|
+
const appRender = renderApp(TestComponent);
|
|
75
|
+
|
|
76
|
+
const teardown = appRender(mockElement, { fusion: mockFusion, env: mockEnv });
|
|
77
|
+
|
|
78
|
+
expect(typeof teardown).toBe('function');
|
|
79
|
+
teardown();
|
|
80
|
+
expect(mockTeardown).toHaveBeenCalled();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should work without a configure callback', () => {
|
|
84
|
+
vi.clearAllMocks();
|
|
85
|
+
const TestComponent = () => <div>Test</div>;
|
|
86
|
+
const appRender = renderApp(TestComponent);
|
|
87
|
+
|
|
88
|
+
// When no configure callback is provided, it may be called with just the component
|
|
89
|
+
// or with undefined as the second parameter
|
|
90
|
+
expect(createComponent).toHaveBeenCalled();
|
|
91
|
+
const calls = vi.mocked(createComponent).mock.calls;
|
|
92
|
+
expect(calls[calls.length - 1][0]).toBe(TestComponent);
|
|
93
|
+
expect(calls[calls.length - 1][1]).toBeUndefined();
|
|
94
|
+
|
|
95
|
+
const teardown = appRender(mockElement, { fusion: mockFusion, env: mockEnv });
|
|
96
|
+
|
|
97
|
+
expect(teardown).toBe(mockTeardown);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should pass component renderer args correctly to renderComponent', () => {
|
|
101
|
+
const TestComponent = () => <div>Test</div>;
|
|
102
|
+
const appRender = renderApp(TestComponent);
|
|
103
|
+
|
|
104
|
+
const args: ComponentRenderArgs = {
|
|
105
|
+
fusion: mockFusion,
|
|
106
|
+
env: mockEnv,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
appRender(mockElement, args);
|
|
110
|
+
|
|
111
|
+
expect(mockRenderFunction).toHaveBeenCalledWith(mockElement, args);
|
|
112
|
+
});
|
|
113
|
+
});
|
package/src/ag-grid/useTheme.ts
CHANGED
|
@@ -2,6 +2,13 @@ import { useAppModule } from '../useAppModule';
|
|
|
2
2
|
import type { AgGridModule } from '@equinor/fusion-framework-module-ag-grid';
|
|
3
3
|
import type { Theme } from '@equinor/fusion-framework-module-ag-grid/themes';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* React hook that returns the current AG Grid theme from the application-scoped
|
|
7
|
+
* AG Grid module.
|
|
8
|
+
*
|
|
9
|
+
* @returns The active {@link Theme} object.
|
|
10
|
+
* @throws If the AG Grid module is not registered in the application.
|
|
11
|
+
*/
|
|
5
12
|
export const useTheme = (): Theme => {
|
|
6
13
|
const agGrid = useAppModule<AgGridModule>('agGrid');
|
|
7
14
|
|
package/src/analytics/index.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics sub-path entry-point.
|
|
3
|
+
*
|
|
4
|
+
* Provides the {@link useTrackFeature} hook for tracking application-level
|
|
5
|
+
* analytics events through the Fusion analytics module.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
1
9
|
export { useTrackFeature } from './useTrackFeature';
|
|
@@ -4,7 +4,23 @@ import type { AnalyticsModule, AnyValueMap } from '@equinor/fusion-framework-mod
|
|
|
4
4
|
import { useCallback } from 'react';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* React hook that returns a callback for tracking application feature usage
|
|
8
|
+
* via the Fusion analytics module.
|
|
9
|
+
*
|
|
10
|
+
* The tracked event includes the current app key and context (if available)
|
|
11
|
+
* as attributes, enabling downstream analytics dashboards to group events
|
|
12
|
+
* by application and context.
|
|
13
|
+
*
|
|
14
|
+
* @returns A `trackFeature` callback: `(name: string, data?: AnyValueMap) => void`.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* const trackFeature = useTrackFeature();
|
|
19
|
+
*
|
|
20
|
+
* const handleClick = useCallback(() => {
|
|
21
|
+
* trackFeature('button-click', { section: 'header' });
|
|
22
|
+
* }, [trackFeature]);
|
|
23
|
+
* ```
|
|
8
24
|
*/
|
|
9
25
|
export const useTrackFeature = () => {
|
|
10
26
|
const analyticsProvider = useFrameworkModule<AnalyticsModule>('analytics');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useRef } from 'react';
|
|
1
|
+
import { useEffect, useRef, type ReactElement } from 'react';
|
|
2
2
|
import { useApploader } from './useApploader';
|
|
3
3
|
|
|
4
4
|
export type ApploaderProps = {
|
|
@@ -13,12 +13,12 @@ export type ApploaderProps = {
|
|
|
13
13
|
*
|
|
14
14
|
* @param { ApploaderProps } props - The props for the component.
|
|
15
15
|
* @param { string } props.appKey - The key of the Fusion app to load and mount.
|
|
16
|
-
* @returns {
|
|
16
|
+
* @returns { ReactElement } The rendered component, which displays loading, error, or the embedded app.
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
19
|
* <Apploader appKey="my-app" />
|
|
20
20
|
*/
|
|
21
|
-
export const Apploader = ({ appKey }: ApploaderProps):
|
|
21
|
+
export const Apploader = ({ appKey }: ApploaderProps): ReactElement => {
|
|
22
22
|
const refWrapp = useRef<HTMLDivElement | null>(null);
|
|
23
23
|
const { loading, error, appRef } = useApploader({ appKey });
|
|
24
24
|
|
package/src/apploader/index.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apploader sub-path entry-point.
|
|
3
|
+
*
|
|
4
|
+
* Provides the {@link Apploader} component and {@link useApploader} hook
|
|
5
|
+
* for embedding Fusion child applications inside a parent Fusion application.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
1
9
|
export { Apploader, type ApploaderProps } from './Apploader';
|
|
2
10
|
export { useApploader } from './useApploader';
|
package/src/bookmark/index.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bookmark sub-path entry-point.
|
|
3
|
+
*
|
|
4
|
+
* Provides helpers to enable and consume the Fusion bookmark module,
|
|
5
|
+
* allowing users to save and restore application state snapshots.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
1
9
|
export { enableBookmark } from '@equinor/fusion-framework-app/enable-bookmark';
|
|
2
10
|
|
|
3
11
|
export { useCurrentBookmark } from './useCurrentBookmark';
|
package/src/context/index.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context sub-path entry-point.
|
|
3
|
+
*
|
|
4
|
+
* Provides hooks for reading and interacting with the Fusion context
|
|
5
|
+
* (project, facility, etc.) at both the application and framework level.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
1
9
|
export * from '@equinor/fusion-framework-react-module-context';
|
|
2
10
|
|
|
3
11
|
export { useContextProvider } from './useContextProvider';
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { ContextModule } from '@equinor/fusion-framework-react-module-context';
|
|
2
2
|
import { useAppModule } from '../useAppModule';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* React hook that resolves the application-scoped context module provider.
|
|
6
|
+
*
|
|
7
|
+
* @returns The context module provider instance.
|
|
8
|
+
* @throws If the context module is not registered in the application scope.
|
|
9
|
+
*/
|
|
4
10
|
export const useContextProvider = () => useAppModule<ContextModule>('context');
|
|
5
11
|
|
|
6
12
|
export default useContextProvider;
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { useCurrentContext as _useCurrentContext } from '@equinor/fusion-framework-react-module-context';
|
|
2
2
|
import useContextProvider from './useContextProvider';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* React hook that returns the currently selected Fusion context from the
|
|
6
|
+
* **application-scoped** context module.
|
|
7
|
+
*
|
|
8
|
+
* @returns The current context object, or `undefined` if no context is selected.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* const context = useCurrentContext();
|
|
13
|
+
* if (context) {
|
|
14
|
+
* console.log('Selected:', context.title);
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
4
18
|
export const useCurrentContext = () => _useCurrentContext(useContextProvider());
|
|
5
19
|
|
|
6
20
|
export default useCurrentContext;
|
|
@@ -8,6 +8,19 @@ import type { AppEnv, AppModuleInitiator } from '@equinor/fusion-framework-app';
|
|
|
8
8
|
import { createComponent } from './create-component';
|
|
9
9
|
import type { AppModule } from '@equinor/fusion-framework-module-app';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Creates a legacy wrapper component that bootstraps a Fusion React app within
|
|
13
|
+
* the older Fusion CLI hosting model.
|
|
14
|
+
*
|
|
15
|
+
* @deprecated Prefer {@link renderApp} for new applications. This helper exists
|
|
16
|
+
* only for backward-compatibility with apps that must run inside the legacy
|
|
17
|
+
* Fusion CLI.
|
|
18
|
+
*
|
|
19
|
+
* @template TModules - Array of additional module types to initialise.
|
|
20
|
+
* @param Component - The root React element to render.
|
|
21
|
+
* @param configure - Optional callback to configure application modules.
|
|
22
|
+
* @returns A React function component that initialises modules and renders the app.
|
|
23
|
+
*/
|
|
11
24
|
export const createLegacyApp = <TModules extends Array<AnyModule>>(
|
|
12
25
|
Component: ElementType,
|
|
13
26
|
configure?: AppModuleInitiator<TModules>,
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature-flag sub-path entry-point.
|
|
3
|
+
*
|
|
4
|
+
* Provides the {@link enableFeatureFlag} configurator helper and the
|
|
5
|
+
* {@link useFeature} hook for reading and toggling feature flags at runtime.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
1
9
|
export {
|
|
2
10
|
IFeatureFlag,
|
|
3
11
|
IFeatureFlagProvider,
|
|
@@ -13,10 +13,26 @@ import { findFeature } from '@equinor/fusion-framework-module-feature-flag/selec
|
|
|
13
13
|
import { useAppModule } from '../useAppModule';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* React hook for reading and toggling a single feature flag.
|
|
17
|
+
*
|
|
18
|
+
* Merges feature flags from both the framework and the application scope,
|
|
19
|
+
* so framework-level flags are visible alongside app-specific ones.
|
|
20
|
+
*
|
|
21
|
+
* @template T - The type of the feature flag's value payload.
|
|
22
|
+
* @param key - The unique key identifying the feature flag.
|
|
23
|
+
* @returns An object with:
|
|
24
|
+
* - `feature` – the resolved {@link IFeatureFlag}, or `undefined` if not found.
|
|
25
|
+
* - `toggleFeature` – callback to toggle the flag; pass `true`/`false` to
|
|
26
|
+
* set explicitly, or omit to invert the current state.
|
|
27
|
+
* - `error` – any error from the feature-flag observable.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* const { feature, toggleFeature } = useFeature('dark-mode');
|
|
32
|
+
* return (
|
|
33
|
+
* <Switch checked={feature?.enabled} onChange={() => toggleFeature()} />
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
20
36
|
*/
|
|
21
37
|
export const useFeature = <T = unknown>(
|
|
22
38
|
key: string,
|
package/src/framework/index.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework sub-path entry-point.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports framework-level hooks (as opposed to application-scoped ones)
|
|
5
|
+
* for accessing the Fusion instance, current user, and HTTP clients.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
1
9
|
export { useFramework } from '@equinor/fusion-framework-react';
|
|
2
10
|
|
|
3
|
-
// TODO
|
|
4
11
|
export {
|
|
5
12
|
useCurrentUser,
|
|
6
13
|
useHttpClient as useFrameworkHttpClient,
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { useFramework } from '@equinor/fusion-framework-react';
|
|
2
2
|
import { useCurrentContext } from '@equinor/fusion-framework-react-module-context';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* React hook that returns the currently selected context from the
|
|
6
|
+
* **framework-level** context module (as opposed to the application-scoped one).
|
|
7
|
+
*
|
|
8
|
+
* Use this when you need the portal/host context rather than the app's own
|
|
9
|
+
* context provider.
|
|
10
|
+
*
|
|
11
|
+
* @returns The current framework context, or `undefined` if none is selected.
|
|
12
|
+
*/
|
|
4
13
|
export const useFrameworkCurrentContext = () => useCurrentContext(useFramework().modules.context);
|
|
5
14
|
|
|
6
15
|
export default useFrameworkCurrentContext;
|
|
@@ -77,7 +77,18 @@ export interface HelpCenter {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
|
-
*
|
|
80
|
+
* React hook that returns an API for opening the portal help-center sidesheet.
|
|
81
|
+
*
|
|
82
|
+
* Each method dispatches a framework event that the portal shell listens for
|
|
83
|
+
* and opens the corresponding help page.
|
|
84
|
+
*
|
|
85
|
+
* @returns A {@link HelpCenter} object with methods to open specific help pages.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```tsx
|
|
89
|
+
* const helpCenter = useHelpCenter();
|
|
90
|
+
* <Button onClick={() => helpCenter.openFaqs()}>FAQs</Button>
|
|
91
|
+
* ```
|
|
81
92
|
*/
|
|
82
93
|
export const useHelpCenter = (): HelpCenter => {
|
|
83
94
|
const eventModule = useAppModule('event');
|
package/src/http/index.ts
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP sub-path entry-point.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports hooks from `@equinor/fusion-framework-react-module-http`,
|
|
5
|
+
* including {@link useHttpClient} for making authenticated HTTP requests
|
|
6
|
+
* from within a Fusion application.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
1
10
|
export * from '@equinor/fusion-framework-react-module-http';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP selector utilities.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports response-selector helpers (e.g. JSON, blob, text selectors)
|
|
5
|
+
* from `@equinor/fusion-framework-module-http/selectors`.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
export * from '@equinor/fusion-framework-module-http/selectors';
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* React bindings for building Fusion Framework applications.
|
|
5
|
+
*
|
|
6
|
+
* Provides the main entry-point helpers (`renderApp`, `createComponent`, `makeComponent`)
|
|
7
|
+
* plus React hooks for accessing framework modules (HTTP, auth, context, navigation, etc.)
|
|
8
|
+
* from within a Fusion app.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* This is the primary package application developers depend on when building
|
|
12
|
+
* React-based Fusion apps. It re-exports core types from `@equinor/fusion-framework-app`
|
|
13
|
+
* and adds React-specific rendering, hooks, and sub-path entry-points for optional
|
|
14
|
+
* modules such as MSAL, feature flags, bookmarks, analytics, and settings.
|
|
15
|
+
*/
|
|
16
|
+
|
|
1
17
|
export type {
|
|
2
18
|
AppConfig,
|
|
3
19
|
AppEnv,
|
|
@@ -8,6 +24,8 @@ export type {
|
|
|
8
24
|
IAppConfigurator,
|
|
9
25
|
} from '@equinor/fusion-framework-app';
|
|
10
26
|
|
|
27
|
+
export type { Fusion } from '@equinor/fusion-framework-react';
|
|
28
|
+
|
|
11
29
|
export { AppManifest } from '@equinor/fusion-framework-module-app';
|
|
12
30
|
|
|
13
31
|
export { useAppModule } from './useAppModule';
|
|
@@ -18,11 +36,11 @@ export { makeComponent, ComponentRenderArgs } from './make-component';
|
|
|
18
36
|
|
|
19
37
|
export { createLegacyApp } from './create-legacy-app';
|
|
20
38
|
|
|
21
|
-
// TODO deprecate
|
|
22
|
-
export { renderApp } from './render-app';
|
|
23
39
|
export { createComponent } from './create-component';
|
|
40
|
+
export { renderApp } from './render-app';
|
|
24
41
|
export { renderComponent } from './render-component';
|
|
25
42
|
|
|
26
43
|
export type { ComponentRenderer } from './create-component';
|
|
44
|
+
export type { RenderTeardown } from './render-component';
|
|
27
45
|
|
|
28
46
|
export { default } from './render-app';
|
package/src/make-component.tsx
CHANGED
|
@@ -13,11 +13,26 @@ import type { FrameworkEvent, FrameworkEventInit } from '@equinor/fusion-framewo
|
|
|
13
13
|
|
|
14
14
|
import { ModuleProvider as AppModuleProvider } from '@equinor/fusion-framework-react-module';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Arguments supplied when rendering a Fusion app component.
|
|
18
|
+
*
|
|
19
|
+
* @template TFusion - The Fusion framework instance type.
|
|
20
|
+
* @template TEnv - The application environment type.
|
|
21
|
+
*/
|
|
16
22
|
export type ComponentRenderArgs<TFusion extends Fusion = Fusion, TEnv = AppEnv> = {
|
|
23
|
+
/** The Fusion framework instance. */
|
|
17
24
|
fusion: TFusion;
|
|
25
|
+
/** The application environment (manifest, config, basename, etc.). */
|
|
18
26
|
env: TEnv;
|
|
19
27
|
};
|
|
20
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Factory function that receives a Fusion instance and environment and returns a
|
|
31
|
+
* lazy React component ready to be rendered.
|
|
32
|
+
*
|
|
33
|
+
* @template TFusion - The Fusion framework instance type.
|
|
34
|
+
* @template TEnv - The application environment type.
|
|
35
|
+
*/
|
|
21
36
|
export type ComponentRenderer<TFusion extends Fusion = Fusion, TEnv = AppEnv> = (
|
|
22
37
|
fusion: TFusion,
|
|
23
38
|
env: TEnv,
|
|
@@ -55,7 +70,7 @@ export const makeComponent = <
|
|
|
55
70
|
): React.LazyExoticComponent<React.ComponentType> =>
|
|
56
71
|
lazy(async () => {
|
|
57
72
|
const init = configureModules<TModules, TRef, TEnv>(configure);
|
|
58
|
-
const modules =
|
|
73
|
+
const modules = await init(args);
|
|
59
74
|
|
|
60
75
|
const { fusion } = args;
|
|
61
76
|
|
package/src/msal/index.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MSAL authentication sub-path entry-point.
|
|
3
|
+
*
|
|
4
|
+
* Provides React hooks for accessing MSAL-based authentication state
|
|
5
|
+
* (current account, access tokens) from within a Fusion application.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Requires `@equinor/fusion-framework-module-msal` to be installed and
|
|
9
|
+
* configured by the host/portal. Applications should **not** configure the
|
|
10
|
+
* MSAL module themselves.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
1
14
|
export { useCurrentAccount } from './useCurrentAccount';
|
|
2
15
|
export { useAccessToken } from './useAccessToken';
|
|
3
16
|
export { useToken } from './useToken';
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { useToken } from './useToken';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* React hook that acquires an OAuth 2.0 access token string via MSAL.
|
|
5
5
|
*
|
|
6
|
-
* @
|
|
7
|
-
*
|
|
6
|
+
* This is a convenience wrapper around {@link useToken} that extracts the
|
|
7
|
+
* `accessToken` property from the full `AuthenticationResult`.
|
|
8
|
+
*
|
|
9
|
+
* @param req - The token request containing the `scopes` to acquire.
|
|
10
|
+
* @param req.scopes - Array of scope strings (e.g. `['User.Read']`).
|
|
11
|
+
* @returns An object with:
|
|
12
|
+
* - `token` – the access token string, or `undefined` while pending.
|
|
13
|
+
* - `pending` – `true` while the token is being acquired.
|
|
14
|
+
* - `error` – any error encountered during acquisition.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* const { token, pending, error } = useAccessToken({ scopes: ['api://my-api/.default'] });
|
|
19
|
+
* ```
|
|
8
20
|
*/
|
|
9
21
|
export const useAccessToken = (req: {
|
|
10
22
|
scopes: string[];
|
|
@@ -2,8 +2,18 @@ import type { AccountInfo } from '@equinor/fusion-framework-module-msal';
|
|
|
2
2
|
import useAppModule from '../useAppModule';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* React hook that returns the currently signed-in user's MSAL account info.
|
|
6
|
+
*
|
|
7
|
+
* @returns The {@link AccountInfo} for the active account, or `undefined` if
|
|
8
|
+
* no user is signed in.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* const account = useCurrentAccount();
|
|
13
|
+
* if (account) {
|
|
14
|
+
* console.log('Signed in as', account.name);
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
7
17
|
*/
|
|
8
18
|
export const useCurrentAccount = (): AccountInfo | undefined => {
|
|
9
19
|
const msalProvider = useAppModule('auth');
|