@genesislcap/blank-app-seed 3.29.2 → 3.30.0-prerelease.2

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.
Files changed (56) hide show
  1. package/.genx/package.json +1 -1
  2. package/.genx/scripts/update-versions.js +45 -15
  3. package/.genx/templates/angular/entityManager.hbs +3 -0
  4. package/.genx/templates/angular/route.hbs +0 -1
  5. package/.genx/templates/react/chart.hbs +6 -2
  6. package/.genx/templates/react/component/component.gridOptions.hbs +1 -1
  7. package/.genx/templates/react/component/component.hbs +22 -14
  8. package/.genx/templates/react/component/component.index.hbs +1 -1
  9. package/.genx/templates/react/entityManager.hbs +16 -9
  10. package/.genx/templates/react/form.hbs +6 -2
  11. package/.genx/templates/react/grid.hbs +15 -5
  12. package/.genx/templates/react/gridLayout.hbs +28 -28
  13. package/.genx/templates/react/horizontalLayout.hbs +5 -5
  14. package/.genx/templates/react/route.hbs +4 -18
  15. package/.genx/templates/web-components/entityManager.hbs +3 -0
  16. package/.genx/utils/formatRouteData.js +1 -1
  17. package/.genx/utils/generateTile.js +1 -0
  18. package/.genx/versions.json +3 -3
  19. package/.github/pull_request_template.md +1 -1
  20. package/.github/workflows/build.yml +3 -2
  21. package/.github/workflows/slack.yml +1 -1
  22. package/.github/workflows/upgrade.yml +6 -1
  23. package/.github/workflows/upgrade_prerelease.yml +1 -0
  24. package/CHANGELOG.md +109 -4
  25. package/client-tmp/react/.eslintrc.cjs +3 -1
  26. package/client-tmp/react/env.development.json +3 -0
  27. package/client-tmp/react/index.html +1 -1
  28. package/client-tmp/react/lint-css.js +18 -0
  29. package/client-tmp/react/package.json +31 -5
  30. package/client-tmp/react/playwright.config.ts +17 -0
  31. package/client-tmp/react/src/App.tsx +33 -6
  32. package/client-tmp/react/src/components/ErrorMessage/ErrorMessage.jsx +62 -0
  33. package/client-tmp/react/src/components/ErrorMessage.test.js +80 -0
  34. package/client-tmp/react/src/config.ts +2 -1
  35. package/client-tmp/react/src/custom-elements.d.ts +1 -1
  36. package/client-tmp/react/src/guards/PermissionsGuard.tsx +37 -0
  37. package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.css +0 -0
  38. package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.jsx +13 -0
  39. package/client-tmp/react/src/share/foundation-login.ts +1 -1
  40. package/client-tmp/react/src/svg-elements.d.ts +1 -1
  41. package/client-tmp/react/src/utils/fdc3.ts +32 -0
  42. package/client-tmp/react/src/utils/history.ts +1 -3
  43. package/client-tmp/react/src/utils/index.ts +4 -0
  44. package/client-tmp/react/src/utils/permissions.ts +7 -0
  45. package/client-tmp/react/src/utils/setApiHost.ts +9 -0
  46. package/client-tmp/react/test/e2e/fixture.ts +26 -0
  47. package/client-tmp/react/test/e2e/flows/001-protected.e2e.ts +6 -0
  48. package/client-tmp/react/test/e2e/index.ts +2 -0
  49. package/client-tmp/react/test/e2e/pages/index.ts +1 -0
  50. package/client-tmp/react/test/e2e/pages/protected.ts +16 -0
  51. package/client-tmp/react/tsconfig.node.json +1 -1
  52. package/client-tmp/react/vite.config.js +59 -0
  53. package/package.json +1 -1
  54. package/client-tmp/react/vite.config.ts +0 -14
  55. /package/client-tmp/react/src/pages/{auth → AuthPage}/AuthPage.css +0 -0
  56. /package/client-tmp/react/src/pages/{auth → AuthPage}/AuthPage.jsx +0 -0
package/CHANGELOG.md CHANGED
@@ -1,18 +1,123 @@
1
1
  # Changelog
2
2
 
