@genesislcap/blank-app-seed 5.22.2-prerelease.2 → 5.23.1

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 (194) hide show
  1. package/.genx/configure.js +11 -1
  2. package/.genx/package.json +1 -1
  3. package/.genx/scripts/generate-test-apps.sh +124 -0
  4. package/.genx/templates/angular/chart.hbs +19 -7
  5. package/.genx/templates/angular/component/component.column.defs.hbs +16 -4
  6. package/.genx/templates/angular/component/component.create.form.hbs +10 -2
  7. package/.genx/templates/angular/component/component.events.config.hbs +31 -6
  8. package/.genx/templates/angular/component/component.filter.form.hbs +1 -2
  9. package/.genx/templates/angular/component/component.gridOptions.hbs +15 -3
  10. package/.genx/templates/angular/component/component.hbs +77 -46
  11. package/.genx/templates/angular/component/component.index.hbs +1 -1
  12. package/.genx/templates/angular/component/component.update.form.hbs +1 -1
  13. package/.genx/templates/angular/entityManager.hbs +6 -6
  14. package/{client-tmp/angular/src/app/utils/fdc3.ts → .genx/templates/angular/fdc3.ts.hbs} +6 -8
  15. package/.genx/templates/angular/form.hbs +9 -12
  16. package/.genx/templates/angular/grid.hbs +43 -40
  17. package/.genx/templates/angular/route.hbs +8 -2
  18. package/.genx/templates/angular/route.template.hbs +7 -7
  19. package/.genx/templates/angular/slices/eventing.slice.hbs +21 -10
  20. package/.genx/templates/angular/store.hbs +1 -5
  21. package/.genx/templates/angular/tabsPanel.hbs +2 -2
  22. package/.genx/templates/react/chart.hbs +6 -15
  23. package/.genx/templates/react/component/component.column.defs.hbs +16 -10
  24. package/.genx/templates/react/component/component.create.form.hbs +2 -2
  25. package/.genx/templates/react/component/component.events.config.hbs +32 -5
  26. package/.genx/templates/react/component/component.filter.form.hbs +1 -2
  27. package/.genx/templates/react/component/component.gridOptions.hbs +17 -11
  28. package/.genx/templates/react/component/component.hbs +84 -42
  29. package/.genx/templates/react/component/component.update.form.hbs +1 -1
  30. package/.genx/templates/react/entityManager.hbs +8 -16
  31. package/{client-tmp/react/src/utils/fdc3.ts → .genx/templates/react/fdc3.ts.hbs} +7 -8
  32. package/.genx/templates/react/form.hbs +1 -15
  33. package/.genx/templates/react/grid.hbs +11 -11
  34. package/.genx/templates/react/gridLayout.hbs +44 -4
  35. package/.genx/templates/react/horizontalLayout.hbs +10 -1
  36. package/.genx/templates/react/route.hbs +23 -16
  37. package/.genx/templates/react/slices/eventing.slice.hbs +19 -8
  38. package/.genx/templates/react/store.hbs +1 -5
  39. package/.genx/templates/react/tabsLayout.hbs +5 -1
  40. package/.genx/templates/web-components/chart.hbs +25 -25
  41. package/.genx/templates/web-components/component/component.column.defs.hbs +11 -3
  42. package/.genx/templates/web-components/component/component.create.form.hbs +11 -4
  43. package/.genx/templates/web-components/component/component.events.config.hbs +33 -6
  44. package/.genx/templates/web-components/component/component.filter.form.hbs +1 -2
  45. package/.genx/templates/web-components/component/component.gridOptions.hbs +12 -3
  46. package/.genx/templates/web-components/component/component.hbs +19 -20
  47. package/.genx/templates/web-components/component/component.index.hbs +1 -1
  48. package/.genx/templates/web-components/component/component.template.hbs +9 -13
  49. package/.genx/templates/web-components/component/component.update.form.hbs +1 -1
  50. package/.genx/templates/web-components/entityManager.hbs +92 -73
  51. package/{client-tmp/web-components/src/utils/fdc3.ts → .genx/templates/web-components/fdc3.ts.hbs} +6 -7
  52. package/.genx/templates/web-components/form.hbs +16 -15
  53. package/.genx/templates/web-components/grid.hbs +49 -41
  54. package/.genx/templates/web-components/gridLayout.hbs +32 -28
  55. package/.genx/templates/web-components/horizontalLayout.hbs +5 -5
  56. package/.genx/templates/web-components/route.template.hbs +4 -6
  57. package/.genx/templates/web-components/slices/eventing.slice.hbs +23 -15
  58. package/.genx/templates/web-components/store.hbs +1 -9
  59. package/.genx/templates/web-components/tabsLayout.hbs +5 -5
  60. package/.genx/tests/fixtures/routes-full.json +299 -0
  61. package/.genx/tests/fixtures/testapp/client/src/pages/Home/Home.tsx +12 -0
  62. package/.genx/utils/formatJSONValue.js +38 -2
  63. package/.genx/utils/formatRouteData.js +67 -18
  64. package/.genx/utils/generateTile.js +10 -1
  65. package/.genx/utils/gridSerializers.js +63 -23
  66. package/.genx/utils/registerPartials.js +15 -12
  67. package/.genx/utils/toJsStringLiteral.js +37 -0
  68. package/.genx/versions.json +3 -3
  69. package/.github/workflows/build.yml +22 -1
  70. package/.husky/pre-commit +8 -0
  71. package/CHANGELOG.md +97 -23
  72. package/bdd-tests/gradle/wrapper/gradle-wrapper.properties +1 -1
  73. package/bdd-tests/gradle.properties +0 -1
  74. package/client-tmp/angular/.oxfmtrc.json +32 -0
  75. package/client-tmp/angular/.oxlintrc.json +4 -0
  76. package/client-tmp/angular/README.md +4 -4
  77. package/client-tmp/angular/jest.config.js +1 -1
  78. package/client-tmp/angular/lint-css.js +24 -3
  79. package/client-tmp/angular/oxlint-staged.js +45 -0
  80. package/client-tmp/angular/package.json +19 -9
  81. package/client-tmp/angular/playwright.config.ts +12 -11
  82. package/client-tmp/angular/src/app/app.component.html +0 -1
  83. package/client-tmp/angular/src/app/app.component.ts +8 -9
  84. package/client-tmp/angular/src/app/app.config.ts +2 -2
  85. package/client-tmp/angular/src/app/app.module.ts +6 -5
  86. package/client-tmp/angular/src/app/components/error-message/error-message.component.html +29 -15
  87. package/client-tmp/angular/src/app/components/error-message/error-message.component.spec.ts +2 -2
  88. package/client-tmp/angular/src/app/components/error-message/error-message.component.ts +3 -5
  89. package/client-tmp/angular/src/app/directive/app-lazy-load.directive.ts +1 -0
  90. package/client-tmp/angular/src/app/guards/chained.guard.ts +19 -19
  91. package/client-tmp/angular/src/app/guards/connection.guard.ts +12 -12
  92. package/client-tmp/angular/src/app/layouts/blank/blank.layout.spec.ts +1 -1
  93. package/client-tmp/angular/src/app/layouts/blank/blank.layout.ts +1 -5
  94. package/client-tmp/angular/src/app/layouts/default/default.layout.html +3 -4
  95. package/client-tmp/angular/src/app/layouts/default/default.layout.spec.ts +4 -4
  96. package/client-tmp/angular/src/app/layouts/default/default.layout.ts +1 -1
  97. package/client-tmp/angular/src/app/pages/auth-login/auth-login.component.ts +1 -2
  98. package/client-tmp/angular/src/app/pages/not-permitted/not-permitted.component.html +3 -3
  99. package/client-tmp/angular/src/app/pages/not-permitted/not-permitted.component.scss +1 -1
  100. package/client-tmp/angular/src/app/pages/not-permitted/not-permitted.component.spec.ts +5 -5
  101. package/client-tmp/angular/src/app/pages/not-permitted/not-permitted.component.ts +3 -4
  102. package/client-tmp/angular/src/app/services/route.service.ts +79 -74
  103. package/client-tmp/angular/src/app/share/foundation-auth.ts +7 -1
  104. package/client-tmp/angular/src/app/share/genesis-components.ts +66 -68
  105. package/client-tmp/angular/src/app/utils/index.ts +3 -1
  106. package/client-tmp/angular/src/app/utils/permissions.ts +7 -7
  107. package/client-tmp/angular/src/declaration.d.ts +1 -1
  108. package/client-tmp/angular/src/environments/environment.ts +1 -1
  109. package/client-tmp/angular/src/jest.setup.ts +8 -0
  110. package/client-tmp/angular/src/main.ts +2 -2
  111. package/client-tmp/angular/src/pbc/container.ts +28 -26
  112. package/client-tmp/angular/src/pbc/elementsRenderer.ts +49 -39
  113. package/client-tmp/angular/src/pbc/utils.ts +61 -60
  114. package/client-tmp/angular/src/styles/_mixins.scss +7 -8
  115. package/client-tmp/angular/src/styles/styles.css +6 -6
  116. package/client-tmp/angular/test/e2e/fixture.ts +2 -2
  117. package/client-tmp/angular/test/e2e/flows/001-protected.e2e.ts +1 -1
  118. package/client-tmp/angular/tsconfig.app.json +2 -8
  119. package/client-tmp/angular/tsconfig.json +1 -4
  120. package/client-tmp/angular/tsconfig.spec.json +4 -11
  121. package/client-tmp/angular/webpack.dev.config.js +3 -4
  122. package/client-tmp/angular/webpack.prod.config.js +3 -4
  123. package/client-tmp/angular/webpack.shared.config.js +20 -24
  124. package/client-tmp/react/.oxfmtrc.json +30 -0
  125. package/client-tmp/react/.oxlintrc.json +4 -0
  126. package/client-tmp/react/README.md +4 -4
  127. package/client-tmp/react/jest.config.ts +8 -4
  128. package/client-tmp/react/jest.setup.ts +85 -1
  129. package/client-tmp/react/oxlint-staged.js +45 -0
  130. package/client-tmp/react/package.json +24 -9
  131. package/client-tmp/react/playwright.config.ts +11 -10
  132. package/client-tmp/react/src/App.tsx +27 -29
  133. package/client-tmp/react/src/__mocks__/fileMock.js +1 -0
  134. package/client-tmp/react/src/components/ErrorMessage/ErrorMessage.test.tsx +16 -4
  135. package/client-tmp/react/src/components/ErrorMessage/ErrorMessage.tsx +32 -29
  136. package/client-tmp/react/src/components/error-boundary/ErrorBoundary.tsx +15 -6
  137. package/client-tmp/react/src/components/routes/AppRoutes.tsx +1 -1
  138. package/client-tmp/react/src/components/single-component/registry.ts +4 -0
  139. package/client-tmp/react/src/custom-elements.d.ts +4 -2
  140. package/client-tmp/react/src/helpers/hasPermissionHelper.tsx +1 -1
  141. package/client-tmp/react/src/helpers/isAuthenticatedHelper.tsx +1 -1
  142. package/client-tmp/react/src/helpers/isConnectedHelper.tsx +3 -3
  143. package/client-tmp/react/src/layouts/blank/BlankLayout.tsx +7 -11
  144. package/client-tmp/react/src/layouts/default/DefaultLayout.tsx +8 -8
  145. package/client-tmp/react/src/main.tsx +11 -11
  146. package/client-tmp/react/src/pages/AuthPage/AuthPage.test.tsx +13 -2
  147. package/client-tmp/react/src/pages/AuthPage/AuthPage.tsx +14 -13
  148. package/client-tmp/react/src/pages/NotFoundPage/NotFoundPage.tsx +2 -7
  149. package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.test.tsx +8 -4
  150. package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.tsx +1 -1
  151. package/client-tmp/react/src/pbc/container.tsx +9 -4
  152. package/client-tmp/react/src/pbc/elementsRenderer.tsx +18 -9
  153. package/client-tmp/react/src/pbc/utils.ts +60 -59
  154. package/client-tmp/react/src/services/auth.service.ts +1 -1
  155. package/client-tmp/react/src/services/store.service.ts +5 -3
  156. package/client-tmp/react/src/share/foundation-login.ts +2 -2
  157. package/client-tmp/react/src/share/genesis-components.ts +46 -47
  158. package/client-tmp/react/src/store/AuthContext.tsx +2 -10
  159. package/client-tmp/react/src/store/RoutesContext.test.tsx +99 -0
  160. package/client-tmp/react/src/store/RoutesContext.tsx +25 -5
  161. package/client-tmp/react/src/styles/styles.css +7 -7
  162. package/client-tmp/react/src/types/LayoutName.ts +1 -1
  163. package/client-tmp/react/src/utils/getLayoutNameByRoute.ts +1 -1
  164. package/client-tmp/react/src/utils/index.ts +2 -0
  165. package/client-tmp/react/src/utils/layout.ts +8 -1
  166. package/client-tmp/react/src/utils/permissions.ts +7 -7
  167. package/client-tmp/react/src/utils/useDocumentTitle.ts +5 -6
  168. package/client-tmp/react/test/e2e/fixture.ts +5 -2
  169. package/client-tmp/react/test/e2e/flows/001-protected.e2e.ts +3 -1
  170. package/client-tmp/react/tsconfig.app.json +1 -1
  171. package/client-tmp/react/tsconfig.json +1 -5
  172. package/client-tmp/web-components/.oxfmtrc.json +30 -0
  173. package/client-tmp/web-components/.oxlintrc.json +4 -0
  174. package/client-tmp/web-components/oxlint-staged.js +45 -0
  175. package/client-tmp/web-components/package.json +14 -22
  176. package/client-tmp/web-components/src/components/components.ts +9 -7
  177. package/client-tmp/web-components/src/main/main.css +1 -2
  178. package/client-tmp/web-components/src/main/main.ts +1 -1
  179. package/client-tmp/web-components/src/routes/config.ts +4 -0
  180. package/client-tmp/web-components/src/utils/index.ts +2 -0
  181. package/client-tmp/web-components/tsconfig.json +1 -4
  182. package/gradle/wrapper/gradle-wrapper.properties +1 -1
  183. package/package.json +1 -1
  184. package/server/gradle/wrapper/gradle-wrapper.properties +1 -1
  185. package/server/gradle.properties +0 -2
  186. package/.genx/templates/angular/gridLayout.hbs +0 -30
  187. package/.genx/templates/angular/horizontalLayout.hbs +0 -7
  188. package/.genx/templates/angular/tabsLayout.hbs +0 -7
  189. package/.genx/tests/fixtures/testapp/client/src/routes/home/home.template.ts +0 -6
  190. package/client-tmp/react/.babelrc +0 -10
  191. package/client-tmp/react/.eslintrc.cjs +0 -21
  192. package/client-tmp/react/git +0 -0
  193. package/client-tmp/react/webpack.config.js +0 -121
  194. package/client-tmp/web-components/.prettierignore +0 -14
