@genesislcap/blank-app-seed 3.30.0-prerelease.1 → 3.30.0-prerelease.11

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 (45) hide show
  1. package/.genx/package.json +1 -1
  2. package/.genx/templates/react/chart.hbs +7 -3
  3. package/.genx/templates/react/component/component.column.defs.hbs +4 -2
  4. package/.genx/templates/react/component/component.create.form.hbs +2 -2
  5. package/.genx/templates/react/component/component.gridOptions.hbs +4 -2
  6. package/.genx/templates/react/component/component.hbs +64 -27
  7. package/.genx/templates/react/component/component.index.hbs +1 -1
  8. package/.genx/templates/react/component/component.update.form.hbs +1 -1
  9. package/.genx/templates/react/entityManager.hbs +62 -49
  10. package/.genx/templates/react/form.hbs +7 -3
  11. package/.genx/templates/react/grid.hbs +16 -10
  12. package/.genx/templates/react/route.hbs +1 -2
  13. package/.genx/templates/react/tabsLayout.hbs +5 -5
  14. package/.genx/utils/generateRoute.js +8 -7
  15. package/.genx/utils/generateTile.js +31 -16
  16. package/.genx/versions.json +3 -3
  17. package/.idea/modules.xml +6 -6
  18. package/CHANGELOG.md +70 -0
  19. package/client-tmp/react/.babelrc +10 -0
  20. package/client-tmp/react/.eslintrc.cjs +1 -0
  21. package/client-tmp/react/jest.config.ts +15 -0
  22. package/client-tmp/react/jest.setup.ts +1 -0
  23. package/client-tmp/react/lint-css.ts +19 -0
  24. package/client-tmp/react/package.json +18 -8
  25. package/client-tmp/react/src/App.tsx +1 -1
  26. package/client-tmp/react/src/components/{ErrorMessage.test.js → ErrorMessage/ErrorMessage.test.tsx} +31 -16
  27. package/client-tmp/react/src/components/ErrorMessage/{ErrorMessage.jsx → ErrorMessage.tsx} +9 -4
  28. package/client-tmp/react/src/custom-elements.d.ts +19 -9
  29. package/client-tmp/react/src/guards/AuthGuard.tsx +1 -1
  30. package/client-tmp/react/src/index.ts +21 -0
  31. package/client-tmp/react/src/pages/AuthPage/AuthPage.test.tsx +10 -0
  32. package/client-tmp/react/src/pages/AuthPage/{AuthPage.jsx → AuthPage.tsx} +3 -2
  33. package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.test.tsx +17 -0
  34. package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.tsx +14 -0
  35. package/client-tmp/react/src/{reportWebVitals.js → reportWebVitals.ts} +1 -1
  36. package/client-tmp/react/tsconfig.app.json +2 -5
  37. package/client-tmp/react/tsconfig.json +4 -1
  38. package/client-tmp/react/tsconfig.node.json +1 -1
  39. package/client-tmp/react/{vite.config.js → vite.config.ts} +9 -9
  40. package/package.json +1 -1
  41. package/server/settings.gradle.kts +2 -2
  42. package/client-tmp/react/lint-css.js +0 -18
  43. package/client-tmp/react/src/index.js +0 -17
  44. package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.jsx +0 -13
  45. /package/client-tmp/react/src/{setupTests.js → setupTests.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/blank-app-seed-config",
3
3
  "description": "Genesis Blank App Seed Configuration",
4
- "version": "3.30.0-prerelease.1",
4
+ "version": "3.30.0-prerelease.11",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "lint": "eslint .",
@@ -1,4 +1,6 @@
1
- {{#if config.permissions.viewRight}}hasUserPermission('{{config.permissions.viewRight}}') ? ({{/if}}
1
+ {{#if config.permissions.viewRight~}}
2
+ hasUserPermission('{{config.permissions.viewRight}}') ? (
3
+ {{/if}}
2
4
  <rapid-g2plot-chart
3
5
  type="{{ config.type }}"
4
6
  config={chartConfig}
@@ -7,7 +9,9 @@
7
9
  resourceName="{{ config.resourceName }}"
8
10
  server-fields="{{ config.xField }} {{ config.yField }}"
9
11
  ></chart-datasource>
10
- </rapid-g2plot-chart>{{#if config.permissions.viewRight}}
12
+ </rapid-g2plot-chart>
13
+ {{#if config.permissions.viewRight~}}
11
14
  ) : (
12
15
  <ErrorMessage elementType="h3" message="You do not have access to view this component." />
13
- ){{/if}}
16
+ )
17
+ {{/if}}
@@ -1,9 +1,11 @@
1
+ {{#if tile.config.columns~}}
1
2
  import { ColDef } from '@ag-grid-community/core';
3
+ {{/if}}
2
4
  import { getNumberFormatter, getDateFormatter } from '@genesislcap/foundation-utils';
3
- {{#if route.FDC3EventHandlersEnabled}}
5
+ {{#if route.FDC3EventHandlersEnabled~}}
4
6
  import { sendEventOnChannel } from '../../../utils';
5
7
  {{/if}}
6
8
 
7
- {{#if tile.config.columns}}
9
+ {{#if tile.config.columns~}}
8
10
  export const columnDefs: ColDef[] = {{{ tile.config.columns }}}
9
11
  {{/if}}
@@ -1,8 +1,8 @@
1
1
  import { UiSchema } from '@genesislcap/foundation-forms';
2
2
 
3
- {{#if tile.config.createFormUiSchema}}
3
+ {{#if tile.config.createFormUiSchema~}}
4
4
  export const createFormSchema: UiSchema = {{{ tile.config.createFormUiSchema }}}
5
5
  {{/if}}
6
- {{#if tile.config.uischema}}
6
+ {{#if tile.config.uischema~}}
7
7
  export const createFormSchema: UiSchema = {{{ tile.config.uischema }}}
8
8
  {{/if}}
@@ -1,9 +1,11 @@
1
+ {{#if tile.config.gridOptions~}}
1
2
  import { GridOptionsConfig } from '@genesislcap/rapid-grid-pro';
3
+ {{/if}}
2
4
  import { getNumberFormatter, getDateFormatter } from '@genesislcap/foundation-utils';
3
- {{#if route.FDC3EventHandlersEnabled}}
5
+ {{#if route.FDC3EventHandlersEnabled~}}
4
6
  import { sendEventOnChannel } from '../../../utils';
5
7
  {{/if}}
6
8
 
7
- {{#if tile.config.gridOptions}}
9
+ {{#if tile.config.gridOptions~}}
8
10
  export const gridOptions: GridOptionsConfig = {{{ tile.config.gridOptions }}}
9
11
  {{/if}}
@@ -1,40 +1,77 @@
1
+ {{#if tile.config.permissions.viewRight~}}
1
2
  import { getUser } from '@genesislcap/foundation-user';
2
3
  import { getViewUpdateRightComponent } from '../../../utils';
3
4
  import ErrorMessage from '../../../components/ErrorMessage/ErrorMessage';
4
- {{#if tile.config.createFormUiSchema}}
5
- import { createFormSchema as createFormSchemaTile } from './{{kebabCase tile.title}}.create.form.schema';
5
+ {{else if tile.config.permissions.updateRight~}}
6
+ import { getUser } from '@genesislcap/foundation-user';
7
+ import { getViewUpdateRightComponent } from '../../../utils';
8
+ import ErrorMessage from '../../../components/ErrorMessage/ErrorMessage';
9
+ {{/if}}
10
+ {{#if tile.config.createFormUiSchema~}}
11
+ import { createFormSchema as createFormSchemaTile } from './{{pascalCase tile.title}}CreateFormSchema';
6
12
  {{/if}}
7
- {{#if tile.config.uischema}}
8
- import { createFormSchema as createFormSchemaTile } from './{{kebabCase tile.title}}.create.form.schema';
13
+ {{#if tile.config.uischema~}}
14
+ import { createFormSchema as createFormSchemaTile } from './{{pascalCase tile.title}}CreateFormSchema';
9
15
  {{/if}}
10
- {{#if tile.config.updateFormUiSchema}}
11
- import { updateFormSchema as updateFormSchemaTile } from './{{kebabCase tile.title}}.update.form.schema';
16
+ {{#if tile.config.updateFormUiSchema~}}
17
+ import { updateFormSchema as updateFormSchemaTile } from './{{pascalCase tile.title}}UpdateFormSchema';
12
18
  {{/if}}
13
- {{#if tile.config.columns}}
14
- import { columnDefs as columnDefsTile } from './{{kebabCase tile.title}}.column.defs';
19
+ {{#if tile.config.columns~}}
20
+ import { columnDefs as columnDefsTile } from './{{pascalCase tile.title}}ColumnDefs';
15
21
  {{/if}}
16
- {{#if tile.config.gridOptions}}
17
- import { gridOptions as gridOptionsTile } from './{{kebabCase tile.title}}.gridOptions';
22
+ {{#if tile.config.gridOptions~}}
23
+ import { GridOptionsConfig } from '@genesislcap/rapid-grid-pro';
24
+ import { gridOptions as gridOptionsTile } from './{{pascalCase tile.title}}GridOptions';
18
25
  {{/if}}
19
- import './{{kebabCase tile.title}}.component.css';
26
+ import './{{pascalCase tile.title}}Component.css';
20
27
 
21
- export const {{pascalCase tile.componentName}} = () => {
22
- const hasUserPermission = (permissionCode) => getViewUpdateRightComponent(getUser(), permissionCode);{{#if tile.config.createFormUiSchema}}
23
- const createFormSchema = createFormSchemaTile;{{/if}}{{#if tile.config.uischema}}
24
- const uischema = createFormSchemaTile;{{/if}}{{#if tile.config.updateFormUiSchema}}
25
- const updateFormSchema = updateFormSchemaTile;{{/if}}{{#if tile.config.columns}}
26
- const columnDefs = columnDefsTile;{{/if}}{{#if tile.config.gridOptions}}
27
- const gridOptions = gridOptionsTile;{{/if}}{{#if tile.config.reqrep}}
28
- const reqrep = { pollingInterval: 5000 };{{/if}}{{#if tile.config.type}}
29
- const chartConfig = { {{#ifEquals tile.config.type 'pie'}}
30
- "radius": 0.75,
31
- "angleField": "value",
32
- "colorField": "groupBy",{{else}}
33
- "xField": "groupBy",
34
- "yField": "value",{{/ifEquals}}
35
- };{{/if}}
28
+ export const {{pascalCase tile.componentName}}: React.FC = () => {
29
+ {{#if tile.config.permissions.viewRight~}}
30
+ const hasUserPermission = (permissionCode: string): boolean => getViewUpdateRightComponent(getUser(), permissionCode);
31
+ {{else if tile.config.permissions.updateRight~}}
32
+ const hasUserPermission = (permissionCode: string): boolean => getViewUpdateRightComponent(getUser(), permissionCode);
33
+ {{/if}}
34
+ {{#if tile.config.createFormUiSchema~}}
35
+ const createFormSchema: typeof createFormSchemaTile = createFormSchemaTile;
36
+ {{/if}}
37
+ {{#if tile.config.uischema~}}
38
+ const uischema: typeof createFormSchemaTile = createFormSchemaTile;
39
+ {{/if}}
40
+ {{#if tile.config.updateFormUiSchema~}}
41
+ const updateFormSchema: typeof updateFormSchemaTile = updateFormSchemaTile;
42
+ {{/if}}
43
+ {{#if tile.config.columns~}}
44
+ const columnDefs: typeof columnDefsTile = columnDefsTile;
45
+ {{/if}}
46
+ {{#if tile.config.gridOptions~}}
47
+ const deferredGridOptions: { onRowClicked: GridOptionsConfig.onRowClicked } = { onRowClicked: gridOptionsTile?.onRowClicked }
48
+ {{/if}}
49
+ {{#if tile.config.reqrep~}}
50
+ const reqrep: { pollingInterval: number } = { pollingInterval: 5000 };
51
+ {{/if}}
52
+ {{#if tile.config.type~}}
53
+ const chartConfig: {
54
+ {{#ifEquals tile.config.type 'pie'~}}
55
+ radius: number;
56
+ angleField: string;
57
+ colorField: string;
58
+ {{else~}}
59
+ xField: string;
60
+ yField: string;
61
+ {{/ifEquals}}
62
+ } = {
63
+ {{#ifEquals tile.config.type 'pie'~}}
64
+ radius: 0.75,
65
+ angleField: 'value',
66
+ colorField: 'groupBy',
67
+ {{else~}}
68
+ xField: 'groupBy',
69
+ yField: 'value',
70
+ {{/ifEquals}}
71
+ };
72
+ {{/if}}
36
73
 
37
74
  return (
38
75
  {{> (lookup tile 'type') tile}}
39
76
  );
40
- };
77
+ };
@@ -1 +1 @@
1
- export * from './{{kebabCase tile.title}}.component.jsx';
1
+ export * from './{{pascalCase tile.title}}Component.tsx';
@@ -1,5 +1,5 @@
1
1
  import { UiSchema } from '@genesislcap/foundation-forms';
2
2
 
3
- {{#if tile.config.updateFormUiSchema}}
3
+ {{#if tile.config.updateFormUiSchema~}}
4
4
  export const updateFormSchema: UiSchema = {{{ tile.config.updateFormUiSchema }}}
5
5
  {{/if}}
@@ -1,52 +1,65 @@
1
- {{#if config.permissions.viewRight}}hasUserPermission('{{config.permissions.viewRight}}') ? ({{/if}}
1
+ {{#if config.permissions.viewRight~}}
2
+ hasUserPermission('{{config.permissions.viewRight}}') ? (
3
+ {{/if}}
2
4
  <entity-management
3
- design-system-prefix="rapid"
4
- enable-row-flashing
5
- enable-cell-flashing
6
- {{#if config.title}}
7
- title="{{ config.title }}"
8
- {{/if}}
9
- resourceName="{{ config.resourceName }}"
10
- {{#if config.createEvent}}
11
- createEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.createEvent }}' : undefined}
12
- {{#if config.createFormUiSchema}}
13
- createFormUiSchema={createFormSchema}
14
- {{/if}}
15
- {{/if}}
16
- {{#if config.updateEvent}}
17
- updateEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.updateEvent }}' : undefined}
18
- {{#if config.updateFormUiSchema}}
19
- updateFormUiSchema={updateFormSchema}
20
- {{/if}}
21
- {{/if}}
22
- {{#if config.deleteEvent}}
23
- deleteEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.deleteEvent }}' : undefined}
24
- {{/if}}
25
- {{#if config.gridOptions}}
26
- gridOptions={gridOptions}
27
- {{/if}}
28
- {{#if config.snapshot}}
29
- datasourceConfig={ isSnapshot: {{ config.snapshot }} }
30
- {{/if}}
31
- {{#if config.reqrep}}
32
- datasourceConfig={reqrep}
33
- {{/if}}
34
- {{#if config.entityName}}
35
- entityLabel="{{ config.entityName }}"
36
- {{/if}}
37
- {{#if config.columns}}
38
- columns={columnDefs}
39
- {{/if}}
40
- {{#if config.modalPosition}}
41
- modal-position="{{ config.modalPosition }}"
42
- {{/if}}
43
- {{#if config.sizeColumnsToFit}}
44
- size-columns-to-fit
45
- {{/if}}
46
- {{#if config.enableSearchBar}}
47
- enable-search-bar
48
- {{/if}}
49
- ></entity-management>{{#if config.permissions.viewRight}}
5
+ design-system-prefix="rapid"
6
+ enable-row-flashing
7
+ enable-cell-flashing
8
+ {{#if config.title~}}
9
+ title="{{ config.title }}"
10
+ {{/if}}
11
+ resourceName="{{ config.resourceName }}"
12
+ {{#if config.createEvent~}}
13
+ {{#if config.permissions.updateRight~}}
14
+ createEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.createEvent }}' : undefined}
15
+ {{else~}}
16
+ createEvent="{{ config.updateEvent }}"
17
+ {{/if}}
18
+ {{#if config.createFormUiSchema~}}
19
+ createFormUiSchema={createFormSchema}
20
+ {{/if}}
21
+ {{/if}}
22
+ {{#if config.updateEvent~}}
23
+ {{#if config.permissions.updateRight~}}
24
+ updateEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.updateEvent }}' : undefined}
25
+ {{else~}}
26
+ updateEvent="{{ config.updateEvent }}"
27
+ {{/if}}
28
+ {{#if config.updateFormUiSchema~}}
29
+ updateFormUiSchema={updateFormSchema}
30
+ {{/if}}
31
+ {{/if}}
32
+ {{#if config.deleteEvent~}}
33
+ {{#if config.permissions.updateRight~}}
34
+ deleteEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.deleteEvent }}' : undefined}
35
+ {{else~}}
36
+ deleteEvent="{{ config.deleteEvent }}"
37
+ {{/if}}
38
+ {{/if}}
39
+ {{#if config.gridOptions~}}
40
+ gridOptions={gridOptions}
41
+ {{/if}}
42
+ {{#if config.snapshot~}}
43
+ datasourceConfig={ isSnapshot: {{ config.snapshot }} }
44
+ {{/if}}
45
+ {{#if config.reqrep~}}
46
+ datasourceConfig={reqrep}
47
+ {{/if}}
48
+ {{#if config.columns~}}
49
+ columns={columnDefs}
50
+ {{/if}}
51
+ {{#if config.modalPosition~}}
52
+ modal-position="{{ config.modalPosition }}"
53
+ {{/if}}
54
+ {{#if config.sizeColumnsToFit~}}
55
+ size-columns-to-fit
56
+ {{/if}}
57
+ {{#if config.enableSearchBar~}}
58
+ enable-search-bar
59
+ {{/if}}
60
+ ></entity-management>
61
+ {{#if config.permissions.viewRight~}}
50
62
  ) : (
51
63
  <ErrorMessage elementType="h3" message="You do not have access to view this component." />
52
- ){{/if}}
64
+ )
65
+ {{/if}}
@@ -1,4 +1,6 @@
1
- {{#if config.permissions.updateRight}}hasUserPermission('{{config.permissions.updateRight}}') ? ({{/if}}
1
+ {{#if config.permissions.updateRight~}}
2
+ hasUserPermission('{{config.permissions.updateRight}}') ? (
3
+ {{/if}}
2
4
  <foundation-form
3
5
  design-system-prefix="rapid"
4
6
  resourceName="{{config.resourceName}}"
@@ -6,7 +8,9 @@
6
8
  uischema={uischema}
7
9
  {{/if}}
8
10
  >
9
- </foundation-form>{{#if config.permissions.updateRight}}
11
+ </foundation-form>
12
+ {{#if config.permissions.updateRight~}}
10
13
  ) : (
11
14
  <ErrorMessage elementType="h3" message="You do not have access to view this component." />
12
- ){{/if}}
15
+ )
16
+ {{/if}}
@@ -1,28 +1,34 @@
1
- {{#if config.permissions.viewRight}}hasUserPermission('{{config.permissions.viewRight}}') ? ({{/if}}
1
+ {{#if config.permissions.viewRight~}}
2
+ hasUserPermission('{{config.permissions.viewRight}}') ? (
3
+ {{/if}}
2
4
  <rapid-grid-pro
3
- header-case-type="capitalCase"{{#if config.useOnlyTemplateCols}}
4
- only-template-col-defs{{/if}}
5
+ header-case-type="capitalCase"
6
+ {{#if config.useOnlyTemplateCols~}}
7
+ only-template-col-defs
8
+ {{/if}}
5
9
  enable-row-flashing
6
10
  enable-cell-flashing
7
11
  >
8
12
  <grid-pro-genesis-datasource
9
13
  resource-name="{{config.resourceName}}"
10
- {{#if config.snapshot}}
14
+ {{#if config.snapshot~}}
11
15
  isSnapshot="{{config.snapshot}}"
12
16
  {{/if}}
13
- {{#if config.reqrep}}
17
+ {{#if config.reqrep~}}
14
18
  datasourceConfig="reqrep"
15
19
  {{/if}}
16
- {{#if config.gridOptions}}
17
- deferredGridOptions=\{{ onRowClicked: gridOptions?.onRowClicked }}
20
+ {{#if config.gridOptions~}}
21
+ deferredGridOptions={deferredGridOptions}
18
22
  {{/if}}
19
23
  ></grid-pro-genesis-datasource>
20
24
  {{#if config.gridOptions}}
21
- {gridOptions?.columnDefs?.map((columnDef, index) => (
25
+ {gridOptionsTile?.columnDefs?.map((columnDef, index) => (
22
26
  <grid-pro-column key={index} definition={columnDef}></grid-pro-column>
23
27
  ))}
24
28
  {{/if}}
25
- </rapid-grid-pro>{{#if config.permissions.viewRight}}
29
+ </rapid-grid-pro>
30
+ {{#if config.permissions.viewRight~}}
26
31
  ) : (
27
32
  <ErrorMessage elementType="h3" message="You do not have access to view this component." />
28
- ){{/if}}
33
+ )
34
+ {{/if}}
@@ -1,10 +1,9 @@
1
1
  import './{{pascalCase route.name}}.css';
2
2
  {{#each route.tiles}}
3
- import { {{pascalCase this.componentName}} } from './{{kebabCase this.title}}-{{this.componentType}}';
3
+ import { {{pascalCase this.componentName}} } from './{{pascalCase this.title}}{{pascalCase this.componentType}}';
4
4
  {{/each}}
5
5
 
6
6
  const {{pascalCase route.name}} = () => {
7
-
8
7
  return (
9
8
  <section className="{{kebabCase route.name}}-page">
10
9
  {{#if route.tiles}}
@@ -1,7 +1,7 @@
1
1
  <rapid-layout-region type="tabs">
2
- {{#each route.tiles}}
3
- <rapid-layout-item title="{{this.title}}">
4
- {{> (lookup . 'type') }}
5
- </rapid-layout-item>
6
- {{/each}}
2
+ {{#each route.tiles}}
3
+ <rapid-layout-item title="{{this.title}}">
4
+ {{> (lookup . 'type') }}
5
+ </rapid-layout-item>
6
+ {{/each}}
7
7
  </rapid-layout-region>
@@ -14,7 +14,7 @@ const getPathByFramework = {
14
14
  route: (clientSrcPath, routeName) => `${clientSrcPath}/${routeName}`,
15
15
  component: (routeDir, routeName) => `${routeDir}/${routeName}.ts`,
16
16
  template: (routeDir, routeName) => `${routeDir}/${routeName}.template.ts`,
17
- style: (routePath, routeName) => `${routePath}/${routeName}.styles.ts`,
17
+ style: (routeDir, routeName) => `${routeDir}/${routeName}.styles.ts`,
18
18
  },
19
19
  [FRAMEWORK_ANGULAR_ALIAS]: {
20
20
  clientSrcPath: `../../client/src/app/pages`,
@@ -22,15 +22,16 @@ const getPathByFramework = {
22
22
  component: (routeDir, routeName) => `${routeDir}/${routeName}.component.ts`,
23
23
  template: (routeDir, routeName) =>
24
24
  `${routeDir}/${routeName}.component.html`,
25
- style: (routePath, routeName) => `${routePath}/${routeName}.component.css`,
25
+ style: (routeDir, routeName) => `${routeDir}/${routeName}.component.css`,
26
26
  },
27
27
  [FRAMEWORK_REACT_ALIAS]: {
28
28
  clientSrcPath: `../../client/src/pages`,
29
- route: (clientSrcPath, routeName) => `${clientSrcPath}/${routeName}`,
29
+ route: (clientSrcPath, routeName, changeCase) =>
30
+ `${clientSrcPath}/${changeCase.pascalCase(routeName)}`,
30
31
  component: (routeDir, routeName, changeCase) =>
31
- `${routeDir}/${changeCase.pascalCase(routeName)}.jsx`,
32
- style: (routePath, routeName, changeCase) =>
33
- `${routePath}/${changeCase.pascalCase(routeName)}.css`,
32
+ `${routeDir}/${changeCase.pascalCase(routeName)}.tsx`,
33
+ style: (routeDir, routeName, changeCase) =>
34
+ `${routeDir}/${changeCase.pascalCase(routeName)}.css`,
34
35
  },
35
36
  };
36
37
 
@@ -44,7 +45,7 @@ const generateRoute = (route, { changeCase, writeFileWithData }, framework) => {
44
45
  } = getPathByFramework[framework];
45
46
  const routeName = changeCase.paramCase(route.name);
46
47
  const sourceTemplateDir = `../${DIR_TEMPLATE_BY_FRAMEWORK[framework]}`;
47
- const routeDir = getRouteDir(clientSrcPath, routeName);
48
+ const routeDir = getRouteDir(clientSrcPath, routeName, changeCase);
48
49
 
49
50
  const filesToWrite = [
50
51
  {
@@ -44,18 +44,32 @@ const getPathByFramework = {
44
44
  },
45
45
  [FRAMEWORK_REACT_ALIAS]: {
46
46
  ...defaultPathGetters,
47
- index: (componentPath) => `${componentPath}/index.jsx`,
47
+ index: (componentPath) => `${componentPath}/index.tsx`,
48
48
  clientSrcPath: `../../client/src/pages`,
49
- route: (clientSrcPath, tile, routeName) =>
50
- `${clientSrcPath}/${routeName}/${tile.name}-${tile.componentType}`,
51
- component: (componentPath, tile) =>
52
- `${componentPath}/${tile.name}.component.jsx`,
53
- style: (componentPath, tile) =>
54
- `${componentPath}/${tile.name}.component.css`,
49
+ route: (clientSrcPath, tile, routeName, changeCase) =>
50
+ `${clientSrcPath}/${changeCase.pascalCase(routeName)}/${changeCase.pascalCase(tile.name)}${changeCase.pascalCase(tile.componentType)}`,
51
+ component: (componentPath, tile, changeCase) =>
52
+ `${componentPath}/${changeCase.pascalCase(tile.name)}Component.tsx`,
53
+ style: (componentPath, tile, changeCase) =>
54
+ `${componentPath}/${changeCase.pascalCase(tile.name)}Component.css`,
55
+ addForm: (componentPath, tile, changeCase) =>
56
+ `${componentPath}/${changeCase.pascalCase(tile.name)}CreateFormSchema.ts`,
57
+ updateForm: (componentPath, tile, changeCase) =>
58
+ `${componentPath}/${changeCase.pascalCase(tile.name)}UpdateFormSchema.ts`,
59
+ columnDefs: (componentPath, tile, changeCase) =>
60
+ `${componentPath}/${changeCase.pascalCase(tile.name)}ColumnDefs.ts`,
61
+ gridOptions: (componentPath, tile, changeCase) =>
62
+ `${componentPath}/${changeCase.pascalCase(tile.name)}GridOptions.ts`,
55
63
  },
56
64
  };
57
65
 
58
- const getFilesToWrite = (tileData, routeName, path, sourceTemplateDir) => {
66
+ const getFilesToWrite = (
67
+ tileData,
68
+ routeName,
69
+ path,
70
+ sourceTemplateDir,
71
+ changeCase,
72
+ ) => {
59
73
  const {
60
74
  clientSrcPath,
61
75
  route: getRouteDir,
@@ -69,7 +83,7 @@ const getFilesToWrite = (tileData, routeName, path, sourceTemplateDir) => {
69
83
  gridOptions: getGridOptionsTarget,
70
84
  } = path;
71
85
 
72
- const routeDir = getRouteDir(clientSrcPath, tileData, routeName);
86
+ const routeDir = getRouteDir(clientSrcPath, tileData, routeName, changeCase);
73
87
 
74
88
  const componentIndexFile = {
75
89
  source: `${sourceTemplateDir}/component/component.index.hbs`,
@@ -78,32 +92,32 @@ const getFilesToWrite = (tileData, routeName, path, sourceTemplateDir) => {
78
92
 
79
93
  const componentFile = {
80
94
  source: `${sourceTemplateDir}/component/component.hbs`,
81
- target: getComponentTarget(routeDir, tileData),
95
+ target: getComponentTarget(routeDir, tileData, changeCase),
82
96
  };
83
97
 
84
98
  const componentStylesFile = {
85
99
  source: `${sourceTemplateDir}/component/component.styles.hbs`,
86
- target: getStyleTarget(routeDir, tileData),
100
+ target: getStyleTarget(routeDir, tileData, changeCase),
87
101
  };
88
102
 
89
103
  const componentAddFormFile = {
90
104
  source: `${sourceTemplateDir}/component/component.create.form.hbs`,
91
- target: getAddFormTarget(routeDir, tileData),
105
+ target: getAddFormTarget(routeDir, tileData, changeCase),
92
106
  };
93
107
 
94
108
  const componentUpdateFormFile = {
95
109
  source: `${sourceTemplateDir}/component/component.update.form.hbs`,
96
- target: getUpdateFormTarget(routeDir, tileData),
110
+ target: getUpdateFormTarget(routeDir, tileData, changeCase),
97
111
  };
98
112
 
99
113
  const componentColumnsFile = {
100
114
  source: `${sourceTemplateDir}/component/component.column.defs.hbs`,
101
- target: getColumnDefsTarget(routeDir, tileData),
115
+ target: getColumnDefsTarget(routeDir, tileData, changeCase),
102
116
  };
103
117
 
104
118
  const componentGridOptionsFile = {
105
119
  source: `${sourceTemplateDir}/component/component.gridOptions.hbs`,
106
- target: getGridOptionsTarget(routeDir, tileData),
120
+ target: getGridOptionsTarget(routeDir, tileData, changeCase),
107
121
  };
108
122
 
109
123
  const filesToWrite = [componentIndexFile, componentFile, componentStylesFile];
@@ -160,13 +174,14 @@ const generateTile = (
160
174
  const routeName = changeCase.paramCase(route.name);
161
175
  const sourceTemplateDir = `../${DIR_TEMPLATE_BY_FRAMEWORK[framework]}`;
162
176
  const { clientSrcPath, route: getRouteDir } = getPathByFramework[framework];
163
- const routeDir = getRouteDir(clientSrcPath, tileData, routeName);
177
+ const routeDir = getRouteDir(clientSrcPath, tileData, routeName, changeCase);
164
178
 
165
179
  const filesToWrite = getFilesToWrite(
166
180
  tileData,
167
181
  routeName,
168
182
  getPathByFramework[framework],
169
183
  sourceTemplateDir,
184
+ changeCase,
170
185
  );
171
186
 
172
187
  makeDirectory(resolve(__dirname, routeDir));
@@ -1,5 +1,5 @@
1
1
  {
2
- "UI": "14.206.1",
3
- "GSF": "8.3.0-beta5",
4
- "Auth": "8.3.0-beta5"
2
+ "UI": "14.208.0",
3
+ "GSF": "TESTBETA-1.0.0-beta1",
4
+ "Auth": "8.4.0-beta1"
5
5
  }
package/.idea/modules.xml CHANGED
@@ -2,12 +2,12 @@
2
2
  <project version="4">
3
3
  <component name="ProjectModuleManager">
4
4
  <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.main.iml" />
6
- <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-fields/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-fields.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-fields/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-fields.main.iml" />
7
- <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-dao/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-dao.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-dao/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-dao.main.iml" />
8
- <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-view/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-view.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-view/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-view.main.iml" />
9
- <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-hft/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-hft.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-hft/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-hft.main.iml" />
10
- <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-sysdef/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-sysdef.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-sysdef/genesisproduct-{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-sysdef.main.iml" />
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}.{{appName}}-dictionary-cache.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}.{{appName}}-dictionary-cache.main.iml" />
6
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-fields/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-fields.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-fields/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-fields.main.iml" />
7
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-dao/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-dao.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-dao/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-dao.main.iml" />
8
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-view/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-view.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-view/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-view.main.iml" />
9
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-hft/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-hft.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-hft/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-hft.main.iml" />
10
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-sysdef/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-sysdef.main.iml" filepath="$PROJECT_DIR$/.idea/modules/server/build/internal-modules/{{appName}}-dictionary-cache/{{appName}}-generated-sysdef/{{appName}}.{{appName}}-dictionary-cache.{{appName}}-generated-sysdef.main.iml" />
11
11
  </modules>
12
12
  </component>
13
13
  </project>
package/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.30.0-prerelease.11](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.10...v3.30.0-prerelease.11) (2024-09-18)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * updating server version information for GSF [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) eabf8c7
9
+
10
+ ## [3.30.0-prerelease.10](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.9...v3.30.0-prerelease.10) (2024-09-13)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#342) d255814
16
+
17
+ ## [3.30.0-prerelease.9](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.8...v3.30.0-prerelease.9) (2024-09-12)
18
+
19
+
20
+ ### Features
21
+
22
+ * integrate TypeScript support into react - [FUI-2157](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/2157) (#338) ac55e1f
23
+
24
+ ## [3.30.0-prerelease.8](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.7...v3.30.0-prerelease.8) (2024-09-11)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * updating server version information for Auth [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) 09ba9a2
30
+
31
+ ## [3.30.0-prerelease.7](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.6...v3.30.0-prerelease.7) (2024-09-11)
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * updating server version information for GSF [PSD-0](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/0) 5d4f8da
37
+
38
+ ## [3.30.0-prerelease.6](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.5...v3.30.0-prerelease.6) (2024-09-10)
39
+
40
+
41
+ ### Features
42
+
43
+ * product name specified with settings plugin property (#331) 082cea0
44
+
45
+ ## [3.30.0-prerelease.5](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.4...v3.30.0-prerelease.5) (2024-09-09)
46
+
47
+
48
+ ### Bug Fixes
49
+
50
+ * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#341) 1d38563
51
+
52
+ ## [3.30.0-prerelease.4](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.3...v3.30.0-prerelease.4) (2024-09-06)
53
+
54
+
55
+ ### Features
56
+
57
+ * add unit tests - [FUI-2173](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/2173) (#332) a4168f3
58
+
59
+ ## [3.30.0-prerelease.3](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.30.0-prerelease.2...v3.30.0-prerelease.3) (2024-09-06)
60
+
61
+
62
+ ### Bug Fixes
63
+
64
+ * update GSF and Auth dependency versions [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#336) d5d69e6
65
+
66
+ ## [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)
67
+
68
+
69
+ ### Bug Fixes
70
+
71
+ * automated dependency version update [skip-ci] [PSD-9](https://github.com/genesiscommunitysuccess/blank-app-seed/issues/9) (#334) 3af309b
72
+
3
73
  ## [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)
4
74
 
5
75
 
@@ -0,0 +1,10 @@
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env",
4
+ "@babel/preset-react",
5
+ "@babel/preset-typescript"
6
+ ],
7
+ "plugins": [
8
+ "react-require"
9
+ ]
10
+ }
@@ -10,6 +10,7 @@ module.exports = {
10
10
  parser: '@typescript-eslint/parser',
11
11
  plugins: ['react-refresh'],
12
12
  rules: {
13
+ '@typescript-eslint/no-explicit-any': 'off',
13
14
  '@typescript-eslint/no-unused-vars': 'off',
14
15
  '@typescript-eslint/no-var-requires': 'off',
15
16
  'react-refresh/only-export-components': [
@@ -0,0 +1,15 @@
1
+ import type { Config } from '@jest/types';
2
+
3
+ const config: Config.InitialOptions = {
4
+ testEnvironment: 'jsdom',
5
+ moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],
6
+ transform: {
7
+ '^.+\\.jsx?$': 'babel-jest',
8
+ '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.app.json' }],
9
+ },
10
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
11
+ testMatch: ["**/?(*.)+(test).[jt]s?(x)"],
12
+ watchPathIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/dist/"],
13
+ };
14
+
15
+ export default config;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,19 @@
1
+ import { execSync } from 'child_process';
2
+ import glob from 'glob';
3
+ import path from 'path';
4
+
5
+ const cssFiles: string[] = glob.sync(path.join(__dirname, '**/*.css'));
6
+
7
+ if (cssFiles.length === 0) {
8
+ console.log('No CSS files found.');
9
+ process.exit(0);
10
+ }
11
+
12
+ const command: string = `genx lint -l stylelint ${cssFiles.join(' ')}`;
13
+
14
+ try {
15
+ execSync(command, { stdio: 'inherit' });
16
+ } catch (error) {
17
+ console.error('Error running stylelint:', error);
18
+ process.exit(1);
19
+ }
@@ -15,16 +15,16 @@
15
15
  "dev:intellij": "npm run dev",
16
16
  "dev:https": "HTTPS=true npm run dev",
17
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",
18
+ "lint": "eslint src/**/*.ts src/**/*.tsx",
19
+ "lint:fix": "eslint src/**/*.ts src/**/*.tsx --fix",
20
20
  "lint:eslint": "npm lint",
21
- "lint:stylelint": "node lint-css.js",
22
- "test": "genx test",
21
+ "lint:stylelint": "npx ts-node lint-css.ts",
22
+ "test": "jest",
23
+ "test:coverage": "jest --coverage",
24
+ "test:unit:watch": "jest --watchAll",
23
25
  "test:e2e": "genx test --e2e",
24
26
  "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"
27
+ "test:e2e:ui": "genx test --e2e --interactive"
28
28
  },
29
29
  "dependencies": {
30
30
  "@ag-grid-community/client-side-row-model": "29.2.0",
@@ -48,9 +48,13 @@
48
48
  "history": "^5.3.0",
49
49
  "react": "^19.0.0-beta-94eed63c49-20240425",
50
50
  "react-dom": "^19.0.0-beta-94eed63c49-20240425",
51
- "react-router-dom": "6.24.1"
51
+ "react-router-dom": "6.24.1",
52
+ "web-vitals": "^2.1.4"
52
53
  },
53
54
  "devDependencies": {
55
+ "@babel/core": "^7.25.2",
56
+ "@babel/preset-env": "^7.25.4",
57
+ "@babel/preset-react": "^7.24.7",
54
58
  "@genesislcap/design-system-configurator": "{{versions.UI}}",
55
59
  "@genesislcap/eslint-config": "{{versions.UI}}",
56
60
  "@genesislcap/prettier-config": "{{versions.UI}}",
@@ -60,15 +64,21 @@
60
64
  "@testing-library/dom": "^10.4.0",
61
65
  "@testing-library/jest-dom": "^6.5.0",
62
66
  "@testing-library/react": "^16.0.0",
67
+ "@types/jest": "^29.5.12",
63
68
  "@types/node": "^20.14.10",
64
69
  "@types/react": "npm:types-react@alpha",
65
70
  "@types/react-dom": "npm:types-react-dom@alpha",
66
71
  "@typescript-eslint/eslint-plugin": "^7.13.1",
67
72
  "@typescript-eslint/parser": "^7.13.1",
68
73
  "@vitejs/plugin-react": "^4.3.1",
74
+ "babel-plugin-react-require": "^4.0.3",
69
75
  "eslint": "^8.57.0",
70
76
  "eslint-plugin-react-hooks": "^4.6.2",
71
77
  "eslint-plugin-react-refresh": "^0.4.7",
78
+ "jest": "^29.7.0",
79
+ "jest-environment-jsdom": "^29.7.0",
80
+ "ts-jest": "^29.2.5",
81
+ "ts-node": "^10.9.2",
72
82
  "typescript": "^5.2.2",
73
83
  "vite": "^5.3.1"
74
84
  },
@@ -15,7 +15,7 @@ import { AuthProvider } from './store/AuthContext';
15
15
  import AuthPage from './pages/AuthPage/AuthPage';
16
16
  import NotPermittedPage from './pages/NotPermittedPage/NotPermittedPage';
17
17
  {{#each routes}}
18
- import {{pascalCase this.name}} from './pages/{{kebabCase this.name}}/{{pascalCase this.name}}';
18
+ import {{pascalCase this.name}} from './pages/{{pascalCase this.name}}/{{pascalCase this.name}}';
19
19
  {{/each}}
20
20
 
21
21
  // Genesis Components
@@ -1,35 +1,33 @@
1
- import React from 'react';
2
1
  import { render, screen } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
- import ErrorMessage from './ErrorMessage';
2
+ import { default as ErrorMessage, ErrorMessageProps } from './ErrorMessage';
5
3
 
6
4
  describe('ErrorMessage Component', () => {
7
- const message = 'Test Error Message';
5
+ const message: string = 'Test Error Message';
8
6
 
9
7
  test('renders the message as a div by default', () => {
10
8
  render(<ErrorMessage message={message} />);
11
- const displayedMessage = screen.getByText(message);
9
+ const displayedMessage: HTMLElement = screen.getByText(message);
12
10
  expect(displayedMessage.tagName).toBe('DIV');
13
11
  expect(displayedMessage).toBeInTheDocument();
14
12
  });
15
13
 
16
14
  test('renders the message as an h1 element when elementType is "h1"', () => {
17
15
  render(<ErrorMessage message={message} elementType="h1" />);
18
- const displayedMessage = screen.getByRole('heading', { level: 1 });
16
+ const displayedMessage: HTMLElement = screen.getByRole('heading', { level: 1 });
19
17
  expect(displayedMessage.tagName).toBe('H1');
20
18
  expect(displayedMessage).toBeInTheDocument();
21
19
  });
22
20
 
23
21
  test('renders the message as a p element when elementType is "p"', () => {
24
22
  render(<ErrorMessage message={message} elementType="p" />);
25
- const displayedMessage = screen.getByText(message);
23
+ const displayedMessage: HTMLElement = screen.getByText(message);
26
24
  expect(displayedMessage.tagName).toBe('P');
27
25
  expect(displayedMessage).toBeInTheDocument();
28
26
  });
29
27
 
30
28
  test('applies the correct styles to the error message wrapper', () => {
31
29
  render(<ErrorMessage message={message} />);
32
- const wrapper = screen.getByText(message).closest('section');
30
+ const wrapper: HTMLElement | null = screen.getByText(message).closest('section');
33
31
  expect(wrapper).toHaveStyle(`
34
32
  display: flex;
35
33
  flex-direction: column;
@@ -42,8 +40,8 @@ describe('ErrorMessage Component', () => {
42
40
 
43
41
  test('applies the correct styles to the error message itself', () => {
44
42
  render(<ErrorMessage message={message} />);
45
- const displayedMessage = screen.getByText(message);
46
- const messageWrapper = displayedMessage.parentElement;
43
+ const displayedMessage: HTMLElement = screen.getByText(message);
44
+ const messageWrapper: HTMLElement | null = displayedMessage.parentElement;
47
45
 
48
46
  expect(messageWrapper).toBeInTheDocument();
49
47
  expect(messageWrapper).toHaveStyle(`
@@ -64,17 +62,34 @@ describe('ErrorMessage Component', () => {
64
62
  });
65
63
 
66
64
  test('renders nothing if the message is an empty string', () => {
67
- const { container } = render(<ErrorMessage message="" />);
65
+ const { container }: { container: HTMLElement } = render(<ErrorMessage message="" />);
68
66
  expect(container.firstChild).toBeNull();
69
67
  });
70
68
 
71
69
  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);
70
+ const elementTypes: ErrorMessageProps['elementType'][] = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'span', 'div'];
71
+ elementTypes.forEach((elementType: ErrorMessageProps['elementType']) => {
72
+ const { container }: { container: HTMLElement } = render(<ErrorMessage message={message} elementType={elementType} />);
73
+ const displayedMessage: HTMLElement | null = container.querySelector(elementType as string);
76
74
  expect(displayedMessage).toBeInTheDocument();
77
- expect(displayedMessage.tagName).toBe(elementType.toUpperCase());
75
+ expect(displayedMessage?.tagName).toBe((elementType as string).toUpperCase());
78
76
  });
79
77
  });
78
+
79
+ test('renders the message as a div element when elementType is unknown', () => {
80
+ render(<ErrorMessage message={message} />);
81
+ const displayedMessage: HTMLElement = screen.getByText(message);
82
+ expect(displayedMessage.tagName).toBe('DIV');
83
+ expect(displayedMessage).toBeInTheDocument();
84
+ });
85
+
86
+ test('renders nothing if the message is null', () => {
87
+ const { container }: { container: HTMLElement } = render(<ErrorMessage />);
88
+ expect(container.firstChild).toBeNull();
89
+ });
90
+
91
+ test('renders nothing if the message is undefined', () => {
92
+ const { container }: { container: HTMLElement } = render(<ErrorMessage message={undefined} />);
93
+ expect(container.firstChild).toBeNull();
94
+ });
80
95
  });
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  const styles = {
4
4
  errorMessageWrapper: {
5
5
  display: 'flex',
6
- flexDirection: 'column',
6
+ flexDirection: 'column' as const,
7
7
  justifyContent: 'center',
8
8
  alignItems: 'center',
9
9
  height: '100%',
@@ -14,11 +14,11 @@ const styles = {
14
14
  backgroundColor: 'var(--neutral-layer-4)',
15
15
  borderColor: 'var(--error-color)',
16
16
  borderRadius: '7px',
17
- borderStyle: 'solid',
17
+ borderStyle: 'solid' as const,
18
18
  borderWidth: '4px',
19
19
  padding: '5px',
20
20
  margin: '15px',
21
- textAlign: 'center',
21
+ textAlign: 'center' as const,
22
22
  width: 'fit-content',
23
23
  alignSelf: 'center',
24
24
  height: 'auto',
@@ -26,7 +26,12 @@ const styles = {
26
26
  },
27
27
  };
28
28
 
29
- const ErrorMessage = ({ elementType = 'div', message = '' }) => {
29
+ export interface ErrorMessageProps {
30
+ elementType?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span';
31
+ message?: string;
32
+ }
33
+
34
+ const ErrorMessage: React.FC<ErrorMessageProps> = ({ elementType = 'div', message = '' }) => {
30
35
  const ElementType = elementType;
31
36
 
32
37
  return message && message !== '' && (
@@ -1,11 +1,21 @@
1
- declare namespace JSX {
2
- interface IntrinsicElements {
3
- // Wildcard for all webcomponents:
4
- [elemName: string]: unknown;
5
- }
6
- }
1
+ import React, { useState, DOMAttributes } from 'react';
7
2
 
8
- declare module '*.module.css' {
9
- const classes: { [key: string]: string };
10
- export default classes;
3
+ type CustomElement<T = HTMLElement> = Partial<T & DOMAttributes<T> & { children: any }>;
4
+
5
+ declare module "react/jsx-runtime" {
6
+ namespace JSX {
7
+ interface IntrinsicElements {
8
+ 'entity-management': CustomElement;
9
+ 'foundation-form': CustomElement;
10
+ 'rapid-grid-pro': CustomElement;
11
+ 'grid-pro-genesis-datasource': CustomElement;
12
+ 'grid-pro-column': CustomElement;
13
+ 'rapid-g2plot-chart': CustomElement;
14
+ 'chart-datasource': CustomElement;
15
+ 'client-app-login': CustomElement;
16
+ 'rapid-layout': CustomElement;
17
+ 'rapid-layout-region': CustomElement;
18
+ 'rapid-layout-item': CustomElement;
19
+ }
20
+ }
11
21
  }
@@ -16,7 +16,7 @@ const AuthGuard: React.FC<AuthGuardProps> = ({ children }: AuthGuardProps) => {
16
16
  };
17
17
 
18
18
  verifyAuth();
19
- }, []);
19
+ }, [checkAuthStatus]);
20
20
 
21
21
  if (isLoading) {
22
22
  return <div>Loading...</div>; // Or some loading component
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import './styles/styles.css';
4
+ import App from './App';
5
+ import reportWebVitals from './reportWebVitals';
6
+
7
+ const rootElement = document.getElementById('root');
8
+
9
+ if (rootElement) {
10
+ const root = ReactDOM.createRoot(rootElement);
11
+ root.render(
12
+ <React.StrictMode>
13
+ <App />
14
+ </React.StrictMode>,
15
+ );
16
+
17
+ // If you want to start measuring performance in your app, pass a function
18
+ // to log results (for example: reportWebVitals(console.log))
19
+ // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
20
+ reportWebVitals();
21
+ }
@@ -0,0 +1,10 @@
1
+ import { render } from '@testing-library/react';
2
+ import AuthPage from './AuthPage';
3
+
4
+ test('renders AuthPage component', () => {
5
+ const { container } = render(<AuthPage />);
6
+ const authPageElement: Element | null = container.querySelector('.auth-page');
7
+ expect(authPageElement).toBeInTheDocument();
8
+ const clientAppLoginElement: Element | null = container.querySelector('client-app-login');
9
+ expect(clientAppLoginElement).toBeInTheDocument();
10
+ });
@@ -1,6 +1,7 @@
1
+ import React from 'react';
1
2
  import './AuthPage.css';
2
3
 
3
- const AuthPage = () => {
4
+ const AuthPage: React.FC = () => {
4
5
  return (
5
6
  <section className="auth-page">
6
7
  <client-app-login></client-app-login>
@@ -8,4 +9,4 @@ const AuthPage = () => {
8
9
  );
9
10
  };
10
11
 
11
- export default AuthPage;
12
+ export default AuthPage;
@@ -0,0 +1,17 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import NotPermittedPage from './NotPermittedPage';
3
+
4
+ jest.mock('../../components/ErrorMessage/ErrorMessage', () => {
5
+ return jest.fn((props: { message: string }) => <h1 data-testid="error-message">{props.message}</h1>);
6
+ });
7
+
8
+ describe('NotPermittedPage Component', () => {
9
+ test('renders the ErrorMessage component with correct props', () => {
10
+ render(<NotPermittedPage />);
11
+
12
+ const errorMessage: HTMLElement = screen.getByTestId('error-message');
13
+ expect(errorMessage).toBeInTheDocument();
14
+ expect(errorMessage.tagName).toBe('H1');
15
+ expect(errorMessage).toHaveTextContent('You do not have permission to access this part of the application, please contact your administrator.');
16
+ });
17
+ });
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import ErrorMessage from '../../components/ErrorMessage/ErrorMessage';
3
+ import './NotPermittedPage.css';
4
+
5
+ const NotPermittedPage: React.FC = () => {
6
+ return (
7
+ <ErrorMessage
8
+ elementType="h1"
9
+ message="You do not have permission to access this part of the application, please contact your administrator."
10
+ />
11
+ );
12
+ };
13
+
14
+ export default NotPermittedPage;
@@ -1,4 +1,4 @@
1
- const reportWebVitals = (onPerfEntry) => {
1
+ const reportWebVitals = onPerfEntry => {
2
2
  if (onPerfEntry && onPerfEntry instanceof Function) {
3
3
  import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4
4
  getCLS(onPerfEntry);
@@ -7,8 +7,6 @@
7
7
  "lib": ["ES2020", "DOM", "DOM.Iterable"],
8
8
  "module": "ESNext",
9
9
  "skipLibCheck": true,
10
-
11
- /* Bundler mode */
12
10
  "moduleResolution": "bundler",
13
11
  "allowImportingTsExtensions": true,
14
12
  "resolveJsonModule": true,
@@ -16,13 +14,12 @@
16
14
  "moduleDetection": "force",
17
15
  "noEmit": true,
18
16
  "jsx": "react-jsx",
19
-
20
- /* Linting */
21
17
  "strict": true,
18
+ "esModuleInterop": true,
22
19
  "noUnusedLocals": true,
23
20
  "noUnusedParameters": true,
24
21
  "noFallthroughCasesInSwitch": true,
25
22
  "types": ["node", "react"]
26
23
  },
27
- "include": ["src"]
24
+ "include": ["src" , "src/**/*.d.ts"],
28
25
  }
@@ -7,5 +7,8 @@
7
7
  {
8
8
  "path": "./tsconfig.node.json"
9
9
  }
10
- ]
10
+ ],
11
+ "compilerOptions": {
12
+ "esModuleInterop": true,
13
+ }
11
14
  }
@@ -9,5 +9,5 @@
9
9
  "strict": true,
10
10
  "noEmit": true
11
11
  },
12
- "include": ["vite.config.js"]
12
+ "include": ["vite.config.ts"]
13
13
  }
@@ -1,28 +1,28 @@
1
1
  import { fileURLToPath } from 'node:url';
2
2
  import { resolve, dirname } from 'path';
3
- import { defineConfig } from 'vite';
3
+ import { defineConfig, UserConfig } from 'vite';
4
4
  import fs from 'fs';
5
5
  import react from '@vitejs/plugin-react';
6
6
  import visualizer from 'rollup-plugin-visualizer';
7
7
 
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
9
 
10
- export default defineConfig(({ mode }) => {
11
- const https = process.env.HTTPS === 'true';
12
- const open = !(process.env.NO_OPEN === 'true');
13
- const jsonFilePath = resolve(process.cwd(), `env.${mode}.json`);
14
- const envConfig = {};
10
+ export default defineConfig(({ mode }: { mode: string }): UserConfig => {
11
+ const https: boolean = process.env.HTTPS === 'true';
12
+ const open: boolean = !(process.env.NO_OPEN === 'true');
13
+ const jsonFilePath: string = resolve(process.cwd(), `env.${mode}.json`);
14
+ const envConfig: Record<string, string> = {};
15
15
 
16
16
  if (fs.existsSync(jsonFilePath)) {
17
- const jsonContent = fs.readFileSync(jsonFilePath, 'utf-8');
18
- const parsedConfig = JSON.parse(jsonContent);
17
+ const jsonContent: string = fs.readFileSync(jsonFilePath, 'utf-8');
18
+ const parsedConfig: Record<string, any> = JSON.parse(jsonContent);
19
19
 
20
20
  for (const key in parsedConfig) {
21
21
  envConfig[`import.meta.env.${key}`] = JSON.stringify(parsedConfig[key]);
22
22
  }
23
23
  }
24
24
 
25
- const config = {
25
+ const config: UserConfig = {
26
26
  define: envConfig,
27
27
  server: {
28
28
  https,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/blank-app-seed",
3
3
  "description": "Genesis Blank App Seed",
4
- "version": "3.30.0-prerelease.1",
4
+ "version": "3.30.0-prerelease.11",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "release": "semantic-release"
@@ -1,5 +1,3 @@
1
- rootProject.name = "genesisproduct-{{appName}}"
2
-
3
1
  pluginManagement {
4
2
  pluginManagement {
5
3
  val genesisVersion: String by settings
@@ -38,6 +36,8 @@ plugins {
38
36
  }
39
37
 
40
38
  genesis {
39
+ productName = "{{appName}}"
40
+
41
41
  dependencies {
42
42
  dependency("global.genesis:auth:${extra.properties["authVersion"]}")
43
43
 
@@ -1,18 +0,0 @@
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
- }
@@ -1,17 +0,0 @@
1
- import React from 'react';
2
- import ReactDOM from 'react-dom/client';
3
- import './styles/styles.css';
4
- import App from './App';
5
- import reportWebVitals from './reportWebVitals';
6
-
7
- const root = ReactDOM.createRoot(document.getElementById('root'));
8
- root.render(
9
- <React.StrictMode>
10
- <App />
11
- </React.StrictMode>,
12
- );
13
-
14
- // If you want to start measuring performance in your app, pass a function
15
- // to log results (for example: reportWebVitals(console.log))
16
- // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17
- reportWebVitals();
@@ -1,13 +0,0 @@
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;