@equinor/fusion-framework-react 0.0.0-context-error-20240131144633
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 +1019 -0
- package/LICENSE +21 -0
- package/README.md +44 -0
- package/dist/esm/Framework.js +10 -0
- package/dist/esm/Framework.js.map +1 -0
- package/dist/esm/app/index.js +6 -0
- package/dist/esm/app/index.js.map +1 -0
- package/dist/esm/app/useAppProvider.js +10 -0
- package/dist/esm/app/useAppProvider.js.map +1 -0
- package/dist/esm/app/useApps.js +16 -0
- package/dist/esm/app/useApps.js.map +1 -0
- package/dist/esm/app/useCurrentApp.js +19 -0
- package/dist/esm/app/useCurrentApp.js.map +1 -0
- package/dist/esm/app/useCurrentAppModule.js +11 -0
- package/dist/esm/app/useCurrentAppModule.js.map +1 -0
- package/dist/esm/app/useCurrentAppModules.js +21 -0
- package/dist/esm/app/useCurrentAppModules.js.map +1 -0
- package/dist/esm/context/index.js +3 -0
- package/dist/esm/context/index.js.map +1 -0
- package/dist/esm/context/useCurrentContext.js +5 -0
- package/dist/esm/context/useCurrentContext.js.map +1 -0
- package/dist/esm/context.js +4 -0
- package/dist/esm/context.js.map +1 -0
- package/dist/esm/create-framework-provider.js +24 -0
- package/dist/esm/create-framework-provider.js.map +1 -0
- package/dist/esm/feature-flag/index.js +6 -0
- package/dist/esm/feature-flag/index.js.map +1 -0
- package/dist/esm/feature-flag/useCurrentAppFeatures.js +12 -0
- package/dist/esm/feature-flag/useCurrentAppFeatures.js.map +1 -0
- package/dist/esm/feature-flag/useFeature.js +16 -0
- package/dist/esm/feature-flag/useFeature.js.map +1 -0
- package/dist/esm/feature-flag/useFeatures.js +27 -0
- package/dist/esm/feature-flag/useFeatures.js.map +1 -0
- package/dist/esm/feature-flag/useFrameworkFeature.js +11 -0
- package/dist/esm/feature-flag/useFrameworkFeature.js.map +1 -0
- package/dist/esm/feature-flag/useFrameworkFeatures.js +11 -0
- package/dist/esm/feature-flag/useFrameworkFeatures.js.map +1 -0
- package/dist/esm/hooks/index.js +3 -0
- package/dist/esm/hooks/index.js.map +1 -0
- package/dist/esm/hooks/use-current-user.js +6 -0
- package/dist/esm/hooks/use-current-user.js.map +1 -0
- package/dist/esm/hooks/use-http-client.js +13 -0
- package/dist/esm/hooks/use-http-client.js.map +1 -0
- package/dist/esm/http/index.js +3 -0
- package/dist/esm/http/index.js.map +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/signalr/index.js +10 -0
- package/dist/esm/signalr/index.js.map +1 -0
- package/dist/esm/useFramework.js +15 -0
- package/dist/esm/useFramework.js.map +1 -0
- package/dist/esm/useFrameworkModule.js +10 -0
- package/dist/esm/useFrameworkModule.js.map +1 -0
- package/dist/esm/version.js +2 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/Framework.d.ts +8 -0
- package/dist/types/app/index.d.ts +6 -0
- package/dist/types/app/useAppProvider.d.ts +4 -0
- package/dist/types/app/useApps.d.ts +8 -0
- package/dist/types/app/useCurrentApp.d.ts +9 -0
- package/dist/types/app/useCurrentAppModule.d.ts +8 -0
- package/dist/types/app/useCurrentAppModules.d.ts +8 -0
- package/dist/types/context/index.d.ts +2 -0
- package/dist/types/context/useCurrentContext.d.ts +5 -0
- package/dist/types/context.d.ts +4 -0
- package/dist/types/create-framework-provider.d.ts +4 -0
- package/dist/types/feature-flag/index.d.ts +6 -0
- package/dist/types/feature-flag/useCurrentAppFeatures.d.ts +2 -0
- package/dist/types/feature-flag/useFeature.d.ts +8 -0
- package/dist/types/feature-flag/useFeatures.d.ts +9 -0
- package/dist/types/feature-flag/useFrameworkFeature.d.ts +3 -0
- package/dist/types/feature-flag/useFrameworkFeatures.d.ts +3 -0
- package/dist/types/hooks/index.d.ts +2 -0
- package/dist/types/hooks/use-current-user.d.ts +8 -0
- package/dist/types/hooks/use-http-client.d.ts +5 -0
- package/dist/types/http/index.d.ts +2 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/signalr/index.d.ts +2 -0
- package/dist/types/useFramework.d.ts +4 -0
- package/dist/types/useFrameworkModule.d.ts +3 -0
- package/dist/types/version.d.ts +1 -0
- package/package.json +94 -0
- package/src/Framework.tsx +22 -0
- package/src/app/index.ts +7 -0
- package/src/app/useAppProvider.ts +19 -0
- package/src/app/useApps.ts +30 -0
- package/src/app/useCurrentApp.ts +38 -0
- package/src/app/useCurrentAppModule.ts +43 -0
- package/src/app/useCurrentAppModules.ts +44 -0
- package/src/context/index.ts +3 -0
- package/src/context/useCurrentContext.ts +6 -0
- package/src/context.ts +25 -0
- package/src/create-framework-provider.tsx +42 -0
- package/src/feature-flag/README.md +44 -0
- package/src/feature-flag/index.ts +7 -0
- package/src/feature-flag/useCurrentAppFeatures.ts +19 -0
- package/src/feature-flag/useFeature.ts +47 -0
- package/src/feature-flag/useFeatures.ts +77 -0
- package/src/feature-flag/useFrameworkFeature.ts +22 -0
- package/src/feature-flag/useFrameworkFeatures.ts +20 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/use-current-user.ts +15 -0
- package/src/hooks/use-http-client.ts +19 -0
- package/src/http/index.ts +3 -0
- package/src/index.tsx +15 -0
- package/src/signalr/index.ts +38 -0
- package/src/useFramework.ts +27 -0
- package/src/useFrameworkModule.ts +31 -0
- package/src/version.ts +2 -0
- package/tsconfig.json +41 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AppModules, AppModulesInstance } from '@equinor/fusion-framework-module-app';
|
|
2
|
+
import { ModuleKey, type AnyModule, ModuleTypes, ModuleType } from '@equinor/fusion-framework-module';
|
|
3
|
+
export declare const useCurrentAppModule: <TType extends unknown = unknown, TKey extends string = ModuleKey<ModuleTypes<AppModules<[TType]>>>>(moduleKey: TKey) => {
|
|
4
|
+
module?: (TType extends AnyModule ? ModuleType<TType> : AppModulesInstance[Extract<"event", TKey> | Extract<"http", TKey> | Extract<"auth", TKey> | Extract<"dispose", TKey>]) | null | undefined;
|
|
5
|
+
error?: unknown;
|
|
6
|
+
complete: boolean;
|
|
7
|
+
};
|
|
8
|
+
export default useCurrentAppModule;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AppModulesInstance } from '@equinor/fusion-framework-module-app';
|
|
2
|
+
import { type AnyModule } from '@equinor/fusion-framework-module';
|
|
3
|
+
export declare const useCurrentAppModules: <TModules extends AnyModule[] = []>() => {
|
|
4
|
+
modules: AppModulesInstance<TModules> | null;
|
|
5
|
+
error?: unknown;
|
|
6
|
+
complete: boolean;
|
|
7
|
+
};
|
|
8
|
+
export default useCurrentAppModules;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const useCurrentContext: () => {
|
|
2
|
+
currentContext: import("@equinor/fusion-framework-react-module-context").ContextItem | null | undefined;
|
|
3
|
+
setCurrentContext: (entry?: string | import("@equinor/fusion-framework-react-module-context").ContextItem | null | undefined) => void | Promise<import("@equinor/fusion-framework-react-module-context").ContextItem<Record<string, unknown>> | null>;
|
|
4
|
+
};
|
|
5
|
+
export default useCurrentContext;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FusionConfigurator } from '@equinor/fusion-framework';
|
|
3
|
+
import type { AnyModule } from '@equinor/fusion-framework-module';
|
|
4
|
+
export declare const createFrameworkProvider: <TModules extends AnyModule[] = []>(cb: (configurator: FusionConfigurator<TModules, any>) => void | Promise<void>) => React.LazyExoticComponent<React.FunctionComponent<React.PropsWithChildren<unknown>>>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { useFeature } from './useFeature';
|
|
2
|
+
export { useFeatures } from './useFeatures';
|
|
3
|
+
export { useCurrentAppFeatures } from './useCurrentAppFeatures';
|
|
4
|
+
export { useFrameworkFeature } from './useFrameworkFeature';
|
|
5
|
+
export { useFrameworkFeatures } from './useFrameworkFeatures';
|
|
6
|
+
export { IFeatureFlag, IFeatureFlagProvider } from '@equinor/fusion-framework-module-feature-flag';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type IFeatureFlag, type IFeatureFlagProvider } from '@equinor/fusion-framework-module-feature-flag';
|
|
2
|
+
export interface UseFeatureResult<T> {
|
|
3
|
+
feature?: IFeatureFlag<T>;
|
|
4
|
+
error?: unknown;
|
|
5
|
+
toggleFeature: (enable?: boolean) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const useFeature: <T = unknown>(provider: IFeatureFlagProvider, key: string) => UseFeatureResult<T>;
|
|
8
|
+
export default useFeature;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type IFeatureFlagProvider, type IFeatureFlag } from '@equinor/fusion-framework-module-feature-flag';
|
|
2
|
+
import { type FeatureSelectorFn } from '@equinor/fusion-framework-module-feature-flag/selectors';
|
|
3
|
+
export interface UseFeaturesResult {
|
|
4
|
+
features: IFeatureFlag[];
|
|
5
|
+
error: unknown;
|
|
6
|
+
toggleFeature: (key: string, enable?: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const useFeatures: (provider?: IFeatureFlagProvider | null, selector?: FeatureSelectorFn) => UseFeaturesResult;
|
|
9
|
+
export default useFeatures;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { Fusion } from '@equinor/fusion-framework';
|
|
2
|
+
export { FusionConfigurator } from '@equinor/fusion-framework';
|
|
3
|
+
export { createFrameworkProvider } from './create-framework-provider';
|
|
4
|
+
export { FrameworkProvider } from './context';
|
|
5
|
+
export { useFramework } from './useFramework';
|
|
6
|
+
export { useFrameworkModule } from './useFrameworkModule';
|
|
7
|
+
export { default, Framework } from './Framework';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { FusionModules, FusionModulesInstance } from '@equinor/fusion-framework';
|
|
2
|
+
import { AnyModule, ModuleKey, ModuleType, ModuleTypes } from '@equinor/fusion-framework-module';
|
|
3
|
+
export declare const useFrameworkModule: <TType extends unknown = unknown, TKey extends string = ModuleKey<ModuleTypes<FusionModules<[TType]>>>>(name: TKey) => TType extends AnyModule ? ModuleType<TType> | undefined : FusionModulesInstance[Extract<"context", TKey> | Extract<"event", TKey> | Extract<"http", TKey> | Extract<"auth", TKey> | Extract<"services", TKey> | Extract<"serviceDiscovery", TKey> | Extract<"dispose", TKey>] | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const version = "6.0.0";
|
package/package.json
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@equinor/fusion-framework-react",
|
|
3
|
+
"version": "0.0.0-context-error-20240131144633",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/esm/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist/esm/index.js",
|
|
8
|
+
"./app": "./dist/esm/app/index.js",
|
|
9
|
+
"./feature-flag": "./dist/esm/feature-flag/index.js",
|
|
10
|
+
"./context": "./dist/esm/context/index.js",
|
|
11
|
+
"./hooks": "./dist/esm/hooks/index.js",
|
|
12
|
+
"./http": "./dist/esm/http/index.js",
|
|
13
|
+
"./signalr": "./dist/esm/signalr/index.js"
|
|
14
|
+
},
|
|
15
|
+
"types": "dist/types/index.d.ts",
|
|
16
|
+
"typesVersions": {
|
|
17
|
+
"*": {
|
|
18
|
+
"app": [
|
|
19
|
+
"dist/types/app/index.d.ts"
|
|
20
|
+
],
|
|
21
|
+
"feature-flag": [
|
|
22
|
+
"dist/types/feature-flag/index.d.ts"
|
|
23
|
+
],
|
|
24
|
+
"context": [
|
|
25
|
+
"dist/types/context/index.d.ts"
|
|
26
|
+
],
|
|
27
|
+
"hooks": [
|
|
28
|
+
"dist/types/hooks/index.d.ts"
|
|
29
|
+
],
|
|
30
|
+
"http": [
|
|
31
|
+
"dist/types/http/index.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"signalr": [
|
|
34
|
+
"dist/types/signalr/index.d.ts"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"keywords": [],
|
|
39
|
+
"author": "",
|
|
40
|
+
"license": "ISC",
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/equinor/fusion-framework.git",
|
|
47
|
+
"directory": "packages/react/framework"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"rxjs": "^7.8.1",
|
|
51
|
+
"@equinor/fusion-framework": "^0.0.0-context-error-20240131144633",
|
|
52
|
+
"@equinor/fusion-framework-module": "^4.2.6",
|
|
53
|
+
"@equinor/fusion-framework-react-module": "^3.0.7",
|
|
54
|
+
"@equinor/fusion-framework-react-module-http": "^4.0.5",
|
|
55
|
+
"@equinor/fusion-observable": "^8.1.4"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/react": "^18.2.20",
|
|
59
|
+
"@types/react-dom": "^18.2.7",
|
|
60
|
+
"react": "^18.2.0",
|
|
61
|
+
"react-dom": "^18.2.0",
|
|
62
|
+
"typescript": "^5.1.3",
|
|
63
|
+
"@equinor/fusion-framework-module-app": "^5.2.12",
|
|
64
|
+
"@equinor/fusion-framework-module-feature-flag": "^1.0.0",
|
|
65
|
+
"@equinor/fusion-framework-react-module-context": "^0.0.0-context-error-20240131144633"
|
|
66
|
+
},
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"@types/react": "^17.0.0 || ^18.0.0",
|
|
69
|
+
"react": "^17.0.0 || ^18.0.0",
|
|
70
|
+
"react-dom": "^17.0.0 || ^18.0.0",
|
|
71
|
+
"@equinor/fusion-framework-module-feature-flag": "^1.0.0",
|
|
72
|
+
"@equinor/fusion-framework-react-module-signalr": "^2.0.16"
|
|
73
|
+
},
|
|
74
|
+
"peerDependenciesMeta": {
|
|
75
|
+
"@equinor/fusion-framework-react-module-context": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@equinor/fusion-framework-react-module-signalr": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@equinor/fusion-framework-module-feature-flag": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"@types/react": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"react-dom": {
|
|
88
|
+
"optional": true
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"scripts": {
|
|
92
|
+
"build": "tsc -b"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FusionConfigurator } from '@equinor/fusion-framework';
|
|
2
|
+
import { createFrameworkProvider } from './create-framework-provider';
|
|
3
|
+
import { PropsWithChildren, ReactNode, Suspense, useMemo } from 'react';
|
|
4
|
+
|
|
5
|
+
type ConfigureCallback = (configurator: FusionConfigurator) => void;
|
|
6
|
+
|
|
7
|
+
export const Framework = (
|
|
8
|
+
props: PropsWithChildren<{
|
|
9
|
+
readonly configure: ConfigureCallback;
|
|
10
|
+
readonly fallback: NonNullable<ReactNode> | null;
|
|
11
|
+
}>,
|
|
12
|
+
) => {
|
|
13
|
+
const { configure, fallback, children } = props;
|
|
14
|
+
const Component = useMemo(() => createFrameworkProvider(configure), [configure]);
|
|
15
|
+
return (
|
|
16
|
+
<Suspense fallback={fallback}>
|
|
17
|
+
<Component>{children}</Component>
|
|
18
|
+
</Suspense>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default Framework;
|
package/src/app/index.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { AppConfig, AppManifest, AppType, IApp } from '@equinor/fusion-framework-module-app';
|
|
2
|
+
|
|
3
|
+
export { useCurrentApp } from './useCurrentApp';
|
|
4
|
+
export { useCurrentAppModule } from './useCurrentAppModule';
|
|
5
|
+
export { useCurrentAppModules } from './useCurrentAppModules';
|
|
6
|
+
export { useApps } from './useApps';
|
|
7
|
+
export { useAppProvider } from './useAppProvider';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FusionModulesInstance } from '@equinor/fusion-framework';
|
|
2
|
+
import { AppModule } from '@equinor/fusion-framework-module-app';
|
|
3
|
+
|
|
4
|
+
import { useFramework } from '../useFramework';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* React Hook - get appProvider interface
|
|
8
|
+
* @returns framework AppModule
|
|
9
|
+
*/
|
|
10
|
+
export const useAppProvider = (): FusionModulesInstance<[AppModule]>['app'] => {
|
|
11
|
+
const provider = useFramework<[AppModule]>().modules.app;
|
|
12
|
+
if (!provider) {
|
|
13
|
+
throw Error('Current framework does not have AppModule configured');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return provider;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default useAppProvider;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AppManifest } from '@equinor/fusion-framework-module-app';
|
|
2
|
+
import { useObservableState } from '@equinor/fusion-observable/react';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useAppProvider } from './useAppProvider';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* React Hook - Get apps from framework
|
|
9
|
+
* @param args Object with boolean member includeHidden
|
|
10
|
+
* @returns Object {apps, isLoading} where apps is Array of AppManifest, isLoading is a boolean on observable complete
|
|
11
|
+
*/
|
|
12
|
+
export const useApps = (args?: {
|
|
13
|
+
includeHidden: boolean;
|
|
14
|
+
}): { apps: AppManifest[] | undefined; isLoading: boolean } => {
|
|
15
|
+
const provider = useAppProvider();
|
|
16
|
+
const { value: manifests, complete } = useObservableState(
|
|
17
|
+
useMemo(() => provider.getAllAppManifests(), [provider]),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const apps = useMemo(() => {
|
|
21
|
+
if (manifests && !args?.includeHidden) {
|
|
22
|
+
return manifests.filter((app) => !app.hide);
|
|
23
|
+
}
|
|
24
|
+
return manifests;
|
|
25
|
+
}, [args, manifests]);
|
|
26
|
+
|
|
27
|
+
return { apps, isLoading: !complete };
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default useApps;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useObservableState } from '@equinor/fusion-observable/react';
|
|
4
|
+
|
|
5
|
+
import { type AnyModule } from '@equinor/fusion-framework-module';
|
|
6
|
+
import { type AppModule, type CurrentApp } from '@equinor/fusion-framework-module-app';
|
|
7
|
+
|
|
8
|
+
import { useFramework } from '../useFramework';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Observers the stream of current app and return the latest application
|
|
12
|
+
*
|
|
13
|
+
* __Warning:__ type hint templates are only hints, this does not check if the modules are actually enabled!
|
|
14
|
+
*
|
|
15
|
+
* @template TModule type hint modules which the application has configured
|
|
16
|
+
* @template TEnv type hint what kind of environment config the application has
|
|
17
|
+
*/
|
|
18
|
+
export const useCurrentApp = <TModules extends Array<AnyModule> = [], TEnv = unknown>(): {
|
|
19
|
+
currentApp: CurrentApp<TModules, TEnv>;
|
|
20
|
+
setCurrentApp: (appKey: string) => void;
|
|
21
|
+
clearCurrentApp: () => void;
|
|
22
|
+
error?: unknown;
|
|
23
|
+
} => {
|
|
24
|
+
const provider = useFramework<[AppModule]>().modules.app;
|
|
25
|
+
if (!provider) {
|
|
26
|
+
throw Error('Current framework does not have AppModule configured');
|
|
27
|
+
}
|
|
28
|
+
const currentApp$ = useMemo(() => provider.current$, [provider]);
|
|
29
|
+
const { value, error } = useObservableState(currentApp$);
|
|
30
|
+
return {
|
|
31
|
+
currentApp: value as CurrentApp<TModules, TEnv>,
|
|
32
|
+
setCurrentApp: useMemo(() => provider.setCurrentApp.bind(provider), [provider]),
|
|
33
|
+
clearCurrentApp: useMemo(() => provider.clearCurrentApp.bind(provider), [provider]),
|
|
34
|
+
error,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default useCurrentApp;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AppModules, AppModulesInstance } from '@equinor/fusion-framework-module-app';
|
|
2
|
+
import {
|
|
3
|
+
ModuleKey,
|
|
4
|
+
type AnyModule,
|
|
5
|
+
ModuleTypes,
|
|
6
|
+
ModuleType,
|
|
7
|
+
} from '@equinor/fusion-framework-module';
|
|
8
|
+
import useCurrentAppModules from './useCurrentAppModules';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Retrieves the current app module based on the provided module key.
|
|
12
|
+
* @template TType - The type of the module.
|
|
13
|
+
* @template TKey - The type of the module key.
|
|
14
|
+
* @param {TKey} moduleKey - The key of the module to retrieve.
|
|
15
|
+
* @returns {AnyModule | null | undefined} - The current app module or null if not found.
|
|
16
|
+
* @remarks
|
|
17
|
+
* - when module is null, there are no current selected application
|
|
18
|
+
* - when undefined is, the application has not enabled the requested module
|
|
19
|
+
*/
|
|
20
|
+
export const useCurrentAppModule = <
|
|
21
|
+
TType extends AnyModule | unknown = unknown,
|
|
22
|
+
TKey extends string = ModuleKey<ModuleTypes<AppModules<[TType]>>>,
|
|
23
|
+
>(
|
|
24
|
+
moduleKey: TKey,
|
|
25
|
+
): {
|
|
26
|
+
module?:
|
|
27
|
+
| (TType extends AnyModule
|
|
28
|
+
? ModuleType<TType>
|
|
29
|
+
: AppModulesInstance[Extract<keyof AppModulesInstance, TKey>])
|
|
30
|
+
| null;
|
|
31
|
+
error?: unknown;
|
|
32
|
+
complete: boolean;
|
|
33
|
+
} => {
|
|
34
|
+
const { modules, error, complete } = useCurrentAppModules();
|
|
35
|
+
const module =
|
|
36
|
+
modules === null
|
|
37
|
+
? null
|
|
38
|
+
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
+
(modules[moduleKey as keyof typeof modules] as any);
|
|
40
|
+
return { module, error, complete };
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default useCurrentAppModule;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import useCurrentApp from './useCurrentApp';
|
|
3
|
+
|
|
4
|
+
import { AppModulesInstance } from '@equinor/fusion-framework-module-app';
|
|
5
|
+
import { Observable, of } from 'rxjs';
|
|
6
|
+
import { type AnyModule } from '@equinor/fusion-framework-module';
|
|
7
|
+
import { useObservableState } from '@equinor/fusion-observable/react';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Observers the stream of current app initialized modules
|
|
11
|
+
*
|
|
12
|
+
* __Warning:__ type hint templates are only hints, this does not check if the modules are actually enabled!
|
|
13
|
+
*
|
|
14
|
+
* @template TModule type hint modules which the application has configured
|
|
15
|
+
* @returns the observable instance of initialized modules of the application
|
|
16
|
+
*/
|
|
17
|
+
export const useCurrentAppModules = <TModules extends Array<AnyModule> = []>(): {
|
|
18
|
+
modules: AppModulesInstance<TModules> | null;
|
|
19
|
+
error?: unknown;
|
|
20
|
+
complete: boolean;
|
|
21
|
+
} => {
|
|
22
|
+
const { currentApp, error: appError } = useCurrentApp<TModules>();
|
|
23
|
+
const modules$ = useMemo(
|
|
24
|
+
() =>
|
|
25
|
+
currentApp
|
|
26
|
+
? (currentApp.instance$ as Observable<AppModulesInstance<TModules>>)
|
|
27
|
+
: of(null),
|
|
28
|
+
[currentApp],
|
|
29
|
+
);
|
|
30
|
+
const {
|
|
31
|
+
value: modules,
|
|
32
|
+
error,
|
|
33
|
+
complete,
|
|
34
|
+
} = useObservableState(modules$, {
|
|
35
|
+
initial: (currentApp?.state.modules as unknown as AppModulesInstance<TModules>) ?? null,
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
modules,
|
|
39
|
+
error: error ?? appError,
|
|
40
|
+
complete,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default useCurrentAppModules;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { useCurrentContext as _useCurrentContext } from '@equinor/fusion-framework-react-module-context';
|
|
2
|
+
import { useFramework } from '../useFramework';
|
|
3
|
+
|
|
4
|
+
export const useCurrentContext = () => _useCurrentContext(useFramework().modules.context);
|
|
5
|
+
|
|
6
|
+
export default useCurrentContext;
|
package/src/context.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import type { Fusion } from '@equinor/fusion-framework';
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
+
export const context = createContext<Fusion<any> | null>(null);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Component for providing framework.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* Should be created by {@link createFrameworkProvider}
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* import {FrameworkProvider} from '@equinor/fusion-framework-react';
|
|
16
|
+
* export const Component = (args: React.PropsWithChildren<{framework: Fusion}>) => {
|
|
17
|
+
* return (
|
|
18
|
+
* <FrameworkProvider value={args.framework}>
|
|
19
|
+
* {args.children}
|
|
20
|
+
* </FrameworkProvider>
|
|
21
|
+
* );
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const FrameworkProvider = context.Provider;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, { lazy } from 'react';
|
|
2
|
+
import initFusion from '@equinor/fusion-framework';
|
|
3
|
+
import { FusionConfigurator } from '@equinor/fusion-framework';
|
|
4
|
+
|
|
5
|
+
import { FrameworkProvider } from './context';
|
|
6
|
+
import type { AnyModule } from '@equinor/fusion-framework-module';
|
|
7
|
+
import { ModuleProvider } from '@equinor/fusion-framework-react-module';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create a framework provider for react.
|
|
11
|
+
*
|
|
12
|
+
* This function is for providers of framework, like a portal.
|
|
13
|
+
*
|
|
14
|
+
* @param configurator - callback for configuring modules
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const config: FusionConfigurator = (config) => {}
|
|
18
|
+
* const Portal = () => {
|
|
19
|
+
* const Framework = createFrameworkProvider(config);
|
|
20
|
+
* return (
|
|
21
|
+
* <Suspense fallback={<span>loading...</span>}>
|
|
22
|
+
* <Framework>{children}</Framework>
|
|
23
|
+
* </Suspense>
|
|
24
|
+
* );
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export const createFrameworkProvider = <TModules extends Array<AnyModule> = []>(
|
|
29
|
+
cb: (configurator: FusionConfigurator<TModules>) => void | Promise<void>,
|
|
30
|
+
): React.LazyExoticComponent<React.FunctionComponent<React.PropsWithChildren<unknown>>> =>
|
|
31
|
+
lazy(async () => {
|
|
32
|
+
const configurator = new FusionConfigurator<TModules>();
|
|
33
|
+
await cb(configurator);
|
|
34
|
+
const framework = await initFusion(configurator);
|
|
35
|
+
return {
|
|
36
|
+
default: ({ children }: { children?: React.ReactNode }) => (
|
|
37
|
+
<FrameworkProvider value={framework}>
|
|
38
|
+
<ModuleProvider value={framework.modules}>{children}</ModuleProvider>
|
|
39
|
+
</FrameworkProvider>
|
|
40
|
+
),
|
|
41
|
+
};
|
|
42
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
__useCurrentAppFeatures__
|
|
2
|
+
|
|
3
|
+
Custom hook for accessing all feature flags for an application
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
const Component = () => {
|
|
7
|
+
const appFeatures = useCurrentAppFeatures();
|
|
8
|
+
if( appFeatures.features === undefined ){
|
|
9
|
+
return <p>The current app does not have features enabled</p>
|
|
10
|
+
}
|
|
11
|
+
return (
|
|
12
|
+
<>
|
|
13
|
+
{
|
|
14
|
+
appFeatures.features.map(feature => (
|
|
15
|
+
<button
|
|
16
|
+
key={feature.key}
|
|
17
|
+
disabled={ appFeatures.readOnly }
|
|
18
|
+
onClick={ () => appFeatures.toggleFeature( feature.key ) }
|
|
19
|
+
>
|
|
20
|
+
{ feature.enabled ? 'disable' : 'enable' } feature { feature.title }
|
|
21
|
+
</button>
|
|
22
|
+
))
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
</>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
__useFrameworkFeature__
|
|
31
|
+
|
|
32
|
+
Custom hook for using a framework feature
|
|
33
|
+
|
|
34
|
+
__useFrameworkFeatures__
|
|
35
|
+
|
|
36
|
+
Custom hook for using all framework features
|
|
37
|
+
|
|
38
|
+
__useFeature__
|
|
39
|
+
|
|
40
|
+
> internal hook for getting a feature from a feature flag module
|
|
41
|
+
|
|
42
|
+
__useFeatures__
|
|
43
|
+
|
|
44
|
+
> internal hook for getting features of a feature flag module
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { useFeature } from './useFeature';
|
|
2
|
+
export { useFeatures } from './useFeatures';
|
|
3
|
+
export { useCurrentAppFeatures } from './useCurrentAppFeatures';
|
|
4
|
+
export { useFrameworkFeature } from './useFrameworkFeature';
|
|
5
|
+
export { useFrameworkFeatures } from './useFrameworkFeatures';
|
|
6
|
+
|
|
7
|
+
export { IFeatureFlag, IFeatureFlagProvider } from '@equinor/fusion-framework-module-feature-flag';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type FeatureFlagModule } from '@equinor/fusion-framework-module-feature-flag';
|
|
2
|
+
import { useCurrentAppModule } from '../app';
|
|
3
|
+
import { useFeatures, type UseFeaturesResult } from './useFeatures';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Custom hook that returns the current app features and provides a function to toggle a feature.
|
|
7
|
+
* @returns An object containing the current app features, a function to toggle a feature, and any error that occurred.
|
|
8
|
+
*/
|
|
9
|
+
export const useCurrentAppFeatures = (): UseFeaturesResult => {
|
|
10
|
+
const { module, error: moduleError } = useCurrentAppModule<FeatureFlagModule>('featureFlag');
|
|
11
|
+
|
|
12
|
+
const { features, toggleFeature, error } = useFeatures(module);
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
features,
|
|
16
|
+
toggleFeature,
|
|
17
|
+
error: error ?? moduleError,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { EMPTY } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
type IFeatureFlag,
|
|
7
|
+
type IFeatureFlagProvider,
|
|
8
|
+
} from '@equinor/fusion-framework-module-feature-flag';
|
|
9
|
+
|
|
10
|
+
import { useObservableState } from '@equinor/fusion-observable/react';
|
|
11
|
+
|
|
12
|
+
import { findFeature } from '@equinor/fusion-framework-module-feature-flag/selectors';
|
|
13
|
+
|
|
14
|
+
export interface UseFeatureResult<T> {
|
|
15
|
+
feature?: IFeatureFlag<T>;
|
|
16
|
+
error?: unknown;
|
|
17
|
+
/**
|
|
18
|
+
* @param enable - Optional provide new enabled state of the feature flag. _Defaults to inversion of current feature flag state_
|
|
19
|
+
*/
|
|
20
|
+
toggleFeature: (enable?: boolean) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Custom hook that retrieves a feature flag from a feature flag provider.
|
|
25
|
+
*
|
|
26
|
+
* @template T - The type of the feature flag value.
|
|
27
|
+
* @param {IFeatureFlagProvider} provider - The feature flag provider.
|
|
28
|
+
* @param {string} key - The key of the feature flag.
|
|
29
|
+
* @returns {UseFeatureResult<T>} - An object containing the feature flag value, a function to toggle the feature flag, and any error that occurred.
|
|
30
|
+
*/
|
|
31
|
+
export const useFeature = <T = unknown>(
|
|
32
|
+
provider: IFeatureFlagProvider,
|
|
33
|
+
key: string,
|
|
34
|
+
): UseFeatureResult<T> => {
|
|
35
|
+
const feature$ = useMemo(() => provider.features$.pipe(findFeature<T>(key)), [provider, key]);
|
|
36
|
+
const { value: feature, error } = useObservableState(feature$ ?? EMPTY);
|
|
37
|
+
const toggleFeature = useCallback(
|
|
38
|
+
(enable?: boolean) => {
|
|
39
|
+
const enabled = enable === undefined ? !provider.getFeature(key)?.enabled : enable;
|
|
40
|
+
provider.toggleFeature({ key, enabled });
|
|
41
|
+
},
|
|
42
|
+
[provider, key],
|
|
43
|
+
);
|
|
44
|
+
return { feature, toggleFeature, error };
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default useFeature;
|