@@ -1,6 +1,3 @@
1
- {{#if config.permissions.viewRight~}}
2
- hasUserPermission('{{config.permissions.viewRight}}') ? (
3
- {{/if}}
4
1
  <>
5
2
  <EntityManagement
6
3
  prefix="rapid"
@@ -9,13 +6,13 @@ hasUserPermission('{{config.permissions.viewRight}}') ? (
9
6
  {{#ifAny config.snapshot config.reqrep config.eventing.listener}}
10
7
  datasourceConfig={datasourceConfig}
11
8
  {{/ifAny}}
12
- {{#if config.title~}}
9
+ {{#if config.title}}
13
10
  title="{{ config.title }}"
14
11
  {{/if}}
15
12
  resourceName="{{ config.resourceName }}"
16
- {{#if config.createEvent~}}
13
+ {{#if config.createEvent}}
17
14
  {{#if config.permissions.updateRight}}
18
- createEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.createEvent }}' : undefined}
15
+ createEvent={canUpdate ? '{{ config.createEvent }}' : undefined}
19
16
  {{else}}
20
17
  createEvent="{{ config.createEvent }}"
21
18
  {{/if}}
@@ -23,9 +20,9 @@ hasUserPermission('{{config.permissions.viewRight}}') ? (
23
20
  createFormUiSchema={createFormSchema}
24
21
  {{/if}}
25
22
  {{/if}}
26
- {{#if config.updateEvent~}}
23
+ {{#if config.updateEvent}}
27
24
  {{#if config.permissions.updateRight}}
28
- updateEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.updateEvent }}' : undefined}
25
+ updateEvent={canUpdate ? '{{ config.updateEvent }}' : undefined}
29
26
  {{else}}
30
27
  updateEvent="{{ config.updateEvent }}"
31
28
  {{/if}}
@@ -33,15 +30,15 @@ hasUserPermission('{{config.permissions.viewRight}}') ? (
33
30
  updateFormUiSchema={updateFormSchema}
34
31
  {{/if}}
35
32
  {{/if}}
36
- {{#if config.deleteEvent~}}
33
+ {{#if config.deleteEvent}}
37
34
  {{#if config.permissions.updateRight}}
38
- deleteEvent={hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.deleteEvent }}' : undefined}
35
+ deleteEvent={canUpdate ? '{{ config.deleteEvent }}' : undefined}
39
36
  {{else}}
40
37
  deleteEvent="{{ config.deleteEvent }}"
41
38
  {{/if}}
42
39
  {{/if}}
43
40
  {{#if config.gridOptions}}
44
- gridOptions={gridOptions}
41
+ gridOptions={gridOptionsTile}
45
42
  {{/if}}
46
43
  {{#if config.eventing.publishEventName}}
47
44
  onSelectionChanged={handleRowSelection}
@@ -73,8 +70,3 @@ hasUserPermission('{{config.permissions.viewRight}}') ? (
73
70
  {{/if}}
74
71
  />
75
72
  </>
76
- {{#if config.permissions.viewRight~}}
77
- ) : (
78
- <ErrorMessage elementType="h3" message="You do not have access to view this component." />
79
- )
80
- {{/if}}
@@ -1,15 +1,15 @@
1
- {{#if FDC3.includeDependencies}}
2
1
  import { DefaultFDC3 } from '@genesislcap/foundation-fdc3';
3
- {{/if}}
4
- export const isFDC3 = (): boolean => !!((window as unknown as { fdc3?: boolean }).fdc3);
5
- {{#if FDC3.includeDependencies}}
2
+
3
+ export const isFDC3 = (): boolean => !!(window as unknown as { fdc3?: boolean }).fdc3;
6
4
 
7
5
  export const onFDC3Ready = async (FDC3ReadyCb: () => any): Promise<void> => {
8
- isFDC3()
9
- ? await FDC3ReadyCb()
10
- : window.addEventListener('fdc3Ready', async () => {
6
+ if (isFDC3()) {
7
+ await FDC3ReadyCb();
8
+ } else {
9
+ window.addEventListener('fdc3Ready', async () => {
11
10
  await FDC3ReadyCb();
12
11
  });
12
+ }
13
13
  };
14
14
 
15
15
  export const listenToChannel = async (
@@ -29,4 +29,3 @@ export const sendEventOnChannel = (channelName: string, type: string) => {
29
29
  await fdc3Service.broadcastOnChannel(channelName, type, payload);
30
30
  };
31
31
  };
32
- {{/if}}
@@ -1,15 +1 @@
1
- {{#if config.permissions.updateRight~}}
2
- hasUserPermission('{{config.permissions.updateRight}}') ? (
3
- {{/if}}
4
- <Form
5
- prefix="rapid"
6
- resourceName="{{config.resourceName}}"
7
- {{#if config.uischema}}
8
- uischema={uischema}
9
- {{/if}}
10
- />
11
- {{#if config.permissions.updateRight~}}
12
- ) : (
13
- <ErrorMessage elementType="h3" message="You do not have access to view this component." />
14
- )
15
- {{/if}}
1
+ <Form prefix="rapid" resourceName="{{config.resourceName}}"{{#if config.uischema}} uischema={uischema}{{/if}} />
@@ -1,14 +1,16 @@
1
- {{#if config.permissions.viewRight~}}
2
- hasUserPermission('{{config.permissions.viewRight}}') ? (
3
- {{/if}}
1
+ {{#if config.useOnlyTemplateCols}}
4
2
  <RapidGridPro
5
3
  headerCaseType={GridProCaseType.capitalCase}
6
- {{#if config.useOnlyTemplateCols}}
7
4
  onlyTemplateColDefs
8
- {{/if}}
9
5
  enableRowFlashing
10
6
  enableCellFlashing
11
- >
7
+ >
8
+ {{else}}
9
+ <RapidGridPro headerCaseType={GridProCaseType.capitalCase} enableRowFlashing enableCellFlashing>
10
+ {{/if}}
11
+ {{#ifAny config.snapshot config.gridOptions config.eventing.publishEventName config.eventing.listener config.reqrep}}
12
+ {{! prettier-ignore must be bare: attribute widths are user data, keep one attribute per line }}
13
+ {/* prettier-ignore */}
12
14
  <GridProGenesisDatasource
13
15
  resourceName="{{config.resourceName}}"
14
16
  {{#if config.snapshot}}
@@ -25,14 +27,12 @@ hasUserPermission('{{config.permissions.viewRight}}') ? (
25
27
  pollingInterval={datasourceConfig.pollingInterval}
26
28
  {{/if}}
27
29
  />
30
+ {{else}}
31
+ <GridProGenesisDatasource resourceName="{{config.resourceName}}" />
32
+ {{/ifAny}}
28
33
  {{#if config.gridOptions}}
29
34
  {gridOptionsTile?.columnDefs?.map((columnDef, index) => (
30
35
  <GridProColumn key={index} definition={columnDef} />
31
36
  ))}
32
37
  {{/if}}
33
38
  </RapidGridPro>
34
- {{#if config.permissions.viewRight~}}
35
- ) : (
36
- <ErrorMessage elementType="h3" message="You do not have access to view this component." />
37
- )
38
- {{/if}}
@@ -9,10 +9,30 @@ const defaultLayout = {
9
9
  children: [
10
10
  {{#each route.tiles}}
11
11
  {{#ifEquals @index 0}}
12
- { type: 'tabset', weight: 50, children: [{ type: 'tab', name: '{{this.title}}', component: '{{camelCase this.componentName}}' }] },
12
+ {
13
+ type: 'tabset',
14
+ weight: 50,
15
+ children: [
16
+ {
17
+ type: 'tab',
18
+ name: {{{this.titleJs}}},
19
+ component: '{{pascalCase this.componentName}}',
20
+ },
21
+ ],
22
+ },
13
23
  {{/ifEquals}}
14
24
  {{#ifEquals @index 2}}
15
- { type: 'tabset', weight: 50, children: [{ type: 'tab', name: '{{this.title}}', component: '{{camelCase this.componentName}}' }] },
25
+ {
26
+ type: 'tabset',
27
+ weight: 50,
28
+ children: [
29
+ {
30
+ type: 'tab',
31
+ name: {{{this.titleJs}}},
32
+ component: '{{pascalCase this.componentName}}',
33
+ },
34
+ ],
35
+ },
16
36
  {{/ifEquals}}
17
37
  {{/each}}
18
38
  ],
@@ -23,10 +43,30 @@ const defaultLayout = {
23
43
  children: [
24
44
  {{#each route.tiles}}
25
45
  {{#ifEquals @index 1}}
26
- { type: 'tabset', weight: 50, children: [{ type: 'tab', name: '{{this.title}}', component: '{{camelCase this.componentName}}' }] },
46
+ {
47
+ type: 'tabset',
48
+ weight: 50,
49
+ children: [
50
+ {
51
+ type: 'tab',
52
+ name: {{{this.titleJs}}},
53
+ component: '{{pascalCase this.componentName}}',
54
+ },
55
+ ],
56
+ },
27
57
  {{/ifEquals}}
28
58
  {{#ifEquals @index 3}}
29
- { type: 'tabset', weight: 50, children: [{ type: 'tab', name: '{{this.title}}', component: '{{camelCase this.componentName}}' }] },
59
+ {
60
+ type: 'tabset',
61
+ weight: 50,
62
+ children: [
63
+ {
64
+ type: 'tab',
65
+ name: {{{this.titleJs}}},
66
+ component: '{{pascalCase this.componentName}}',
67
+ },
68
+ ],
69
+ },
30
70
  {{/ifEquals}}
31
71
  {{/each}}
32
72
  ],
@@ -4,7 +4,16 @@ const defaultLayout = {
4
4
  type: 'row',
5
5
  children: [
6
6
  {{#each route.tiles}}
7
- { type: 'tabset', children: [{ type: 'tab', name: '{{this.title}}', component: '{{camelCase this.componentName}}' }] },
7
+ {
8
+ type: 'tabset',
9
+ children: [
10
+ {
11
+ type: 'tab',
12
+ name: {{{this.titleJs}}},
13
+ component: '{{pascalCase this.componentName}}',
14
+ },
15
+ ],
16
+ },
8
17
  {{/each}}
9
18
  ],
10
19
  },
@@ -1,22 +1,25 @@
1
1
  {{#if route.tiles}}
2
- import React, { useRef } from 'react';
3
2
  import { Layout, Model, TabNode } from 'flexlayout-react';
4
- import { getFlexLayoutStorageKey } from '../../utils/layout';
3
+ import React, { useState } from 'react';
5
4
  import { TileErrorBoundary } from '../../components/error-boundary/ErrorBoundary';
5
+ import { getFlexLayoutStorageKey } from '../../utils/layout';
6
+ /* eslint-disable import-es/order -- generated tile imports follow tile order, not alphabetical */
6
7
  {{#each route.tiles}}
7
8
  import { {{pascalCase this.componentName}} } from './{{pascalCase this.title}}{{pascalCase this.componentType}}';
8
9
  {{/each}}
9
- {{/if}}
10
+ /* eslint-enable import-es/order */
10
11
  import './{{pascalCase route.name}}.css';
11
12
 
12
- {{#if route.tiles}}
13
- const STORAGE_KEY = getFlexLayoutStorageKey('{{route.layoutKey}}');
13
+ // Kept as its own constant so the (arbitrarily long) layout key never forces a line wrap.
14
+ const LAYOUT_KEY = '{{route.layoutKey}}';
15
+ const STORAGE_KEY = getFlexLayoutStorageKey(LAYOUT_KEY);
14
16
 
15
17
  {{> (lookup ./route 'layoutType') }}
16
18
 
19
+ {{! Map keys match the imported component names so the entries stay shorthand and never wrap. }}
17
20
  const componentMap: Record<string, React.FC> = {
18
21
  {{#each route.tiles}}
19
- '{{camelCase this.componentName}}': {{pascalCase this.componentName}},
22
+ {{pascalCase this.componentName}},
20
23
  {{/each}}
21
24
  };
22
25
 
@@ -24,16 +27,18 @@ function loadModel(): Model {
24
27
  if (STORAGE_KEY) {
25
28
  const saved = localStorage.getItem(STORAGE_KEY);
26
29
  if (saved) {
27
- try { return Model.fromJson(JSON.parse(saved)); } catch {}
30
+ try {
31
+ return Model.fromJson(JSON.parse(saved));
32
+ } catch {
33
+ // Ignore a corrupt persisted layout and fall back to the default below.
34
+ }
28
35
  }
29
36
  }
30
37
  return Model.fromJson(defaultLayout);
31
38
  }
32
- {{/if}}
33
39
 
34
40
  const {{pascalCase route.name}} = () => {
35
- {{#if route.tiles}}
36
- const modelRef = useRef<Model>(loadModel());
41
+ const [model] = useState<Model>(loadModel);
37
42
 
38
43
  const factory = (node: TabNode) => {
39
44
  const Component = componentMap[node.getComponent() ?? ''];
@@ -52,17 +57,19 @@ const {{pascalCase route.name}} = () => {
52
57
  localStorage.setItem(STORAGE_KEY, JSON.stringify(model.toJson()));
53
58
  }
54
59
  };
55
- {{/if}}
56
60
 
57
61
  return (
58
62
  <section className="{{kebabCase route.name}}-page">
59
- {{#if route.tiles}}
60
- <Layout model={modelRef.current} factory={factory} onModelChange={onModelChange} />
61
- {{else}}
62
- Welcome to {{sentenceCase route.name}}
63
- {{/if}}
63
+ <Layout model={model} factory={factory} onModelChange={onModelChange} />
64
64
  </section>
65
65
  );
66
66
  };
67
+ {{else}}
68
+ import './{{pascalCase route.name}}.css';
69
+
70
+ const {{pascalCase route.name}} = () => {
71
+ return <section className="{{kebabCase route.name}}-page">Welcome to {{sentenceCase route.name}}</section>;
72
+ };
73
+ {{/if}}
67
74
 
68
75
  export default {{pascalCase route.name}};
@@ -5,18 +5,24 @@ import { createSlice } from '@genesislcap/foundation-redux';
5
5
 
6
6
  export const eventingSlice = createSlice({
7
7
  name: 'eventing',
8
+ {{#if events.length}}
8
9
  initialState: {
9
10
  {{#each events}}
10
- {{this}}: null{{#unless @last}},{{/unless}}
11
+ {{this}}: null as Record<string, any> | null,
11
12
  {{/each}}
12
13
  },
13
14
  reducers: {
14
15
  {{#each events}}
15
16
  publish{{pascalCase this}}: (state, action) => {
16
17
  state.{{this}} = action.payload;
17
- }{{#unless @last}},{{/unless}}
18
+ },
18
19
  {{/each}}
19
20
  },
21
+ {{else}}
22
+ initialState: {},
23
+ reducers: {},
24
+ {{/if}}
25
+ {{#if listeners.length}}
20
26
  selectors: {
21
27
  {{#each listeners}}
22
28
  getCriteriaFor{{pascalCase tileName}}: (state) => {
@@ -26,16 +32,21 @@ export const eventingSlice = createSlice({
26
32
 
27
33
  {{#each mappings}}
28
34
  if (data.{{sourceField}}) {
29
- criteriaBuilder.And(new ExpressionBuilder()
30
- .withField('{{targetField}}')
31
- .withValue(data.{{sourceField}})
32
- .withSerialiser(Serialisers.EQ)
33
- .build());
35
+ criteriaBuilder.And(
36
+ new ExpressionBuilder()
37
+ .withField('{{targetField}}')
38
+ .withValue(data.{{sourceField}})
39
+ .withSerialiser(Serialisers.EQ)
40
+ .build(),
41
+ );
34
42
  }
35
43
  {{/each}}
36
44
 
37
45
  return criteriaBuilder.build();
38
- }{{#unless @last}},{{/unless}}
46
+ },
39
47
  {{/each}}
40
48
  },
49
+ {{else}}
50
+ selectors: {},
51
+ {{/if}}
41
52
  });
@@ -2,11 +2,7 @@ import { createStore } from '@genesislcap/foundation-redux';
2
2
  import { eventingSlice } from './slices/eventing.slice';
3
3
 
4
4
  export const { reduxStore, store, actions, selectors } = createStore([eventingSlice], {
5
- eventing: {
6
- {{#each events}}
7
- {{this}}: null{{#unless @last}},{{/unless}}
8
- {{/each}}
9
- },
5
+ eventing: eventingSlice.getInitialState(),
10
6
  });
11
7
 
12
8
  export type Store = typeof store;
@@ -8,7 +8,11 @@ const defaultLayout = {
8
8
  weight: 100,
9
9
  children: [
10
10
  {{#each route.tiles}}
11
- { type: 'tab', name: '{{this.title}}', component: '{{camelCase this.componentName}}' },
11
+ {
12
+ type: 'tab',
13
+ name: {{{this.titleJs}}},
14
+ component: '{{pascalCase this.componentName}}',
15
+ },
12
16
  {{/each}}
13
17
  ],
14
18
  },
@@ -1,26 +1,26 @@
1
1
  ${whenElse(
2
- (x) => getViewUpdateRightComponent(x.user, '{{config.permissions.viewRight}}'),
3
- html`
4
- <rapid-g2plot-chart
5
- type="{{ config.type }}"
6
- :config="${(x) => ({
7
- {{#ifEquals config.type "pie"}}
8
- radius: 0.75,
9
- angleField: 'value',
10
- colorField: 'groupBy',
11
- {{else}}
12
- xField: 'groupBy',
13
- yField: 'value',
14
- {{/ifEquals}}
15
- })}"
16
- >
17
- <chart-datasource
18
- resourceName="{{ config.resourceName }}"
19
- server-fields="{{ config.xField }} {{ config.yField }}"
20
- ></chart-datasource>
21
- </rapid-g2plot-chart>
22
- `,
23
- html`
24
- <not-permitted-component></not-permitted-component>
25
- `,
26
- )}
2
+ (x) => getViewUpdateRightComponent(x.user, '{{config.permissions.viewRight}}'),
3
+ html`
4
+ <rapid-g2plot-chart
5
+ type="{{ config.type }}"
6
+ :config="${(x) => ({
7
+ {{#ifEquals config.type "pie"}}
8
+ radius: 0.75,
9
+ angleField: 'value',
10
+ colorField: 'groupBy',
11
+ {{else}}
12
+ xField: 'groupBy',
13
+ yField: 'value',
14
+ {{/ifEquals}}
15
+ })}"
16
+ >
17
+ <chart-datasource
18
+ resourceName="{{ config.resourceName }}"
19
+ server-fields="{{ config.xField }} {{ config.yField }}"
20
+ ></chart-datasource>
21
+ </rapid-g2plot-chart>
22
+ `,
23
+ html`
24
+ <not-permitted-component></not-permitted-component>
25
+ `,
26
+ )}
@@ -1,9 +1,17 @@
1
- import { ColDef } from '@ag-grid-community/core';
2
- import { getNumberFormatter, getDateFormatter } from '@genesislcap/foundation-utils';
1
+ import type { ColDef } from '@ag-grid-community/core';
2
+ {{#ifContains tile.config.columns "getNumberFormatter"}}
3
+ import { getNumberFormatter{{#ifContains tile.config.columns "getDateFormatter"}}, getDateFormatter{{/ifContains}} } from '@genesislcap/foundation-utils';
4
+ {{else}}
5
+ {{#ifContains tile.config.columns "getDateFormatter"}}
6
+ import { getDateFormatter } from '@genesislcap/foundation-utils';
7
+ {{/ifContains}}
8
+ {{/ifContains}}
3
9
  {{#if route.FDC3EventHandlersEnabled}}
10
+ {{#ifContains tile.config.columns "sendEventOnChannel"}}
4
11
  import { sendEventOnChannel } from '../../../utils';
12
+ {{/ifContains}}
5
13
  {{/if}}
6
14
 
7
15
  {{#if tile.config.columns}}
8
- export const columnDefs: ColDef[] = {{{ tile.config.columns }}}
16
+ export const columnDefs: ColDef[] = {{{ tile.config.columns }}};
9
17
  {{/if}}
@@ -1,8 +1,15 @@
1
+ {{#ifAny tile.config.createFormUiSchema tile.config.uischema}}
1
2
  import { UiSchema } from '@genesislcap/foundation-forms';
2
3
 
3
4
  {{#if tile.config.createFormUiSchema}}
4
- export const createFormSchema: UiSchema = {{{ tile.config.createFormUiSchema }}}
5
- {{/if}}
6
- {{#if tile.config.uischema}}
7
- export const createFormSchema: UiSchema = {{{ tile.config.uischema }}}
5
+ export const createFormSchema: UiSchema = {{{ tile.config.createFormUiSchema }}};
6
+ {{else}}
7
+ export const createFormSchema: UiSchema = {{{ tile.config.uischema }}};
8
8
  {{/if}}
9
+ {{else}}
10
+ /**
11
+ * No `uischema` was supplied for this form, so its fields are derived from the resource metadata.
12
+ * Export a `createFormSchema` here and pass it to the form to take control of the layout.
13
+ */
14
+ export {};
15
+ {{/ifAny}}
@@ -1,11 +1,36 @@
1
- import { type CustomAction, CrudMenuPosition, UiSchema } from '@genesislcap/foundation-entity-management';
1
+ {{#ifContains tile.config.customEvents '"position":'}}
2
+ {{#ifContains tile.config.customEvents '"uischema":'}}
3
+ import {
4
+ type CustomAction,
5
+ CrudMenuPosition,
6
+ UiSchema,
7
+ } from '@genesislcap/foundation-entity-management';
8
+ {{else}}
9
+ import { type CustomAction, CrudMenuPosition } from '@genesislcap/foundation-entity-management';
10
+ {{/ifContains}}
11
+ {{else}}
12
+ {{#ifContains tile.config.customEvents '"uischema":'}}
13
+ import { type CustomAction, UiSchema } from '@genesislcap/foundation-entity-management';
14
+ {{else}}
15
+ import { type CustomAction } from '@genesislcap/foundation-entity-management';
16
+ {{/ifContains}}
17
+ {{/ifContains}}
2
18
 
19
+ {{#ifContains tile.config.customEvents '"uischema":'}}
3
20
  {{#each tile.config.customEvents}}
4
21
  {{#if this.hasForm}}
5
22
  export const {{camelCase this.name}}FormSchema: UiSchema = {{{this.uischema}}};
6
23
  {{/if}}
7
24
  {{/each}}
8
25
 
26
+ {{/ifContains}}
27
+ {{#each tile.config.customEvents}}
28
+ {{#if this.defaultValues}}
29
+ {{! Hoisted so the serialised literal keeps its own indentation; `as const` keeps the record-type discriminators literal so they still satisfy `DefaultValues`. }}
30
+ const {{camelCase this.name}}DefaultValues = {{{this.defaultValues}}} as const;
31
+
32
+ {{/if}}
33
+ {{/each}}
9
34
  export const customActions: CustomAction[] = [
10
35
  {{#each tile.config.customEvents}}
11
36
  {
@@ -17,7 +42,9 @@ export const customActions: CustomAction[] = [
17
42
  {{#if this.hasForm}}
18
43
  uiSchema: {{camelCase this.name}}FormSchema,
19
44
  {{/if}}
20
- defaultValues: {{{this.defaultValues}}},
45
+ {{#if this.defaultValues}}
46
+ defaultValues: {{camelCase this.name}}DefaultValues,
47
+ {{/if}}
21
48
  },
22
49
  {{#if this.position}}
23
50
  position: CrudMenuPosition.{{{pascalCase this.position}}},
@@ -26,15 +53,15 @@ export const customActions: CustomAction[] = [
26
53
  icon: '{{this.icon}}',
27
54
  {{/if}}
28
55
  {{#if this.tooltip}}
29
- tooltip: '{{this.tooltip}}',
56
+ tooltip: {{{this.tooltipJs}}},
30
57
  {{/if}}
31
58
  {{#if this.confirmSubmit}}
32
59
  confirmSubmit: {
33
- state: '{{this.confirmSubmit.state}}',
34
- message: '{{this.confirmSubmit.message}}'
60
+ state: '{{#if this.confirmSubmit.state}}{{this.confirmSubmit.state}}{{else}}enabled{{/if}}',
61
+ message: {{{this.confirmSubmitMessageJs}}},
35
62
  },
36
63
  {{/if}}
37
64
  requiresSelection: true,
38
65
  },
39
66
  {{/each}}
40
- ];
67
+ ];
@@ -1,6 +1,5 @@
1
1
  import { UiSchema } from '@genesislcap/foundation-forms';
2
2
 
3
3
  {{#if tile.config.filterFormUiSchema}}
4
- export const filterFormSchema: UiSchema = {{{ tile.config.filterFormUiSchema }}}
4
+ export const filterFormSchema: UiSchema = {{{ tile.config.filterFormUiSchema }}};
5
5
  {{/if}}
6
-
@@ -1,8 +1,17 @@
1
- import { GridOptions } from '@ag-grid-community/core';
2
- import { getNumberFormatter, getDateFormatter } from '@genesislcap/foundation-utils';
1
+ import type { GridOptions } from '@ag-grid-community/core';
2
+ {{#ifContains tile.config.gridOptions "getNumberFormatter"}}
3
+ import { getNumberFormatter{{#ifContains tile.config.gridOptions "getDateFormatter"}}, getDateFormatter{{/ifContains}} } from '@genesislcap/foundation-utils';
4
+ {{else}}
5
+ {{#ifContains tile.config.gridOptions "getDateFormatter"}}
6
+ import { getDateFormatter } from '@genesislcap/foundation-utils';
7
+ {{/ifContains}}
8
+ {{/ifContains}}
3
9
  {{#if route.FDC3EventHandlersEnabled}}
10
+ {{#ifContains tile.config.gridOptions "sendEventOnChannel"}}
4
11
  import { sendEventOnChannel } from '../../../utils';
12
+ {{/ifContains}}
5
13
  {{/if}}
14
+
6
15
  {{#if tile.config.gridOptions}}
7
- export const gridOptions: GridOptions = {{{ tile.config.gridOptions }}}
16
+ export const gridOptions: GridOptions = {{{ tile.config.gridOptions }}};
8
17
  {{/if}}
@@ -1,31 +1,30 @@
1
+ {{#if tile.config.columns}}
2
+ import type { ColDef } from '@ag-grid-community/core';
3
+ {{/if}}
1
4
  import { Connect } from '@genesislcap/foundation-comms';
2
5
  import { User } from '@genesislcap/foundation-user';
3
- import { customElement, GenesisElement, observable } from '@genesislcap/web-core';
4
- {{#if tile.config.gridOptions}}
5
- import { gridOptions as baseGridOptions } from './{{kebabCase tile.title}}.gridOptions';
6
- {{/if}}
6
+ import { customElement, GenesisElement{{#if tile.config.columns}}, observable{{/if}} } from '@genesislcap/web-core';
7
7
  {{#if tile.config.eventing.publishEventName}}
8
- import { actions } from '../../../store/store';
9
- {{/if}}
8
+ import { actions{{#if tile.config.eventing.listener}}, selectors{{/if}} } from '../../../store/store';
9
+ {{else}}
10
10
  {{#if tile.config.eventing.listener}}
11
11
  import { selectors } from '../../../store/store';
12
12
  {{/if}}
13
- import { {{pascalCase tile.title}}Styles as styles } from './{{kebabCase tile.title}}.styles';
14
- import { {{pascalCase tile.title}}Template as template } from './{{kebabCase tile.title}}.template';
13
+ {{/if}}
15
14
  {{#if tile.config.columns}}
16
15
  import { columnDefs } from './{{kebabCase tile.title}}.column.defs';
17
- import { ColDef } from '@ag-grid-community/core';
18
16
  {{/if}}
17
+ import { {{pascalCase tile.title}}Styles as styles } from './{{kebabCase tile.title}}.styles';
18
+ import { {{pascalCase tile.title}}Template as template } from './{{kebabCase tile.title}}.template';
19
19
 
20
20
  {{#ifAny tile.metadata.comment tile.metadata.todo}}
21
21
  /**
22
22
  {{~#if tile.metadata.comment}}{{{ tile.metadata.comment }}}{{/if}}
23
- {{~#if tile.metadata.todo}}{{#if tile.metadata.comment}}
23
+ {{~#if tile.metadata.todo}}{{#if tile.metadata.comment}}
24
24
  *{{/if}}
25
25
  * TODO: {{{ tile.metadata.todo }}}{{/if}}
26
26
  */
27
27
  {{/ifAny}}
28
-
29
28
  @customElement({
30
29
  name: '{{kebabCase tile.componentName}}',
31
30
  template,
@@ -34,13 +33,12 @@ import { ColDef } from '@ag-grid-community/core';
34
33
  export class {{pascalCase tile.componentName}} extends GenesisElement {
35
34
  @User user: User;
36
35
  @Connect connect!: Connect;
36
+ {{#if tile.config.columns}}
37
+
38
+ @observable columns: ColDef[] = [...columnDefs];
39
+ {{/if}}
40
+ {{#if tile.config.eventing.publishEventName}}
37
41
 
38
- {{#if tile.config.columns}}
39
- @observable columns: ColDef[] = [
40
- ...columnDefs,
41
- ];
42
- {{/if}}
43
- {{#if tile.config.eventing.publishEventName}}
44
42
  public handleRowSelection = (e: any) => {
45
43
  const selectedRows = e.api.getSelectedRows();
46
44
  if (!selectedRows || !selectedRows.length) {
@@ -50,11 +48,12 @@ export class {{pascalCase tile.componentName}} extends GenesisElement {
50
48
  const { TIMESTAMP, RECORD_ID, ROW_REF, ...data } = selectedRows[0];
51
49
  actions.eventing.publish{{pascalCase tile.config.eventing.publishEventName}}(data);
52
50
  };
53
- {{/if}}
54
- {{#if tile.config.eventing.listener}}
51
+ {{/if}}
52
+ {{#if tile.config.eventing.listener}}
53
+
55
54
  getCriteria() {
56
55
  const c = selectors.eventing.getCriteriaFor{{pascalCase tile.title}}();
57
56
  return c || '';
58
57
  }
59
- {{/if}}
58
+ {{/if}}
60
59
  }