3
- ## [3.29.2](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1...v3.29.2) (2024-08-15)
3
+ ## [3.30.0-prerelease.2](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.1...v3.30.0-prerelease.2) (2024-09-06)
4
4
 
5
5
 
6
6
  ### Bug Fixes
7
7
 
8
- * handling multiple hyphens when generating DB namespace PA-1361 (#318) 2dbaadb, closes PSD-9 PSD-9 PSD-0 PSD-0 PSD-0 PSD-0 PTC-0
8
+ * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#334) 3af309b
9
9
 
10
- ## [3.29.1](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.0...v3.29.1) (2024-08-14)
10
+ ## [3.30.0-prerelease.1](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.15...v3.30.0-prerelease.1) (2024-09-05)
11
+
12
+
13
+ ### Features
14
+
15
+ * add entityLabel so toast popups tell us the type of entity added GENC-762 (#333) 692bda0
16
+
17
+ ## [3.29.1-prerelease.15](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.14...v3.29.1-prerelease.15) (2024-09-05)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * updating server version information for Auth [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) 9e491e3
23
+
24
+ ## [3.29.1-prerelease.14](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.13...v3.29.1-prerelease.14) (2024-09-05)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * updating server version information for GSF [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) a9473e4
30
+
31
+ ## [3.29.1-prerelease.13](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.12...v3.29.1-prerelease.13) (2024-09-05)
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#328) 626c48b
37
+
38
+ ## [3.29.1-prerelease.12](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.11...v3.29.1-prerelease.12) (2024-09-03)
39
+
40
+
41
+ ### Bug Fixes
42
+
43
+ * update unit test commands in package.json (#329) 290a3ab
44
+
45
+ ## [3.29.1-prerelease.11](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.10...v3.29.1-prerelease.11) (2024-08-28)
46
+
47
+
48
+ ### Bug Fixes
49
+
50
+ * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#323) aea0500
51
+
52
+ ## [3.29.1-prerelease.10](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.9...v3.29.1-prerelease.10) (2024-08-23)
53
+
54
+
55
+ ### Bug Fixes
56
+
57
+ * updating server version information for Auth [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) 940ebbc
58
+
59
+ ## [3.29.1-prerelease.9](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.8...v3.29.1-prerelease.9) (2024-08-23)
60
+
61
+
62
+ ### Bug Fixes
63
+
64
+ * updating server version information for GSF [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) fea6c6f
65
+
66
+ ## [3.29.1-prerelease.8](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.7...v3.29.1-prerelease.8) (2024-08-23)
67
+
68
+
69
+ ### Bug Fixes
70
+
71
+ * updating server version information for GSF [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) 0fbf0b3
72
+
73
+ ## [3.29.1-prerelease.7](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.6...v3.29.1-prerelease.7) (2024-08-20)
74
+
75
+
76
+ ### Bug Fixes
77
+
78
+ * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#321) b5d9dd9
79
+
80
+ ## [3.29.1-prerelease.6](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.5...v3.29.1-prerelease.6) (2024-08-20)
81
+
82
+
83
+ ### Bug Fixes
84
+
85
+ * updating server version information for GSF [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) f18c4cf
86
+
87
+ ## [3.29.1-prerelease.5](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.4...v3.29.1-prerelease.5) (2024-08-16)
88
+
89
+
90
+ ### Bug Fixes
91
+
92
+ * updating server version information for GSF [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) a2c959c
93
+
94
+ ## [3.29.1-prerelease.4](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.3...v3.29.1-prerelease.4) (2024-08-16)
95
+
96
+
97
+ ### Bug Fixes
98
+
99
+ * updating server version information for GSF [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) 872539b
100
+
101
+ ## [3.29.1-prerelease.3](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.2...v3.29.1-prerelease.3) (2024-08-15)
102
+
103
+
104
+ ### Bug Fixes
105
+
106
+ * useonlytemplatecols not enabled from create GENC-703 (#316) 93c9e9f
107
+
108
+ ## [3.29.1-prerelease.2](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.1-prerelease.1...v3.29.1-prerelease.2) (2024-08-15)
109
+
110
+
111
+ ### Bug Fixes
112
+
113
+ * handling multiple hyphens when generating DB namespace PA-1361 (#317) ceda4bb
114
+
115
+ ## [3.29.1-prerelease.1](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.29.0...v3.29.1-prerelease.1) (2024-08-14)
11
116
 
12
117
 
13
118
  ### Bug Fixes
14
119
 
15
- * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#313) 2b62917
120
+ * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#314) 5070baa
16
121
 
17
122
  ## [3.29.0](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.28.6...v3.29.0) (2024-08-13)
18
123
 
@@ -1,6 +1,6 @@
1
1
  module.exports = {
2
2
  root: true,
3
- env: { browser: true, es2020: true },
3
+ env: { browser: true, es2020: true, node: true, jest: true },
4
4
  extends: [
5
5
  'eslint:recommended',
6
6
  'plugin:@typescript-eslint/recommended',
@@ -10,6 +10,8 @@ module.exports = {
10
10
  parser: '@typescript-eslint/parser',
11
11
  plugins: ['react-refresh'],
12
12
  rules: {
13
+ '@typescript-eslint/no-unused-vars': 'off',
14
+ '@typescript-eslint/no-var-requires': 'off',
13
15
  'react-refresh/only-export-components': [
14
16
  'warn',
15
17
  { allowConstantExport: true },
@@ -0,0 +1,3 @@
1
+ {
2
+ "VITE_API_HOST": "{{apiHost}}"
3
+ }
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>{{pkgName}}</title>
7
+ <title>{{capitalCase appName}}</title>
8
8
  </head>
9
9
  <body>
10
10
  <div id="root"></div>
@@ -0,0 +1,18 @@
1
+ const { execSync } = require('child_process');
2
+ const glob = require('glob');
3
+ const path = require('path');
4
+ const cssFiles = glob.sync(path.join(__dirname, '**/*.css'));
5
+
6
+ if (cssFiles.length === 0) {
7
+ console.log('No CSS files found.');
8
+ process.exit(0);
9
+ }
10
+
11
+ const command = `genx lint -l stylelint ${cssFiles.join(' ')}`;
12
+
13
+ try {
14
+ execSync(command, { stdio: 'inherit' });
15
+ } catch (error) {
16
+ console.error('Error running stylelint:', error);
17
+ process.exit(1);
18
+ }
@@ -5,12 +5,26 @@
5
5
  "scripts": {
6
6
  "baseline": "npm run clean && npm run bootstrap",
7
7
  "bootstrap": "npm i --legacy-peer-deps",
8
+ "bootstrap:ci": "npm ci --no-fund --no-audit",
9
+ "build": "vite build",
10
+ "build:stats": "npm run build --stats-json",
11
+ "clean": "genx clean dist node_modules",
8
12
  "dev": "vite",
9
- "build": "tsc -b && vite build",
10
- "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
11
- "serve": "vite preview",
12
- "clean": "rm -rf node_modules dist",
13
- "lint:fix": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0 --fix"
13
+ "dev:docker": "npm run dev -- --host 0.0.0.0",
14
+ "dev:no-open": "NO_OPEN=true npm run dev",
15
+ "dev:intellij": "npm run dev",
16
+ "dev:https": "HTTPS=true npm run dev",
17
+ "dsconfig": "dsconfig --path src/styles/design-tokens.json",
18
+ "lint": "eslint src/**/*.js src/**/*.jsx",
19
+ "lint:fix": "eslint src/**/*.js src/**/*.jsx --fix",
20
+ "lint:eslint": "npm lint",
21
+ "lint:stylelint": "node lint-css.js",
22
+ "test": "genx test",
23
+ "test:e2e": "genx test --e2e",
24
+ "test:e2e:debug": "genx test --e2e --debug",
25
+ "test:e2e:ui": "genx test --e2e --interactive",
26
+ "test:coverage": "genx test --no-watch --coverage",
27
+ "test:unit:watch": "genx test --watch"
14
28
  },
15
29
  "dependencies": {
16
30
  "@ag-grid-community/client-side-row-model": "29.2.0",
@@ -19,6 +33,9 @@
19
33
  "@ag-grid-enterprise/core": "29.2.0",
20
34
  "@ag-grid-enterprise/row-grouping": "29.2.0",
21
35
  "@ag-grid-enterprise/server-side-row-model": "29.2.0",
36
+ {{#if FDC3.includeDependencies}}
37
+ "@genesislcap/foundation-fdc3": "{{versions.UI}}",
38
+ {{/if}}
22
39
  "@genesislcap/foundation-comms": "{{versions.UI}}",
23
40
  "@genesislcap/foundation-login": "{{versions.UI}}",
24
41
  "@genesislcap/foundation-entity-management": "{{versions.UI}}",
@@ -34,6 +51,15 @@
34
51
  "react-router-dom": "6.24.1"
35
52
  },
36
53
  "devDependencies": {
54
+ "@genesislcap/design-system-configurator": "{{versions.UI}}",
55
+ "@genesislcap/eslint-config": "{{versions.UI}}",
56
+ "@genesislcap/prettier-config": "{{versions.UI}}",
57
+ "@genesislcap/foundation-testing": "{{versions.UI}}",
58
+ "@genesislcap/genx": "{{versions.UI}}",
59
+ "@genesislcap/build-kit": "{{versions.UI}}",
60
+ "@testing-library/dom": "^10.4.0",
61
+ "@testing-library/jest-dom": "^6.5.0",
62
+ "@testing-library/react": "^16.0.0",
37
63
  "@types/node": "^20.14.10",
38
64
  "@types/react": "npm:types-react@alpha",
39
65
  "@types/react-dom": "npm:types-react-dom@alpha",
@@ -0,0 +1,17 @@
1
+ import { configDefaults } from '@genesislcap/foundation-testing/e2e';
2
+
3
+ export const PROTOCOL = process.env['PROTOCOL'] || 'http';
4
+ export const HOST = process.env['HOST'] || 'localhost';
5
+ export const PORT: number = Number(process.env['PORT']) || 5173;
6
+
7
+ export default {
8
+ ...configDefaults,
9
+ webServer: {
10
+ ...configDefaults.webServer,
11
+ url: `${PROTOCOL}://${HOST}:${PORT}`,
12
+ },
13
+ use: {
14
+ ...configDefaults.use,
15
+ baseURL: `${PROTOCOL}://${HOST}:${PORT}`,
16
+ }
17
+ };
@@ -1,36 +1,59 @@
1
- import React from 'react';
2
1
  import {
3
2
  unstable_HistoryRouter as HistoryRouter,
4
3
  Routes,
5
4
  Route,
6
5
  useLocation,
7
6
  } from 'react-router-dom';
8
- import history from './utils/history';
7
+ import { useEffect } from 'react';
8
+ import { history, setApiHost{{#if FDC3.channels.length}}, listenToChannel{{/if}} } from './utils';
9
9
  import LayoutWrapper from './layouts/LayoutWrapper';
10
- import { routeLayouts } from './config';
10
+ import { AUTH_PATH, NOT_PERMITTED_PATH, routeLayouts } from './config';
11
11
  import AuthGuard from './guards/AuthGuard';
12
+ import PermissionsGuard from './guards/PermissionsGuard';
12
13
  import { AuthProvider } from './store/AuthContext';
13
14
  // Pages Components
14
- import AuthPage from './pages/auth/AuthPage';
15
+ import AuthPage from './pages/AuthPage/AuthPage';
16
+ import NotPermittedPage from './pages/NotPermittedPage/NotPermittedPage';
15
17
  {{#each routes}}
16
18
  import {{pascalCase this.name}} from './pages/{{kebabCase this.name}}/{{pascalCase this.name}}';
17
19
  {{/each}}
20
+
18
21
  // Genesis Components
19
22
  import './share/genesis-components';
20
23
 
21
24
  const LayoutWithLocation = () => {
22
25
  const location = useLocation();
23
26
  const layout = routeLayouts[location.pathname] || 'default';
27
+ {{#if FDC3.channels.length}}
28
+ useEffect(() => {
29
+ {{#each FDC3.channels}}
30
+ listenToChannel('{{this.name}}', '{{this.type}}', (result) => {
31
+ console.log('Received FDC3 channel message on: {{this.name}} channel, type: {{this.type}}', result);
32
+ // TODO: Add your listener logic here
33
+ // E.g. open a modal or route to specific page: Route.path.push(`[Route name]`);
34
+ });
35
+ {{/each}}
36
+
37
+ return () => {
38
+ console.log('Component is being unmounted');
39
+ };
40
+ }, []);
41
+ {{/if}}
24
42
 
25
43
  let pageComponent;
44
+ let permissionCode = '{{this.permissions.viewRight}}';
26
45
 
27
46
  switch (location.pathname) {
28
- case '/auth':
47
+ case `/${AUTH_PATH}`:
29
48
  pageComponent = <AuthPage />;
30
49
  break;
50
+ case `/${NOT_PERMITTED_PATH}`:
51
+ pageComponent = <NotPermittedPage />;
52
+ break;
31
53
  {{#each routes}}
32
54
  case '/{{kebabCase this.name}}':
33
55
  pageComponent = <{{pascalCase this.name}} />;
56
+ permissionCode = '{{this.permissions.viewRight}}';
34
57
  break;
35
58
  {{/each}}
36
59
  default:
@@ -45,13 +68,17 @@ const LayoutWithLocation = () => {
45
68
  } else {
46
69
  return (
47
70
  <AuthGuard>
48
- <LayoutWrapper layout={layout}>{pageComponent}</LayoutWrapper>
71
+ <PermissionsGuard permissionCode={permissionCode}>
72
+ <LayoutWrapper layout={layout}>{pageComponent}</LayoutWrapper>
73
+ </PermissionsGuard>
49
74
  </AuthGuard>
50
75
  );
51
76
  }
52
77
  };
53
78
 
54
79
  const App: React.FC = () => {
80
+ setApiHost();
81
+
55
82
  return (
56
83
  <AuthProvider>
57
84
  <HistoryRouter history={history}>
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+
3
+ const styles = {
4
+ errorMessageWrapper: {
5
+ display: 'flex',
6
+ flexDirection: 'column',
7
+ justifyContent: 'center',
8
+ alignItems: 'center',
9
+ height: '100%',
10
+ width: '100%',
11
+ },
12
+ errorMessage: {
13
+ color: 'var(--neutral-foreground-rest)',
14
+ backgroundColor: 'var(--neutral-layer-4)',
15
+ borderColor: 'var(--error-color)',
16
+ borderRadius: '7px',
17
+ borderStyle: 'solid',
18
+ borderWidth: '4px',
19
+ padding: '5px',
20
+ margin: '15px',
21
+ textAlign: 'center',
22
+ width: 'fit-content',
23
+ alignSelf: 'center',
24
+ height: 'auto',
25
+ maxHeight: '100%'
26
+ },
27
+ };
28
+
29
+ const ErrorMessage = ({ elementType = 'div', message = '' }) => {
30
+ const ElementType = elementType;
31
+
32
+ return message && message !== '' && (
33
+ <section style={styles.errorMessageWrapper}>
34
+ <div style={styles.errorMessage}>
35
+ {(() => {
36
+ switch (ElementType) {
37
+ case 'h1':
38
+ return <h1>{message}</h1>;
39
+ case 'h2':
40
+ return <h2>{message}</h2>;
41
+ case 'h3':
42
+ return <h3>{message}</h3>;
43
+ case 'h4':
44
+ return <h4>{message}</h4>;
45
+ case 'h5':
46
+ return <h5>{message}</h5>;
47
+ case 'h6':
48
+ return <h6>{message}</h6>;
49
+ case 'p':
50
+ return <p>{message}</p>;
51
+ case 'span':
52
+ return <span>{message}</span>;
53
+ default:
54
+ return <div>{message}</div>;
55
+ }
56
+ })()}
57
+ </div>
58
+ </section>
59
+ );
60
+ };
61
+
62
+ export default ErrorMessage;
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import ErrorMessage from './ErrorMessage';
5
+
6
+ describe('ErrorMessage Component', () => {
7
+ const message = 'Test Error Message';
8
+
9
+ test('renders the message as a div by default', () => {
10
+ render(<ErrorMessage message={message} />);
11
+ const displayedMessage = screen.getByText(message);
12
+ expect(displayedMessage.tagName).toBe('DIV');
13
+ expect(displayedMessage).toBeInTheDocument();
14
+ });
15
+
16
+ test('renders the message as an h1 element when elementType is "h1"', () => {
17
+ render(<ErrorMessage message={message} elementType="h1" />);
18
+ const displayedMessage = screen.getByRole('heading', { level: 1 });
19
+ expect(displayedMessage.tagName).toBe('H1');
20
+ expect(displayedMessage).toBeInTheDocument();
21
+ });
22
+
23
+ test('renders the message as a p element when elementType is "p"', () => {
24
+ render(<ErrorMessage message={message} elementType="p" />);
25
+ const displayedMessage = screen.getByText(message);
26
+ expect(displayedMessage.tagName).toBe('P');
27
+ expect(displayedMessage).toBeInTheDocument();
28
+ });
29
+
30
+ test('applies the correct styles to the error message wrapper', () => {
31
+ render(<ErrorMessage message={message} />);
32
+ const wrapper = screen.getByText(message).closest('section');
33
+ expect(wrapper).toHaveStyle(`
34
+ display: flex;
35
+ flex-direction: column;
36
+ justify-content: center;
37
+ align-items: center;
38
+ height: 100%;
39
+ width: 100%;
40
+ `);
41
+ });
42
+
43
+ test('applies the correct styles to the error message itself', () => {
44
+ render(<ErrorMessage message={message} />);
45
+ const displayedMessage = screen.getByText(message);
46
+ const messageWrapper = displayedMessage.parentElement;
47
+
48
+ expect(messageWrapper).toBeInTheDocument();
49
+ expect(messageWrapper).toHaveStyle(`
50
+ color: var(--neutral-foreground-rest);
51
+ background-color: var(--neutral-layer-4);
52
+ border-color: var(--error-color);
53
+ border-radius: 7px;
54
+ border-style: solid;
55
+ border-width: 4px;
56
+ padding: 5px;
57
+ margin: 15px;
58
+ text-align: center;
59
+ width: fit-content;
60
+ align-self: center;
61
+ height: auto;
62
+ max-height: 100%;
63
+ `);
64
+ });
65
+
66
+ test('renders nothing if the message is an empty string', () => {
67
+ const { container } = render(<ErrorMessage message="" />);
68
+ expect(container.firstChild).toBeNull();
69
+ });
70
+
71
+ test('renders the correct element type for various elementType props', () => {
72
+ const elementTypes = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'span', 'div'];
73
+ elementTypes.forEach((elementType) => {
74
+ const { container } = render(<ErrorMessage message={message} elementType={elementType} />);
75
+ const displayedMessage = container.querySelector(elementType);
76
+ expect(displayedMessage).toBeInTheDocument();
77
+ expect(displayedMessage.tagName).toBe(elementType.toUpperCase());
78
+ });
79
+ });
80
+ });
@@ -9,9 +9,10 @@ export const routeLayouts: RouteLayouts = {
9
9
  import type { MainMenu } from './types/menu';
10
10
 
11
11
  export const AUTH_PATH = 'auth';
12
+ export const NOT_PERMITTED_PATH = 'not-permitted';
12
13
 
13
14
  export const API_DATA = {
14
- URL: '',
15
+ URL: import.meta.env.VITE_API_HOST,
15
16
  AUTH: {
16
17
  username: '', // provide login to a user in given environment
17
18
  password: '', // provide password to a user in given environment
@@ -1,7 +1,7 @@
1
1
  declare namespace JSX {
2
2
  interface IntrinsicElements {
3
3
  // Wildcard for all webcomponents:
4
- [elemName: string]: any;
4
+ [elemName: string]: unknown;
5
5
  }
6
6
  }
7
7
 
@@ -0,0 +1,37 @@
1
+ import { useEffect, useState, ReactNode } from 'react';
2
+ import { useNavigate } from 'react-router-dom';
3
+ import { getUser } from '@genesislcap/foundation-user';
4
+ import { NOT_PERMITTED_PATH } from '../config';
5
+
6
+ interface PermissionsGuardProps {
7
+ children: ReactNode;
8
+ permissionCode?: string;
9
+ }
10
+
11
+ const PermissionsGuard: React.FC<PermissionsGuardProps> = ({ children, permissionCode }: PermissionsGuardProps) => {
12
+ const navigate = useNavigate();
13
+ const [isAuthorized, setIsAuthorized] = useState(false);
14
+ const [isLoading, setIsLoading] = useState(true);
15
+
16
+ useEffect(() => {
17
+ const checkPermission = async () => {
18
+ const user = getUser();
19
+ if (permissionCode && !user.hasPermission(permissionCode)) {
20
+ navigate(`/${NOT_PERMITTED_PATH}`);
21
+ } else {
22
+ setIsAuthorized(true);
23
+ }
24
+ setIsLoading(false);
25
+ };
26
+
27
+ checkPermission();
28
+ }, [navigate, permissionCode]);
29
+
30
+ if (isLoading) {
31
+ return <div>Loading...</div>; // Or some loading component
32
+ }
33
+
34
+ return isAuthorized ? <>{children}</> : null;
35
+ };
36
+
37
+ export default PermissionsGuard;
@@ -0,0 +1,13 @@
1
+ import ErrorMessage from '../../components/ErrorMessage/ErrorMessage';
2
+ import './NotPermittedPage.css';
3
+
4
+ const NotPermittedPage = () => {
5
+ return (
6
+ <ErrorMessage
7
+ elementType="h1"
8
+ message="You do not have permission to access this part of the application, please contact your administrator."
9
+ ></ErrorMessage>
10
+ );
11
+ };
12
+
13
+ export default NotPermittedPage;
@@ -1,7 +1,7 @@
1
1
  import {configure, define} from '@genesislcap/foundation-login';
2
2
  import { AUTH_PATH } from '../config';
3
3
  import { DI } from '@microsoft/fast-foundation';
4
- import history from '../utils/history';
4
+ import { history } from '../utils/history';
5
5
 
6
6
  /**
7
7
  * Configure the micro frontend
@@ -1,4 +1,4 @@
1
1
  declare module '*.svg' {
2
- const content: any;
2
+ const content: string;
3
3
  export default content;
4
4
  }
@@ -0,0 +1,32 @@
1
+ {{#if FDC3.includeDependencies}}
2
+ import { DefaultFDC3 } from '@genesislcap/foundation-fdc3';
3
+ {{/if}}
4
+ export const isFDC3 = (): boolean => !!((window as unknown as { fdc3?: boolean }).fdc3);
5
+ {{#if FDC3.includeDependencies}}
6
+
7
+ export const onFDC3Ready = async (FDC3ReadyCb: () => any): Promise<void> => {
8
+ isFDC3()
9
+ ? await FDC3ReadyCb()
10
+ : window.addEventListener('fdc3Ready', async () => {
11
+ await FDC3ReadyCb();
12
+ });
13
+ };
14
+
15
+ export const listenToChannel = async (
16
+ channelName: string,
17
+ type: string,
18
+ callback: (result: any) => void,
19
+ ): Promise<void> => {
20
+ const fdc3Service = new DefaultFDC3();
21
+ fdc3Service.addChannelListener(channelName, type, callback);
22
+ };
23
+
24
+ export const sendEventOnChannel = (channelName: string, type: string) => {
25
+ return async (e: any) => {
26
+ const fdc3Service = new DefaultFDC3();
27
+ // check for ag-grid-specific events, fall back to standard events
28
+ const payload = e.data || e.detail;
29
+ await fdc3Service.broadcastOnChannel(channelName, type, payload);
30
+ };
31
+ };
32
+ {{/if}}
@@ -1,5 +1,3 @@
1
1
  import { createBrowserHistory } from 'history';
2
2
 
3
- const history = createBrowserHistory();
4
-
5
- export default history;
3
+ export const history = createBrowserHistory();
@@ -0,0 +1,4 @@
1
+ export * from './history';
2
+ export * from './fdc3';
3
+ export * from './permissions';
4
+ export * from './setApiHost';
@@ -0,0 +1,7 @@
1
+ import { User } from '@genesislcap/foundation-user';
2
+
3
+ export const getViewUpdateRightComponent = (
4
+ user: User,
5
+ right: string,
6
+ event: string | boolean = true,
7
+ ) => (!right || user.hasPermission(right) ? event : '');
@@ -0,0 +1,9 @@
1
+ import { API_DATA } from '../config';
2
+
3
+ export const setApiHost = () => {
4
+ const { URL: apiHost } = API_DATA;
5
+
6
+ if (apiHost) {
7
+ sessionStorage.setItem('hostUrl', apiHost);
8
+ }
9
+ };