@genesislcap/blank-app-seed 3.30.0-prerelease.13 → 3.30.0-prerelease.15
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/.genx/package.json +1 -1
- package/CHANGELOG.md +14 -0
- package/client-tmp/angular/__mocks__/fileMock.js +1 -0
- package/client-tmp/angular/angular.json +0 -29
- package/client-tmp/angular/jest.config.js +20 -0
- package/client-tmp/angular/package.json +6 -6
- package/client-tmp/angular/src/app/layouts/default/default.layout.spec.ts +2 -2
- package/client-tmp/angular/src/jest.setup.ts +46 -0
- package/client-tmp/angular/tsconfig.app.json +1 -2
- package/client-tmp/angular/tsconfig.json +1 -2
- package/client-tmp/angular/tsconfig.spec.json +13 -7
- package/client-tmp/react/package.json +12 -6
- package/client-tmp/react/src/App.tsx +85 -68
- package/client-tmp/react/src/config.ts +0 -15
- package/client-tmp/react/src/guards/ProtectedGuard.tsx +56 -0
- package/client-tmp/react/src/helpers/hasPermissionHelper.tsx +10 -0
- package/client-tmp/react/src/helpers/isAuthenticatedHelper.tsx +14 -0
- package/client-tmp/react/src/helpers/isConnectedHelper.tsx +16 -0
- package/client-tmp/react/src/layouts/blank/BlankLayout.tsx +1 -1
- package/client-tmp/react/src/layouts/default/DefaultLayout.tsx +17 -14
- package/client-tmp/react/src/main.tsx +19 -5
- package/client-tmp/react/src/pages/NotFoundPage/NotFoundPage.css +0 -0
- package/client-tmp/react/src/pages/NotFoundPage/NotFoundPage.tsx +14 -0
- package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.test.tsx +1 -1
- package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.tsx +1 -1
- package/client-tmp/react/src/pbc/README.md +7 -0
- package/client-tmp/react/src/pbc/container.tsx +36 -0
- package/client-tmp/react/src/pbc/elementsRenderer.tsx +40 -0
- package/client-tmp/react/src/pbc/utils.ts +121 -0
- package/client-tmp/react/src/services/store.service.ts +48 -0
- package/client-tmp/react/src/share/foundation-login.ts +13 -6
- package/client-tmp/react/src/share/genesis-components.ts +49 -23
- package/client-tmp/react/src/store/AuthContext.tsx +0 -2
- package/client-tmp/react/src/store/RoutesContext.tsx +73 -0
- package/client-tmp/react/src/types/LayoutName.ts +3 -0
- package/client-tmp/react/src/types/RouteLayouts.ts +3 -1
- package/client-tmp/react/src/utils/getLayoutNameByRoute.ts +5 -0
- package/client-tmp/react/src/utils/history.ts +4 -2
- package/client-tmp/react/src/utils/index.ts +3 -1
- package/client-tmp/react/src/utils/store.ts +34 -0
- package/client-tmp/react/test/e2e/fixture.ts +1 -1
- package/client-tmp/react/tsconfig.app.json +1 -22
- package/client-tmp/react/tsconfig.json +28 -10
- package/client-tmp/react/vite.config.ts +21 -3
- package/package.json +1 -1
- package/client-tmp/angular/karma.conf.js +0 -9
- package/client-tmp/angular/src/app/app.component.spec.ts +0 -23
- package/client-tmp/react/src/guards/AuthGuard.tsx +0 -32
- package/client-tmp/react/src/guards/PermissionsGuard.tsx +0 -37
- package/client-tmp/react/src/index.ts +0 -21
- package/client-tmp/react/src/reportWebVitals.ts +0 -13
- /package/server/{{appName}}-app/src/main/genesis/scripts/{{{appName}}-data-pipelines.kts → {{appName}}-pipelines.kts} +0 -0
package/.genx/package.json
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.30.0-prerelease.15](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.14...v3.30.0-prerelease.15) (2024-09-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* pbc support in react [FUI-2140](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/2140) (#347) 4c41243, closes FUI-2173 FUI-2173 FUI-2173 FUI-2157 FUI-2157 origin/ak/FUI-2173 ak/FUI-2157 FUI-2157 FUI-2157
|
|
9
|
+
|
|
10
|
+
## [3.30.0-prerelease.14](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.13...v3.30.0-prerelease.14) (2024-09-26)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* replaced karma with jest in angular (#348) 805d7ec
|
|
16
|
+
|
|
3
17
|
## [3.30.0-prerelease.13](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.12...v3.30.0-prerelease.13) (2024-09-18)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = 'test-file-stub';
|
|
@@ -90,35 +90,6 @@
|
|
|
90
90
|
"buildTarget": "{{pkgName}}:build"
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
-
"test": {
|
|
94
|
-
"builder": "@angular-builders/custom-webpack:karma",
|
|
95
|
-
"configurations": {
|
|
96
|
-
"production": {
|
|
97
|
-
"customWebpackConfig": {
|
|
98
|
-
"path": "./webpack.prod.config.js",
|
|
99
|
-
"mergeStrategies": {
|
|
100
|
-
"externals": "replace"
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
"development": {
|
|
105
|
-
"customWebpackConfig": {
|
|
106
|
-
"path": "./webpack.dev.config.js",
|
|
107
|
-
"mergeStrategies": {
|
|
108
|
-
"externals": "replace"
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
"defaultConfiguration": "development",
|
|
114
|
-
"options": {
|
|
115
|
-
"polyfills": ["zone.js", "zone.js/testing"],
|
|
116
|
-
"tsConfig": "tsconfig.spec.json",
|
|
117
|
-
"assets": ["src/favicon.ico", "src/assets"],
|
|
118
|
-
"styles": ["src/styles/styles.css"],
|
|
119
|
-
"scripts": []
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
93
|
"lint": {
|
|
123
94
|
"builder": "@angular-eslint/builder:lint",
|
|
124
95
|
"options": {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const { pathsToModuleNameMapper } = require('ts-jest');
|
|
2
|
+
const { compilerOptions } = require('./tsconfig');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
preset: 'jest-preset-angular',
|
|
6
|
+
roots: ['<rootDir>/src/'],
|
|
7
|
+
testMatch: ['**/+(*.)+(spec).+(ts)'],
|
|
8
|
+
setupFilesAfterEnv: ['<rootDir>/src/jest.setup.ts'],
|
|
9
|
+
collectCoverage: true,
|
|
10
|
+
coverageReporters: ['html'],
|
|
11
|
+
coverageDirectory: 'coverage/my-app',
|
|
12
|
+
transformIgnorePatterns: [
|
|
13
|
+
'node_modules/(?!(@genesislcap/*|consola|@angular|@microsoft|exenv-es6|uuid))',
|
|
14
|
+
],
|
|
15
|
+
moduleNameMapper: {
|
|
16
|
+
...pathsToModuleNameMapper(compilerOptions.paths || {}, { prefix: '<rootDir>/' }),
|
|
17
|
+
'\\.(jpg|jpeg|png|gif|svg)$': '<rootDir>/src/__mocks__/fileMock.js',
|
|
18
|
+
'\\.(css)$': 'identity-obj-proxy',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"lint:fix": "genx lint --fix",
|
|
28
28
|
"lint:eslint": "genx lint -l eslint --profile",
|
|
29
29
|
"lint:stylelint": "node lint-css.js",
|
|
30
|
-
"test": "
|
|
30
|
+
"test": "jest",
|
|
31
31
|
"test:e2e": "genx test --e2e",
|
|
32
32
|
"test:e2e:debug": "genx test --e2e --debug",
|
|
33
33
|
"test:e2e:ui": "genx test --e2e --interactive",
|
|
@@ -54,14 +54,14 @@
|
|
|
54
54
|
"@genesislcap/genx": "{{versions.UI}}",
|
|
55
55
|
"@genesislcap/build-kit": "{{versions.UI}}",
|
|
56
56
|
"@types/jasmine": "~5.1.0",
|
|
57
|
+
"@types/jest": "^29.5.13",
|
|
57
58
|
"@types/numeral": "^2.0.5",
|
|
58
59
|
"file-loader": "^6.2.0",
|
|
59
60
|
"jasmine-core": "~5.1.0",
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"karma-jasmine-html-reporter": "~2.1.0",
|
|
61
|
+
"jest": "^29.7.0",
|
|
62
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
63
|
+
"jest-preset-angular": "^14.2.4",
|
|
64
|
+
"jest-transform-stub": "^2.0.0",
|
|
65
65
|
"svg-url-loader": "^8.0.0",
|
|
66
66
|
"typescript": "~5.4.5",
|
|
67
67
|
"ts-node": "10.9.2",
|
|
@@ -4,7 +4,7 @@ import { DefaultLayoutComponent } from './default.layout';
|
|
|
4
4
|
import { ElementRef, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
5
5
|
|
|
6
6
|
class MockRouter {
|
|
7
|
-
navigate =
|
|
7
|
+
navigate = jest.fn();
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
class MockElementRef implements ElementRef {
|
|
@@ -46,4 +46,4 @@ describe('DefaultLayoutComponent', () => {
|
|
|
46
46
|
component.navigateAngular(path);
|
|
47
47
|
expect(router.navigate).toHaveBeenCalledWith([path]);
|
|
48
48
|
});
|
|
49
|
-
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import 'jest-preset-angular/setup-jest';
|
|
2
|
+
|
|
3
|
+
// Mock window.matchMedia
|
|
4
|
+
Object.defineProperty(window, 'matchMedia', {
|
|
5
|
+
writable: true,
|
|
6
|
+
value: (query: string) => ({
|
|
7
|
+
matches: false,
|
|
8
|
+
media: query,
|
|
9
|
+
onchange: null,
|
|
10
|
+
addListener: jest.fn(), // Deprecated
|
|
11
|
+
removeListener: jest.fn(), // Deprecated
|
|
12
|
+
addEventListener: jest.fn(),
|
|
13
|
+
removeEventListener: jest.fn(),
|
|
14
|
+
dispatchEvent: jest.fn(),
|
|
15
|
+
}),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Mock BroadcastChannel
|
|
19
|
+
class MockBroadcastChannel {
|
|
20
|
+
name: string;
|
|
21
|
+
onmessage: ((this: BroadcastChannel, ev: MessageEvent) => any) | null = null;
|
|
22
|
+
onmessageerror: ((this: BroadcastChannel, ev: MessageEvent) => any) | null = null;
|
|
23
|
+
|
|
24
|
+
constructor(name: string) {
|
|
25
|
+
this.name = name;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
postMessage(message: any) {
|
|
29
|
+
if (this.onmessage) {
|
|
30
|
+
this.onmessage({ data: message } as MessageEvent);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
close() {}
|
|
35
|
+
|
|
36
|
+
addEventListener() {}
|
|
37
|
+
removeEventListener() {}
|
|
38
|
+
dispatchEvent() {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
Object.defineProperty(window, 'BroadcastChannel', {
|
|
44
|
+
writable: true,
|
|
45
|
+
value: MockBroadcastChannel,
|
|
46
|
+
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
|
2
1
|
{
|
|
3
2
|
"compileOnSave": false,
|
|
4
3
|
"compilerOptions": {
|
|
@@ -23,7 +22,7 @@
|
|
|
23
22
|
"ES2022",
|
|
24
23
|
"dom"
|
|
25
24
|
],
|
|
26
|
-
"resolveJsonModule": true
|
|
25
|
+
"resolveJsonModule": true
|
|
27
26
|
},
|
|
28
27
|
"angularCompilerOptions": {
|
|
29
28
|
"enableI18nLegacyMessageIdFormat": false,
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
|
2
1
|
{
|
|
3
2
|
"extends": "./tsconfig.json",
|
|
4
3
|
"compilerOptions": {
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"target": "ES2022",
|
|
5
6
|
"outDir": "./out-tsc/spec",
|
|
6
7
|
"types": [
|
|
7
|
-
"
|
|
8
|
-
]
|
|
8
|
+
"jest"
|
|
9
|
+
],
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"emitDecoratorMetadata": true,
|
|
12
|
+
"resolveJsonModule": true
|
|
9
13
|
},
|
|
14
|
+
"files": [
|
|
15
|
+
"src/jest.setup.ts",
|
|
16
|
+
],
|
|
10
17
|
"include": [
|
|
11
|
-
"src/**/*.
|
|
12
|
-
"src
|
|
13
|
-
"src/**/*.spec.ts"
|
|
18
|
+
"src/**/*.spec.ts",
|
|
19
|
+
"src/**/*.d.ts"
|
|
14
20
|
]
|
|
15
|
-
}
|
|
21
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"build": "vite build",
|
|
10
10
|
"build:stats": "npm run build --stats-json",
|
|
11
11
|
"clean": "genx clean dist node_modules",
|
|
12
|
-
"dev": "vite",
|
|
12
|
+
"dev": "vite build && vite preview",
|
|
13
13
|
"dev:docker": "npm run dev -- --host 0.0.0.0",
|
|
14
14
|
"dev:no-open": "NO_OPEN=true npm run dev",
|
|
15
15
|
"dev:intellij": "npm run dev",
|
|
@@ -33,17 +33,21 @@
|
|
|
33
33
|
"@ag-grid-enterprise/core": "29.2.0",
|
|
34
34
|
"@ag-grid-enterprise/row-grouping": "29.2.0",
|
|
35
35
|
"@ag-grid-enterprise/server-side-row-model": "29.2.0",
|
|
36
|
+
"@genesislcap/foundation-comms": "{{versions.UI}}",
|
|
37
|
+
"@genesislcap/foundation-entity-management": "{{versions.UI}}",
|
|
36
38
|
{{#if FDC3.includeDependencies}}
|
|
37
39
|
"@genesislcap/foundation-fdc3": "{{versions.UI}}",
|
|
38
40
|
{{/if}}
|
|
39
|
-
"@genesislcap/foundation-comms": "{{versions.UI}}",
|
|
40
|
-
"@genesislcap/foundation-login": "{{versions.UI}}",
|
|
41
|
-
"@genesislcap/foundation-entity-management": "{{versions.UI}}",
|
|
42
41
|
"@genesislcap/foundation-header": "{{versions.UI}}",
|
|
42
|
+
"@genesislcap/foundation-layout": "{{versions.UI}}",
|
|
43
|
+
"@genesislcap/foundation-logger": "{{versions.UI}}",
|
|
44
|
+
"@genesislcap/foundation-login": "{{versions.UI}}",
|
|
45
|
+
"@genesislcap/foundation-shell": "{{versions.UI}}",
|
|
43
46
|
"@genesislcap/foundation-ui": "{{versions.UI}}",
|
|
47
|
+
"@genesislcap/foundation-utils": "{{versions.UI}}",
|
|
44
48
|
"@genesislcap/rapid-design-system": "{{versions.UI}}",
|
|
45
49
|
"@genesislcap/rapid-grid-pro": "{{versions.UI}}",
|
|
46
|
-
"@genesislcap/
|
|
50
|
+
"@genesislcap/web-core": "{{versions.UI}}",
|
|
47
51
|
"@genesislcap/g2plot-chart": "{{versions.UI}}",
|
|
48
52
|
"history": "^5.3.0",
|
|
49
53
|
"react": "^19.0.0-beta-94eed63c49-20240425",
|
|
@@ -64,6 +68,7 @@
|
|
|
64
68
|
"@testing-library/dom": "^10.4.0",
|
|
65
69
|
"@testing-library/jest-dom": "^6.5.0",
|
|
66
70
|
"@testing-library/react": "^16.0.0",
|
|
71
|
+
"@types/css-modules": "^1.0.5",
|
|
67
72
|
"@types/jest": "^29.5.12",
|
|
68
73
|
"@types/node": "^20.14.10",
|
|
69
74
|
"@types/react": "npm:types-react@alpha",
|
|
@@ -80,7 +85,8 @@
|
|
|
80
85
|
"ts-jest": "^29.2.5",
|
|
81
86
|
"ts-node": "^10.9.2",
|
|
82
87
|
"typescript": "^5.2.2",
|
|
83
|
-
"vite": "^5.3.1"
|
|
88
|
+
"vite": "^5.3.1",
|
|
89
|
+
"vite-plugin-tsconfig-paths": "^1.4.1"
|
|
84
90
|
},
|
|
85
91
|
"overrides": {
|
|
86
92
|
"@types/react": "npm:types-react@alpha",
|
|
@@ -1,31 +1,70 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { unstable_HistoryRouter as HistoryRouter, Routes, Route, useLocation } from 'react-router-dom';
|
|
1
3
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
history,
|
|
5
|
+
setApiHost,
|
|
6
|
+
getLayoutNameByRoute,
|
|
7
|
+
{{#if FDC3.channels.length~}}
|
|
8
|
+
listenToChannel,
|
|
9
|
+
onFDC3Ready,
|
|
10
|
+
{{/if}}
|
|
11
|
+
} from './utils';
|
|
12
|
+
import { customEventFactory, registerStylesTarget } from '@/pbc/utils';
|
|
9
13
|
import LayoutWrapper from './layouts/LayoutWrapper';
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import PermissionsGuard from './guards/PermissionsGuard';
|
|
14
|
+
import LayoutName from '@/types/LayoutName';
|
|
15
|
+
import { AUTH_PATH, routeLayouts } from './config';
|
|
13
16
|
import { AuthProvider } from './store/AuthContext';
|
|
14
|
-
|
|
17
|
+
import { RoutesProvider, useRoutesContext } from './store/RoutesContext';
|
|
15
18
|
import AuthPage from './pages/AuthPage/AuthPage';
|
|
16
|
-
import
|
|
17
|
-
{
|
|
18
|
-
import
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
// Genesis Components
|
|
22
|
-
import './share/genesis-components';
|
|
19
|
+
import { registerComponents as genesisRegisterComponents } from './share/genesis-components';
|
|
20
|
+
import { configureFoundationLogin } from './share/foundation-login';
|
|
21
|
+
import ProtectedGuard from './guards/ProtectedGuard';
|
|
22
|
+
import { storeService } from '@/services/store.service';
|
|
23
23
|
|
|
24
|
-
const
|
|
24
|
+
const DynamicLayout = () => {
|
|
25
25
|
const location = useLocation();
|
|
26
|
-
const
|
|
27
|
-
{
|
|
26
|
+
const [layoutName, setLayoutName] = useState<LayoutName>(routeLayouts[location.pathname] || 'default');
|
|
27
|
+
const handleRouteChange = (location: any) => {
|
|
28
|
+
setLayoutName(getLayoutNameByRoute(location.pathname));
|
|
29
|
+
};
|
|
30
|
+
const route = useRoutesContext().find((r) => r.path === location.pathname);
|
|
31
|
+
let pageComponent;
|
|
32
|
+
let content;
|
|
33
|
+
|
|
28
34
|
useEffect(() => {
|
|
35
|
+
handleRouteChange(location);
|
|
36
|
+
const unlisten = history.listen(handleRouteChange);
|
|
37
|
+
|
|
38
|
+
return () => {
|
|
39
|
+
unlisten();
|
|
40
|
+
}
|
|
41
|
+
}, [location]);
|
|
42
|
+
|
|
43
|
+
if (route) {
|
|
44
|
+
pageComponent = route.element;
|
|
45
|
+
} else {
|
|
46
|
+
pageComponent = <AuthPage />;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (location.pathname === `/${AUTH_PATH}` || location.pathname === '/') {
|
|
50
|
+
content = pageComponent;
|
|
51
|
+
} else {
|
|
52
|
+
content = <ProtectedGuard>{pageComponent}</ProtectedGuard>
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return <LayoutWrapper layout={layoutName}>{content}</LayoutWrapper>
|
|
56
|
+
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const App: React.FC = ({ rootElement }) => {
|
|
60
|
+
const dispatchCustomEvent = (type: string, detail?: any) => {
|
|
61
|
+
rootElement.dispatchEvent(customEventFactory(type, detail));
|
|
62
|
+
};
|
|
63
|
+
const handleStoreConnected = (event: CustomEvent) => {
|
|
64
|
+
storeService.onConnected(event);
|
|
65
|
+
};
|
|
66
|
+
{{#if FDC3.channels.length~}}
|
|
67
|
+
const FDC3ReadyHandler = () => {
|
|
29
68
|
{{#each FDC3.channels}}
|
|
30
69
|
listenToChannel('{{this.name}}', '{{this.type}}', (result) => {
|
|
31
70
|
console.log('Received FDC3 channel message on: {{this.name}} channel, type: {{this.type}}', result);
|
|
@@ -33,61 +72,39 @@ const LayoutWithLocation = () => {
|
|
|
33
72
|
// E.g. open a modal or route to specific page: Route.path.push(`[Route name]`);
|
|
34
73
|
});
|
|
35
74
|
{{/each}}
|
|
36
|
-
|
|
37
|
-
return () => {
|
|
38
|
-
console.log('Component is being unmounted');
|
|
39
|
-
};
|
|
40
|
-
}, []);
|
|
75
|
+
};
|
|
41
76
|
{{/if}}
|
|
42
77
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
switch (location.pathname) {
|
|
47
|
-
case `/${AUTH_PATH}`:
|
|
48
|
-
pageComponent = <AuthPage />;
|
|
49
|
-
break;
|
|
50
|
-
case `/${NOT_PERMITTED_PATH}`:
|
|
51
|
-
pageComponent = <NotPermittedPage />;
|
|
52
|
-
break;
|
|
53
|
-
{{#each routes}}
|
|
54
|
-
case '/{{kebabCase this.name}}':
|
|
55
|
-
pageComponent = <{{pascalCase this.name}} />;
|
|
56
|
-
permissionCode = '{{this.permissions.viewRight}}';
|
|
57
|
-
break;
|
|
58
|
-
{{/each}}
|
|
59
|
-
default:
|
|
60
|
-
pageComponent = <AuthPage />;
|
|
61
|
-
}
|
|
78
|
+
setApiHost();
|
|
79
|
+
genesisRegisterComponents();
|
|
80
|
+
configureFoundationLogin({ router: history });
|
|
62
81
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<PermissionsGuard permissionCode={permissionCode}>
|
|
72
|
-
<LayoutWrapper layout={layout}>{pageComponent}</LayoutWrapper>
|
|
73
|
-
</PermissionsGuard>
|
|
74
|
-
</AuthGuard>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
rootElement.addEventListener('store-connected', handleStoreConnected);
|
|
84
|
+
registerStylesTarget(document.body, 'main');
|
|
85
|
+
{{#if FDC3.channels.length~}}
|
|
86
|
+
onFDC3Ready(FDC3ReadyHandler);
|
|
87
|
+
{{/if}}
|
|
88
|
+
dispatchCustomEvent('store-connected', rootElement);
|
|
89
|
+
dispatchCustomEvent('store-ready', true);
|
|
78
90
|
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
return () => {
|
|
92
|
+
rootElement.removeEventListener('store-connected', handleStoreConnected);
|
|
93
|
+
dispatchCustomEvent('store-disconnected');
|
|
94
|
+
};
|
|
95
|
+
}, []);
|
|
81
96
|
|
|
82
97
|
return (
|
|
83
98
|
<AuthProvider>
|
|
84
|
-
<
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
<RoutesProvider>
|
|
100
|
+
<HistoryRouter history={history}>
|
|
101
|
+
<Routes>
|
|
102
|
+
<Route path="*" element={<DynamicLayout />} />
|
|
103
|
+
</Routes>
|
|
104
|
+
</HistoryRouter>
|
|
105
|
+
</RoutesProvider>
|
|
89
106
|
</AuthProvider>
|
|
90
107
|
);
|
|
91
108
|
};
|
|
92
109
|
|
|
93
|
-
export default App;
|
|
110
|
+
export default App;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { RouteLayouts } from './types/RouteLayouts';
|
|
2
2
|
|
|
3
3
|
export const routeLayouts: RouteLayouts = {
|
|
4
|
-
'/auth-mock': 'blank',
|
|
5
4
|
'/auth': 'blank',
|
|
6
5
|
'/': 'blank',
|
|
7
6
|
};
|
|
8
7
|
|
|
9
|
-
import type { MainMenu } from './types/menu';
|
|
10
|
-
|
|
11
8
|
export const AUTH_PATH = 'auth';
|
|
12
9
|
export const NOT_PERMITTED_PATH = 'not-permitted';
|
|
13
10
|
|
|
@@ -18,15 +15,3 @@ export const API_DATA = {
|
|
|
18
15
|
password: '', // provide password to a user in given environment
|
|
19
16
|
},
|
|
20
17
|
};
|
|
21
|
-
|
|
22
|
-
export const mainMenu: MainMenu = [
|
|
23
|
-
{{#each routes}}
|
|
24
|
-
{
|
|
25
|
-
index: {{@index}},
|
|
26
|
-
path: '{{kebabCase this.name}}',
|
|
27
|
-
title: '{{#if this.title}}{{this.title}}{{else}}{{this.name}}{{/if}}',
|
|
28
|
-
icon: '{{this.icon}}',
|
|
29
|
-
variant: 'solid'
|
|
30
|
-
}{{#unless @last}},{{/unless}}
|
|
31
|
-
{{/each}}
|
|
32
|
-
];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useState, useEffect, ReactNode } from 'react';
|
|
2
|
+
import isConnectedHelper from '@/helpers/isConnectedHelper';
|
|
3
|
+
import isAuthenticatedHelper from '@/helpers/isAuthenticatedHelper';
|
|
4
|
+
import hasPermissionHelper from '@/helpers/hasPermissionHelper';
|
|
5
|
+
import { useRoutesContext } from '@/store/RoutesContext';
|
|
6
|
+
import { NOT_PERMITTED_PATH, AUTH_PATH } from '@/config';
|
|
7
|
+
|
|
8
|
+
enum PermissionState {
|
|
9
|
+
ALLOWED = 'allowed',
|
|
10
|
+
DENIED = 'denied',
|
|
11
|
+
UNKNOWN = 'unknown',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const redirectUrlByPermissionState: { [key in Partial<PermissionState>]?: string } = {
|
|
15
|
+
[PermissionState.DENIED]: NOT_PERMITTED_PATH,
|
|
16
|
+
[PermissionState.UNKNOWN]: AUTH_PATH,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const ProtectedGuard: React.FC<{ children: ReactNode }> = ({ children }: { children: ReactNode }) => {
|
|
20
|
+
const routes = useRoutesContext();
|
|
21
|
+
const [isConnected, setIsConnected] = useState<boolean | null>(null);
|
|
22
|
+
const isAuthenticated: boolean | null = null;
|
|
23
|
+
const route = routes.find(({ path }) => path === location.pathname);
|
|
24
|
+
const hasPermission = route?.data?.permissionCode ? hasPermissionHelper(route.data?.permissionCode) : true;
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
isConnectedHelper().then((connectedState: boolean): void => {
|
|
28
|
+
setIsConnected(connectedState);
|
|
29
|
+
});
|
|
30
|
+
}, []);
|
|
31
|
+
|
|
32
|
+
useEffect((): void => {
|
|
33
|
+
if (isConnected === null) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const isAuthenticated = isAuthenticatedHelper();
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
let permissionState;
|
|
41
|
+
|
|
42
|
+
if (!isConnected || !isAuthenticated) {
|
|
43
|
+
permissionState = PermissionState.UNKNOWN;
|
|
44
|
+
} else if (hasPermission === false) {
|
|
45
|
+
permissionState = PermissionState.DENIED;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (permissionState) {
|
|
49
|
+
window.location.href = `/${redirectUrlByPermissionState[permissionState]}`;
|
|
50
|
+
}
|
|
51
|
+
}, [routes, isConnected, isAuthenticated, hasPermission]);
|
|
52
|
+
|
|
53
|
+
return children;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default ProtectedGuard;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getUser } from '@genesislcap/foundation-user';
|
|
2
|
+
|
|
3
|
+
const hasPermissionHelper = (permissionCode: string | undefined): boolean => {
|
|
4
|
+
const user = getUser();
|
|
5
|
+
|
|
6
|
+
return !!(permissionCode && !user.hasPermission(permissionCode))
|
|
7
|
+
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default hasPermissionHelper;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getUser } from '@genesislcap/foundation-user';
|
|
2
|
+
|
|
3
|
+
const isAuthenticatedHelper = (): boolean => {
|
|
4
|
+
const user = getUser();
|
|
5
|
+
|
|
6
|
+
if (!user.isAuthenticated) {
|
|
7
|
+
user.trackPath();
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default isAuthenticatedHelper;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getConnect } from '@genesislcap/foundation-comms';
|
|
2
|
+
|
|
3
|
+
const isConnectedHelper = (): Promise<boolean> => {
|
|
4
|
+
const connect = getConnect();
|
|
5
|
+
const hostUrl = sessionStorage.getItem('hostUrl');
|
|
6
|
+
|
|
7
|
+
if (connect.isConnected) {
|
|
8
|
+
return new Promise((resolve) => resolve(true));
|
|
9
|
+
}
|
|
10
|
+
if (!hostUrl) {
|
|
11
|
+
return new Promise((resolve) => resolve(false));
|
|
12
|
+
}
|
|
13
|
+
return connect.connect(hostUrl);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default isConnectedHelper;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { ReactNode, useEffect, useRef } from 'react';
|
|
2
2
|
import { configureDesignSystem } from '@genesislcap/foundation-ui';
|
|
3
3
|
import styles from './BlankLayout.module.css';
|
|
4
|
-
import * as designTokens from '
|
|
4
|
+
import * as designTokens from '@/styles/design-tokens.json';
|
|
5
5
|
|
|
6
6
|
interface BlankLayoutProps {
|
|
7
7
|
children: ReactNode;
|