@genesislcap/blank-app-seed 5.7.0 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.genx/configure.js +114 -0
- package/.genx/package.json +5 -2
- package/.genx/prompts/api.js +25 -0
- package/.genx/prompts/ui.js +12 -0
- package/.genx/prompts.js +8 -2
- package/.genx/static.js +1 -0
- package/.genx/templates/angular/component/component.filter.form.hbs +6 -0
- package/.genx/templates/angular/component/component.hbs +36 -4
- package/.genx/templates/angular/entityManager.hbs +23 -6
- package/.genx/templates/angular/grid.hbs +5 -2
- package/.genx/templates/angular/slices/eventing.slice.hbs +41 -0
- package/.genx/templates/angular/store.hbs +14 -0
- package/.genx/templates/angular/tabsLayout.hbs +1 -1
- package/.genx/templates/react/component/component.filter.form.hbs +6 -0
- package/.genx/templates/react/component/component.hbs +90 -15
- package/.genx/templates/react/entityManager.hbs +17 -17
- package/.genx/templates/react/grid.hbs +5 -9
- package/.genx/templates/react/gridLayout.hbs +4 -4
- package/.genx/templates/react/horizontalLayout.hbs +1 -1
- package/.genx/templates/react/route.hbs +12 -1
- package/.genx/templates/react/slices/eventing.slice.hbs +39 -0
- package/.genx/templates/react/store.hbs +22 -0
- package/.genx/templates/react/tabsLayout.hbs +2 -2
- package/.genx/templates/web-components/component/component.filter.form.hbs +6 -0
- package/.genx/templates/web-components/component/component.hbs +26 -0
- package/.genx/templates/web-components/component/component.template.hbs +3 -0
- package/.genx/templates/web-components/entityManager.hbs +23 -9
- package/.genx/templates/web-components/grid.hbs +13 -5
- package/.genx/templates/web-components/slices/eventing.slice.hbs +44 -0
- package/.genx/templates/web-components/store.hbs +18 -0
- package/.genx/utils/fontUtils.js +75 -0
- package/.genx/utils/formatRouteData.js +7 -0
- package/.genx/utils/generateRoute.js +1 -1
- package/.genx/utils/generateStore.js +98 -0
- package/.genx/utils/generateTile.js +13 -0
- package/.genx/utils/index.js +4 -0
- package/.genx/versions.json +3 -3
- package/.github/CODEOWNERS +1 -1
- package/.github/pull_request_template.md +6 -0
- package/.github/workflows/upgrade.yml +0 -1
- package/CHANGELOG.md +508 -11
- package/client-tmp/angular/package.json +5 -0
- package/client-tmp/angular/src/app/app.component.ts +2 -1
- package/client-tmp/angular/src/app/app.module.ts +3 -0
- package/client-tmp/angular/src/app/layouts/default/default.layout.css +8 -0
- package/client-tmp/angular/src/app/layouts/default/default.layout.html +3 -0
- package/client-tmp/angular/src/app/share/genesis-components.ts +14 -2
- package/client-tmp/angular/src/styles/design-tokens.json +5 -1
- package/client-tmp/angular/src/styles/styles.css +15 -1
- package/client-tmp/react/index.html +0 -1
- package/client-tmp/react/package.json +17 -28
- package/client-tmp/react/public/index.html +3 -1
- package/client-tmp/react/src/App.tsx +47 -32
- package/client-tmp/react/src/components/routes/AppRoutes.tsx +4 -4
- package/client-tmp/react/src/config.ts +1 -1
- package/client-tmp/react/src/layouts/blank/BlankLayout.tsx +1 -1
- package/client-tmp/react/src/layouts/default/DefaultLayout.module.css +8 -0
- package/client-tmp/react/src/layouts/default/DefaultLayout.tsx +15 -4
- package/client-tmp/react/src/main.tsx +1 -1
- package/client-tmp/react/src/pages/AuthPage/AuthPage.tsx +1 -1
- package/client-tmp/react/src/pages/NotFoundPage/NotFoundPage.tsx +1 -1
- package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.test.tsx +1 -1
- package/client-tmp/react/src/pages/NotPermittedPage/NotPermittedPage.tsx +1 -1
- package/client-tmp/react/src/pbc/container.tsx +1 -1
- package/client-tmp/react/src/services/store.service.ts +20 -9
- package/client-tmp/react/src/share/foundation-login.ts +2 -2
- package/client-tmp/react/src/share/genesis-components.ts +14 -2
- package/client-tmp/react/src/store/RoutesContext.tsx +8 -7
- package/client-tmp/react/src/styles/design-tokens.json +5 -1
- package/client-tmp/react/src/styles/styles.css +15 -1
- package/client-tmp/react/src/utils/getLayoutNameByRoute.ts +1 -1
- package/client-tmp/react/src/utils/goldenLayout.helper.ts +59 -0
- package/client-tmp/react/src/utils/useDocumentTitle.ts +46 -0
- package/client-tmp/react/test/e2e/fixture.ts +1 -1
- package/client-tmp/web-components/package.json +4 -0
- package/client-tmp/web-components/src/components/components.ts +20 -10
- package/client-tmp/web-components/src/layouts/default.ts +12 -1
- package/client-tmp/web-components/src/main/main.css +12 -0
- package/client-tmp/web-components/src/main/main.ts +1 -1
- package/client-tmp/web-components/src/routes/config.ts +5 -6
- package/client-tmp/web-components/src/styles/design-tokens.json +5 -1
- package/client-tmp/web-components/src/styles/typography.ts +6 -4
- package/package.json +1 -1
- package/server/settings.gradle.kts +0 -3
- package/client-tmp/react/lint-css.ts +0 -19
- package/client-tmp/react/vite.config.ts +0 -70
- /package/client-tmp/angular/src/app/store/{store.ts → foundation-store.ts} +0 -0
- /package/client-tmp/web-components/src/store/{store.ts → foundation-store.ts} +0 -0
package/.genx/configure.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
const versions = require('./versions.json');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const {
|
|
5
|
+
DIRS_MAP,
|
|
6
|
+
DIR_CLIENT_MAIN_ALIAS,
|
|
7
|
+
DIR_CLIENT_TEMP_ALIAS,
|
|
8
|
+
FRAMEWORKS_DIR_MAP,
|
|
9
|
+
} = require('./static');
|
|
2
10
|
const {
|
|
3
11
|
excludeFrameworks,
|
|
4
12
|
formatRouteData,
|
|
@@ -8,6 +16,8 @@ const {
|
|
|
8
16
|
registerPartials,
|
|
9
17
|
validateRoute,
|
|
10
18
|
deleteGradleWrappers,
|
|
19
|
+
generateStore,
|
|
20
|
+
fontUtils,
|
|
11
21
|
} = require('./utils');
|
|
12
22
|
|
|
13
23
|
/**
|
|
@@ -38,8 +48,111 @@ module.exports = async (data, utils) => {
|
|
|
38
48
|
includeDependencies: !!(FDC3ListenersEnabled || FDC3EventHandlersEnabled),
|
|
39
49
|
channels: data.ui?.fdc3?.channels || [],
|
|
40
50
|
};
|
|
51
|
+
|
|
52
|
+
if (data.designTokens && Object.keys(data.designTokens).length > 0) {
|
|
53
|
+
try {
|
|
54
|
+
const frameworkDir = FRAMEWORKS_DIR_MAP.get(data.framework);
|
|
55
|
+
const templateFile = path.join(__dirname, '..', DIR_CLIENT_TEMP_ALIAS, frameworkDir, 'src/styles/design-tokens.json');
|
|
56
|
+
const jsonContent = JSON.stringify(data.designTokens, null, 2);
|
|
57
|
+
const templateDir = path.dirname(templateFile);
|
|
58
|
+
if (!fs.existsSync(templateDir)) {
|
|
59
|
+
fs.mkdirSync(templateDir, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
fs.writeFileSync(templateFile, jsonContent);
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.warn('Failed to write designTokens to template:', err?.message || err);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Handle header logo copy
|
|
68
|
+
if (data.headerLogo && data.headerLogo.trim() !== '') {
|
|
69
|
+
try {
|
|
70
|
+
const sourcePath = path.resolve(data.headerLogo);
|
|
71
|
+
if (!fs.existsSync(sourcePath)) {
|
|
72
|
+
console.warn(`Header logo file not found: ${sourcePath}`);
|
|
73
|
+
} else {
|
|
74
|
+
const ext = path.extname(sourcePath);
|
|
75
|
+
const frameworkDir = FRAMEWORKS_DIR_MAP.get(data.framework);
|
|
76
|
+
let targetDir;
|
|
77
|
+
|
|
78
|
+
// Angular uses src/assets, others use public
|
|
79
|
+
if (data.framework === 'angular') {
|
|
80
|
+
targetDir = path.join(__dirname, '..', DIR_CLIENT_TEMP_ALIAS, frameworkDir, 'src/assets');
|
|
81
|
+
} else {
|
|
82
|
+
targetDir = path.join(__dirname, '..', DIR_CLIENT_TEMP_ALIAS, frameworkDir, 'public');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Ensure target directory exists
|
|
86
|
+
if (!fs.existsSync(targetDir)) {
|
|
87
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const targetPath = path.join(targetDir, `header-logo${ext}`);
|
|
91
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
92
|
+
|
|
93
|
+
// Store the logo source path for templates
|
|
94
|
+
data.headerLogoSrc = `./header-logo${ext}`;
|
|
95
|
+
|
|
96
|
+
console.log(`Header logo copied to: ${targetPath}`);
|
|
97
|
+
}
|
|
98
|
+
} catch (err) {
|
|
99
|
+
console.warn('Failed to copy header logo:', err?.message || err);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Handle custom fonts
|
|
104
|
+
if (data.customFonts && data.customFonts.trim() !== '') {
|
|
105
|
+
try {
|
|
106
|
+
const customFontsObj = typeof data.customFonts === 'string'
|
|
107
|
+
? JSON.parse(data.customFonts)
|
|
108
|
+
: data.customFonts;
|
|
109
|
+
|
|
110
|
+
const processedFonts = fontUtils.processFontFiles(customFontsObj);
|
|
111
|
+
|
|
112
|
+
if (processedFonts) {
|
|
113
|
+
const { fontFamily, fontData } = processedFonts;
|
|
114
|
+
const frameworkDir = FRAMEWORKS_DIR_MAP.get(data.framework);
|
|
115
|
+
|
|
116
|
+
// Set data immediately so templates can use it even if file copy fails
|
|
117
|
+
data.fontFamily = fontFamily;
|
|
118
|
+
data.fontData = fontData;
|
|
119
|
+
|
|
120
|
+
// Determine target directory
|
|
121
|
+
let targetDir;
|
|
122
|
+
if (data.framework === 'angular') {
|
|
123
|
+
targetDir = path.join(__dirname, '..', DIR_CLIENT_TEMP_ALIAS, frameworkDir, 'src/assets/fonts');
|
|
124
|
+
} else {
|
|
125
|
+
targetDir = path.join(__dirname, '..', DIR_CLIENT_TEMP_ALIAS, frameworkDir, 'public/fonts');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Create directory
|
|
129
|
+
if (!fs.existsSync(targetDir)) {
|
|
130
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Copy font files
|
|
134
|
+
customFontsObj.files.forEach((fontPath, index) => {
|
|
135
|
+
const sourcePath = path.resolve(fontPath.trim());
|
|
136
|
+
|
|
137
|
+
if (fs.existsSync(sourcePath)) {
|
|
138
|
+
const fileName = path.basename(sourcePath);
|
|
139
|
+
const targetPath = path.join(targetDir, fileName);
|
|
140
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
141
|
+
console.log(`Font copied: ${fileName}`);
|
|
142
|
+
} else {
|
|
143
|
+
console.warn(`Font file not found: ${sourcePath}`);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
} catch (err) {
|
|
148
|
+
console.warn('Failed to process custom fonts:', err?.message || err);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
41
152
|
excludeFrameworks(data.framework);
|
|
42
153
|
|
|
154
|
+
generateStore(data.routes, utils, data.framework);
|
|
155
|
+
|
|
43
156
|
data.routes.forEach((route) => {
|
|
44
157
|
generateRoute(route, utils, data.framework);
|
|
45
158
|
});
|
|
@@ -50,6 +163,7 @@ module.exports = async (data, utils) => {
|
|
|
50
163
|
generateCsv(entity, utils);
|
|
51
164
|
});
|
|
52
165
|
|
|
166
|
+
|
|
53
167
|
if (data.excludeGradleWrapper) {
|
|
54
168
|
deleteGradleWrappers();
|
|
55
169
|
}
|
package/.genx/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genesislcap/blank-app-seed-config",
|
|
3
3
|
"description": "Genesis Blank App Seed Configuration",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.8.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"lint": "eslint .",
|
|
@@ -38,17 +38,20 @@
|
|
|
38
38
|
"product-info",
|
|
39
39
|
".yml",
|
|
40
40
|
".sh",
|
|
41
|
-
".json",
|
|
42
41
|
".js",
|
|
43
42
|
".kt",
|
|
44
43
|
".kts",
|
|
45
44
|
".ts",
|
|
45
|
+
".css",
|
|
46
46
|
".md",
|
|
47
47
|
".properties",
|
|
48
48
|
".html",
|
|
49
49
|
".gitignore",
|
|
50
50
|
".xml",
|
|
51
51
|
".iml"
|
|
52
|
+
],
|
|
53
|
+
"exclude": [
|
|
54
|
+
"design-tokens.json"
|
|
52
55
|
]
|
|
53
56
|
}
|
|
54
57
|
}
|
package/.genx/prompts/api.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const { websocketValidator } = require('./validators');
|
|
2
2
|
const { TEXTS } = require('../static');
|
|
3
3
|
|
|
4
|
+
const defaultHeaderLogo = '';
|
|
5
|
+
|
|
4
6
|
const apiHostIntro = () => console.log(TEXTS.INTRO_API_HOST);
|
|
5
7
|
const ssoIntro = () => console.log(TEXTS.INTRO_API_SSO);
|
|
6
8
|
|
|
@@ -26,8 +28,31 @@ module.exports = async (inquirer, prevAns = {}) => {
|
|
|
26
28
|
when: prevAns.enableSSO === undefined,
|
|
27
29
|
},
|
|
28
30
|
]);
|
|
31
|
+
|
|
32
|
+
const { headerLogo = prevAns.headerLogo } = await inquirer.prompt([
|
|
33
|
+
{
|
|
34
|
+
name: 'headerLogo',
|
|
35
|
+
type: 'input',
|
|
36
|
+
message: 'Header logo file path (optional)',
|
|
37
|
+
default: defaultHeaderLogo,
|
|
38
|
+
when: prevAns.headerLogo === undefined,
|
|
39
|
+
},
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
const { customFonts = prevAns.customFonts } = await inquirer.prompt([
|
|
43
|
+
{
|
|
44
|
+
name: 'customFonts',
|
|
45
|
+
type: 'input',
|
|
46
|
+
message: 'Custom fonts JSON (optional, e.g. {"files":["./Font-Regular.ttf","./Font-Bold.ttf"]})',
|
|
47
|
+
default: prevAns.customFonts || '',
|
|
48
|
+
when: prevAns.customFonts === undefined,
|
|
49
|
+
},
|
|
50
|
+
]);
|
|
51
|
+
|
|
29
52
|
return {
|
|
30
53
|
apiHost,
|
|
31
54
|
enableSSO,
|
|
55
|
+
headerLogo,
|
|
56
|
+
customFonts,
|
|
32
57
|
};
|
|
33
58
|
};
|
package/.genx/prompts/ui.js
CHANGED
|
@@ -13,6 +13,9 @@ const parseRoutes = parseJSONArgument('routes', defaultRoutes);
|
|
|
13
13
|
const defaultUI = {};
|
|
14
14
|
const parseUI = parseJSONArgument('ui', defaultUI);
|
|
15
15
|
|
|
16
|
+
const defaultDesignTokens = {};
|
|
17
|
+
const parseDesignTokens = parseJSONArgument('designTokens', defaultDesignTokens);
|
|
18
|
+
|
|
16
19
|
const selectedFrameworkInfo = (framework) => {
|
|
17
20
|
if (framework && frameworkValidator(framework) === true) {
|
|
18
21
|
console.log(
|
|
@@ -28,6 +31,7 @@ module.exports = async (inquirer, prevAns = {}) => {
|
|
|
28
31
|
framework = prevAns.framework,
|
|
29
32
|
ui = prevAns.ui,
|
|
30
33
|
routes = prevAns.routes,
|
|
34
|
+
designTokens = prevAns.designTokens,
|
|
31
35
|
} = await inquirer.prompt([
|
|
32
36
|
{
|
|
33
37
|
name: 'framework',
|
|
@@ -55,11 +59,19 @@ module.exports = async (inquirer, prevAns = {}) => {
|
|
|
55
59
|
when: !prevAns.routes,
|
|
56
60
|
default: JSON.stringify(defaultRoutes),
|
|
57
61
|
},
|
|
62
|
+
{
|
|
63
|
+
name: 'designTokens',
|
|
64
|
+
type: 'input',
|
|
65
|
+
message: TEXTS.MESSAGE_UI_DESIGN_TOKENS,
|
|
66
|
+
when: !prevAns.designTokens,
|
|
67
|
+
default: JSON.stringify(defaultDesignTokens),
|
|
68
|
+
},
|
|
58
69
|
]);
|
|
59
70
|
|
|
60
71
|
return {
|
|
61
72
|
routes: parseRoutes(routes),
|
|
62
73
|
ui: parseUI(ui),
|
|
74
|
+
designTokens: parseDesignTokens(designTokens),
|
|
63
75
|
framework: normalizeFrameworkAlias(framework),
|
|
64
76
|
};
|
|
65
77
|
};
|
package/.genx/prompts.js
CHANGED
|
@@ -16,7 +16,7 @@ module.exports = async (inquirer, prevAns = {}) => {
|
|
|
16
16
|
Version: ${version}
|
|
17
17
|
License: ${license}`);
|
|
18
18
|
|
|
19
|
-
const { apiHost, enableSSO } = await apiPrompts(inquirer, prevAns);
|
|
19
|
+
const { apiHost, enableSSO, headerLogo, customFonts } = await apiPrompts(inquirer, prevAns);
|
|
20
20
|
const {
|
|
21
21
|
description,
|
|
22
22
|
groupId,
|
|
@@ -25,12 +25,17 @@ module.exports = async (inquirer, prevAns = {}) => {
|
|
|
25
25
|
csv,
|
|
26
26
|
excludeGradleWrapper,
|
|
27
27
|
} = await genesisServerPrompts(inquirer, prevAns);
|
|
28
|
-
const { routes, ui, framework } = await uiPrompts(
|
|
28
|
+
const { routes, ui, framework, designTokens } = await uiPrompts(
|
|
29
|
+
inquirer,
|
|
30
|
+
prevAns,
|
|
31
|
+
);
|
|
29
32
|
|
|
30
33
|
return {
|
|
31
34
|
apiHost,
|
|
32
35
|
routes,
|
|
33
36
|
enableSSO,
|
|
37
|
+
headerLogo,
|
|
38
|
+
customFonts,
|
|
34
39
|
description,
|
|
35
40
|
groupId,
|
|
36
41
|
applicationVersion,
|
|
@@ -39,5 +44,6 @@ module.exports = async (inquirer, prevAns = {}) => {
|
|
|
39
44
|
ui,
|
|
40
45
|
framework,
|
|
41
46
|
excludeGradleWrapper,
|
|
47
|
+
designTokens,
|
|
42
48
|
};
|
|
43
49
|
};
|
package/.genx/static.js
CHANGED
|
@@ -78,6 +78,7 @@ const TEXTS = {
|
|
|
78
78
|
'Generate empty CSV for entities? (config in JSON format)',
|
|
79
79
|
MESSAGE_UI_ROTUES: 'Pages config in JSON format',
|
|
80
80
|
MESSAGE_UI_CONFIG: 'UI configuration in JSON format',
|
|
81
|
+
MESSAGE_UI_DESIGN_TOKENS: 'Design tokens JSON (leave empty to use defaults)',
|
|
81
82
|
MESSAGE_UI_FRAMEWORK: 'Framework',
|
|
82
83
|
ERROR_VALIDATOR_FRAMEWORK: 'Selected framework is not supported',
|
|
83
84
|
ERROR_VALIDATOR_WEBSOCKET: 'Not a valid websocket',
|
|
@@ -18,12 +18,19 @@ import { createFormSchema } from './{{kebabCase tile.title}}.create.form.schema'
|
|
|
18
18
|
{{#if tile.config.updateFormUiSchema}}
|
|
19
19
|
import { updateFormSchema } from './{{kebabCase tile.title}}.update.form.schema';
|
|
20
20
|
{{/if}}
|
|
21
|
+
{{#if tile.config.filterFormUiSchema}}
|
|
22
|
+
import { filterFormSchema } from './{{kebabCase tile.title}}.filter.form.schema';
|
|
23
|
+
{{/if}}
|
|
21
24
|
{{#if tile.config.columns}}
|
|
22
25
|
import { columnDefs } from './{{kebabCase tile.title}}.column.defs';
|
|
23
26
|
{{/if}}
|
|
24
27
|
{{#if tile.config.gridOptions}}
|
|
25
28
|
import { gridOptions } from './{{kebabCase tile.title}}.gridOptions';
|
|
26
29
|
{{/if}}
|
|
30
|
+
{{#ifAny tile.config.eventing.publishEventName tile.config.eventing.listener}}
|
|
31
|
+
import { actions, selectors } from '../../../store/store';
|
|
32
|
+
import { injectSelector } from '@reduxjs/angular-redux';
|
|
33
|
+
{{/ifAny}}
|
|
27
34
|
|
|
28
35
|
{{#ifAny tile.metadata.comment tile.metadata.todo}}
|
|
29
36
|
/**
|
|
@@ -49,9 +56,9 @@ export class {{pascalCase tile.componentName}} {
|
|
|
49
56
|
hasUserPermission = (permissionCode: string) => getViewUpdateRightComponent(getUser(), permissionCode);{{#if tile.config.createFormUiSchema}}
|
|
50
57
|
createFormSchema = createFormSchema;{{/if}}{{#if tile.config.uischema}}
|
|
51
58
|
uischema = createFormSchema;{{/if}}{{#if tile.config.updateFormUiSchema}}
|
|
52
|
-
updateFormSchema = updateFormSchema;{{/if}}{{#if tile.config.
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
updateFormSchema = updateFormSchema;{{/if}}{{#if tile.config.filterFormUiSchema}}
|
|
60
|
+
filterFormSchema = filterFormSchema;{{/if}}{{#if tile.config.gridOptions}}
|
|
61
|
+
gridOptions = gridOptions as GridOptionsConfig;{{/if}}{{#if tile.config.columns}}
|
|
55
62
|
columnDefs = [
|
|
56
63
|
...columnDefs,
|
|
57
64
|
];{{/if}}{{#if tile.config.type}}
|
|
@@ -62,5 +69,30 @@ export class {{pascalCase tile.componentName}} {
|
|
|
62
69
|
"xField": "groupBy",
|
|
63
70
|
"yField": "value",{{/ifEquals}}
|
|
64
71
|
};{{/if}}{{#if tile.config.customEvents}}
|
|
65
|
-
customActions = emCustomActions;{{/if}}
|
|
72
|
+
customActions = emCustomActions;{{/if}}{{#ifAny tile.config.eventing.publishEventName tile.config.eventing.listener}}
|
|
73
|
+
{{#if tile.config.eventing.listener}}
|
|
74
|
+
criteria = injectSelector(selectors.eventing.getCriteriaFor{{pascalCase tile.title}});
|
|
75
|
+
{{/if}}
|
|
76
|
+
{{/ifAny}}{{#if tile.config.eventing.publishEventName}}
|
|
77
|
+
handleRowSelection = (e: any) => {
|
|
78
|
+
{{#ifEquals tile.componentType 'grid'}}
|
|
79
|
+
const selectedRows = e.api.getSelectedRows();
|
|
80
|
+
{{else}}
|
|
81
|
+
const selectedRows = e.detail.api.getSelectedRows();
|
|
82
|
+
{{/ifEquals}}
|
|
83
|
+
if (!selectedRows || !selectedRows.length) {
|
|
84
|
+
actions.eventing.publish{{pascalCase tile.config.eventing.publishEventName}}(null);
|
|
85
|
+
return;
|
|
86
|
+
};
|
|
87
|
+
const { TIMESTAMP, RECORD_ID, ROW_REF, ...data } = selectedRows[0];
|
|
88
|
+
actions.eventing.publish{{pascalCase tile.config.eventing.publishEventName}}(data);
|
|
89
|
+
};{{/if}}
|
|
90
|
+
{{#ifAny tile.config.gridOptions tile.config.eventing.publishEventName}}
|
|
91
|
+
gridOptionsModel = {
|
|
92
|
+
{{#if tile.config.gridOptions}}
|
|
93
|
+
onRowClicked: gridOptions?.onRowClicked,{{/if}}{{#if tile.config.eventing.publishEventName}}{{#ifEquals tile.componentType 'grid'}}
|
|
94
|
+
onSelectionChanged: this.handleRowSelection,
|
|
95
|
+
rowSelection: 'single'{{/ifEquals}}{{/if}}
|
|
96
|
+
};
|
|
97
|
+
{{/ifAny}}
|
|
66
98
|
}
|
|
@@ -25,14 +25,25 @@
|
|
|
25
25
|
[deleteEvent]="hasUserPermission('{{config.permissions.updateRight}}') ? '{{ config.deleteEvent }}' : undefined"
|
|
26
26
|
{{/if}}
|
|
27
27
|
{{#if config.gridOptions}}
|
|
28
|
-
[gridOptions]="
|
|
28
|
+
[gridOptions]="gridOptionsModel"
|
|
29
29
|
{{/if}}
|
|
30
|
-
{{#if config.
|
|
31
|
-
|
|
32
|
-
{{/if}}
|
|
33
|
-
{{#if config.reqrep}}
|
|
34
|
-
[datasourceConfig]="reqrep"
|
|
30
|
+
{{#if config.eventing.publishEventName}}
|
|
31
|
+
(selectionChanged)="handleRowSelection($event)"
|
|
35
32
|
{{/if}}
|
|
33
|
+
{{#ifAny config.snapshot config.reqrep config.eventing.listener}}
|
|
34
|
+
[datasourceConfig]="{
|
|
35
|
+
{{#if config.snapshot}}
|
|
36
|
+
isSnapshot: {{ config.snapshot }},
|
|
37
|
+
{{/if}}
|
|
38
|
+
{{#if config.reqrep}}
|
|
39
|
+
pollingInterval: 5000,
|
|
40
|
+
requestAutoSetup: false,
|
|
41
|
+
{{/if}}
|
|
42
|
+
{{#if config.eventing.listener}}
|
|
43
|
+
criteria: criteria()
|
|
44
|
+
{{/if}}
|
|
45
|
+
}"
|
|
46
|
+
{{/ifAny}}
|
|
36
47
|
{{#if config.entityName}}
|
|
37
48
|
entityLabel="{{ config.entityName }}"
|
|
38
49
|
{{/if}}
|
|
@@ -48,6 +59,12 @@
|
|
|
48
59
|
{{#if config.enableSearchBar}}
|
|
49
60
|
enable-search-bar
|
|
50
61
|
{{/if}}
|
|
62
|
+
{{#if config.enableFilters}}
|
|
63
|
+
enable-filters
|
|
64
|
+
{{#if config.filterFormUiSchema}}
|
|
65
|
+
[filtersUiSchema]="filterFormSchema"
|
|
66
|
+
{{/if}}
|
|
67
|
+
{{/if}}
|
|
51
68
|
{{#if config.customEvents}}
|
|
52
69
|
[customActions]="customActions"
|
|
53
70
|
{{/if}}
|
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
polling-interval="5000"
|
|
15
15
|
request-auto-setup="false"
|
|
16
16
|
{{/if}}
|
|
17
|
-
{{#if config.
|
|
18
|
-
[
|
|
17
|
+
{{#if config.eventing.listener}}
|
|
18
|
+
[criteria]="criteria()"
|
|
19
19
|
{{/if}}
|
|
20
|
+
{{#ifAny config.gridOptions config.eventing.publishEventName}}
|
|
21
|
+
[deferredGridOptions]="gridOptionsModel"
|
|
22
|
+
{{/ifAny}}
|
|
20
23
|
></grid-pro-genesis-datasource>
|
|
21
24
|
{{#if config.gridOptions}}
|
|
22
25
|
<grid-pro-column *ngFor="let columnDef of gridOptions?.columnDefs" [definition]="columnDef"></grid-pro-column>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { CriteriaBuilder, ExpressionBuilder, Serialisers } from '@genesislcap/foundation-criteria';
|
|
2
|
+
import { createSlice } from '@genesislcap/foundation-redux';
|
|
3
|
+
|
|
4
|
+
export const eventingSlice = createSlice({
|
|
5
|
+
name: 'eventing',
|
|
6
|
+
initialState: {
|
|
7
|
+
{{#each events}}
|
|
8
|
+
{{this}}: null{{#unless @last}},{{/unless}}
|
|
9
|
+
{{/each}}
|
|
10
|
+
},
|
|
11
|
+
reducers: {
|
|
12
|
+
{{#each events}}
|
|
13
|
+
publish{{pascalCase this}}: (state, action) => {
|
|
14
|
+
state.{{this}} = action.payload;
|
|
15
|
+
}{{#unless @last}},{{/unless}}
|
|
16
|
+
{{/each}}
|
|
17
|
+
},
|
|
18
|
+
selectors: {
|
|
19
|
+
{{#each listeners}}
|
|
20
|
+
getCriteriaFor{{pascalCase tileName}}: (state) => {
|
|
21
|
+
const criteriaBuilder = new CriteriaBuilder();
|
|
22
|
+
const data: any = state.{{eventName}};
|
|
23
|
+
if (!data) return '';
|
|
24
|
+
|
|
25
|
+
{{#each mappings}}
|
|
26
|
+
if (data.{{sourceField}}) {
|
|
27
|
+
criteriaBuilder.And(new ExpressionBuilder()
|
|
28
|
+
.withField('{{targetField}}')
|
|
29
|
+
.withValue(data.{{sourceField}})
|
|
30
|
+
.withSerialiser(Serialisers.EQ)
|
|
31
|
+
.build());
|
|
32
|
+
}
|
|
33
|
+
{{/each}}
|
|
34
|
+
|
|
35
|
+
return criteriaBuilder.build();
|
|
36
|
+
}{{#unless @last}},{{/unless}}
|
|
37
|
+
{{/each}}
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createStore } from '@genesislcap/foundation-redux';
|
|
2
|
+
import { eventingSlice } from './slices/eventing.slice';
|
|
3
|
+
|
|
4
|
+
export const { reduxStore, store, actions, selectors } = createStore([eventingSlice], {
|
|
5
|
+
eventing: {
|
|
6
|
+
{{#each events}}
|
|
7
|
+
{{this}}: null{{#unless @last}},{{/unless}}
|
|
8
|
+
{{/each}}
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type Store = typeof store;
|
|
13
|
+
export type Actions = typeof actions;
|
|
14
|
+
export type Selectors = typeof selectors;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<rapid-layout-region type="tabs">
|
|
2
2
|
{{#each route.tiles}}
|
|
3
3
|
<rapid-layout-item title="{{this.title}}">
|
|
4
|
-
{{
|
|
4
|
+
<app-{{kebabCase this.componentName}}></app-{{kebabCase this.componentName}}>
|
|
5
5
|
</rapid-layout-item>
|
|
6
6
|
{{/each}}
|
|
7
7
|
</rapid-layout-region>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
1
2
|
{{#if tile.config.permissions.viewRight~}}
|
|
2
3
|
import { getUser } from '@genesislcap/foundation-user';
|
|
3
4
|
import { getViewUpdateRightComponent } from '../../../utils';
|
|
@@ -22,6 +23,9 @@ import { createFormSchema as createFormSchemaTile } from './{{pascalCase tile.ti
|
|
|
22
23
|
{{#if tile.config.updateFormUiSchema~}}
|
|
23
24
|
import { updateFormSchema as updateFormSchemaTile } from './{{pascalCase tile.title}}UpdateFormSchema';
|
|
24
25
|
{{/if}}
|
|
26
|
+
{{#if tile.config.filterFormUiSchema~}}
|
|
27
|
+
import { filterFormSchema as filterFormSchemaTile } from './{{pascalCase tile.title}}FilterFormSchema';
|
|
28
|
+
{{/if}}
|
|
25
29
|
{{#if tile.config.columns~}}
|
|
26
30
|
import { columnDefs as columnDefsTile } from './{{pascalCase tile.title}}ColumnDefs';
|
|
27
31
|
{{/if}}
|
|
@@ -29,6 +33,15 @@ import { columnDefs as columnDefsTile } from './{{pascalCase tile.title}}ColumnD
|
|
|
29
33
|
import { GridOptionsConfig } from '@genesislcap/rapid-grid-pro';
|
|
30
34
|
import { gridOptions as gridOptionsTile } from './{{pascalCase tile.title}}GridOptions';
|
|
31
35
|
{{/if}}
|
|
36
|
+
{{#if tile.config.eventing.publishEventName}}
|
|
37
|
+
import { actions } from '../../../store/store';
|
|
38
|
+
{{/if}}
|
|
39
|
+
{{#if tile.config.eventing.listener}}
|
|
40
|
+
import { useSelector } from 'react-redux';
|
|
41
|
+
import { selectors } from '../../../store/store';
|
|
42
|
+
{{/if}}
|
|
43
|
+
import { layoutComponentsMap, LayoutComponentNames } from '../../../store/store';
|
|
44
|
+
import { getElementByTagFromComponent } from '../../../utils/goldenLayout.helper';
|
|
32
45
|
import './{{pascalCase tile.title}}Component.css';
|
|
33
46
|
|
|
34
47
|
{{#ifAny tile.metadata.comment tile.metadata.todo}}
|
|
@@ -41,32 +54,94 @@ import './{{pascalCase tile.title}}Component.css';
|
|
|
41
54
|
{{/ifAny}}
|
|
42
55
|
|
|
43
56
|
export const {{pascalCase tile.componentName}}: React.FC = () => {
|
|
44
|
-
{{#if tile.config.permissions.viewRight
|
|
45
|
-
const hasUserPermission = (permissionCode: string): boolean => getViewUpdateRightComponent(getUser(), permissionCode);
|
|
46
|
-
{{else if tile.config.permissions.updateRight
|
|
47
|
-
const hasUserPermission = (permissionCode: string): boolean => getViewUpdateRightComponent(getUser(), permissionCode);
|
|
57
|
+
{{#if tile.config.permissions.viewRight}}
|
|
58
|
+
const hasUserPermission = (permissionCode: string): string | boolean => getViewUpdateRightComponent(getUser(), permissionCode);
|
|
59
|
+
{{else if tile.config.permissions.updateRight}}
|
|
60
|
+
const hasUserPermission = (permissionCode: string): string | boolean => getViewUpdateRightComponent(getUser(), permissionCode);
|
|
61
|
+
{{/if}}
|
|
62
|
+
{{#if tile.config.eventing.publishEventName}}
|
|
63
|
+
const handleRowSelection = (e: any) => {
|
|
64
|
+
const selectedRows = e.api.getSelectedRows();
|
|
65
|
+
if (!selectedRows || !selectedRows.length) {
|
|
66
|
+
actions.eventing.publish{{pascalCase tile.config.eventing.publishEventName}}(null);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const { TIMESTAMP, RECORD_ID, ROW_REF, ...data } = selectedRows[0];
|
|
70
|
+
actions.eventing.publish{{pascalCase tile.config.eventing.publishEventName}}(data);
|
|
71
|
+
};
|
|
48
72
|
{{/if}}
|
|
49
|
-
{{#if tile.config.createFormUiSchema
|
|
73
|
+
{{#if tile.config.createFormUiSchema}}
|
|
50
74
|
const createFormSchema: typeof createFormSchemaTile = createFormSchemaTile;
|
|
51
75
|
{{/if}}
|
|
52
|
-
{{#if tile.config.uischema
|
|
76
|
+
{{#if tile.config.uischema}}
|
|
53
77
|
const uischema: typeof createFormSchemaTile = createFormSchemaTile;
|
|
54
78
|
{{/if}}
|
|
55
|
-
{{#if tile.config.updateFormUiSchema
|
|
79
|
+
{{#if tile.config.updateFormUiSchema}}
|
|
56
80
|
const updateFormSchema: typeof updateFormSchemaTile = updateFormSchemaTile;
|
|
57
81
|
{{/if}}
|
|
58
|
-
{{#if tile.config.
|
|
82
|
+
{{#if tile.config.filterFormUiSchema}}
|
|
83
|
+
const filterFormSchema: typeof filterFormSchemaTile = filterFormSchemaTile;
|
|
84
|
+
{{/if}}
|
|
85
|
+
{{#if tile.config.columns}}
|
|
59
86
|
const columnDefs: typeof columnDefsTile = [...columnDefsTile];
|
|
60
87
|
{{/if}}
|
|
61
|
-
{{#
|
|
62
|
-
const
|
|
88
|
+
{{#ifAny tile.config.gridOptions tile.config.eventing.publishEventName}}
|
|
89
|
+
const gridOptions: { {{#if tile.config.gridOptions}}onRowClicked: GridOptionsConfig.onRowClicked, {{/if}}{{#if tile.config.eventing.publishEventName}}onSelectionChanged: any, rowSelection: 'multiple' | 'single'{{/if}} } = {
|
|
90
|
+
{{#if tile.config.gridOptions}}
|
|
91
|
+
onRowClicked: gridOptionsTile?.onRowClicked,
|
|
92
|
+
{{/if}}
|
|
93
|
+
{{#if tile.config.eventing.publishEventName}}
|
|
94
|
+
onSelectionChanged: handleRowSelection,
|
|
95
|
+
rowSelection: 'single',
|
|
96
|
+
{{/if}}
|
|
97
|
+
}
|
|
98
|
+
{{/ifAny}}
|
|
99
|
+
const datasourceConfig: { isSnapshot?: boolean, pollingInterval?: string, requestAutoSetup?: string, criteria?: string } = {
|
|
100
|
+
{{#if tile.config.snapshot}}
|
|
101
|
+
isSnapshot: {{ tile.config.snapshot }},
|
|
102
|
+
{{/if}}
|
|
103
|
+
{{#if tile.config.reqrep}}
|
|
104
|
+
pollingInterval: '5000',
|
|
105
|
+
requestAutoSetup: 'false',
|
|
106
|
+
{{/if}}
|
|
107
|
+
{{#if tile.config.eventing.listener}}
|
|
108
|
+
criteria: useSelector(selectors.eventing.getCriteriaFor{{pascalCase tile.title}}),
|
|
109
|
+
{{/if}}
|
|
110
|
+
}
|
|
111
|
+
{{#if tile.componentType}}
|
|
112
|
+
{{#ifEquals tile.componentType 'grid'}}
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
const componentElement = layoutComponentsMap.get(LayoutComponentNames.{{constantCase tile.componentName}});
|
|
115
|
+
const componentDatasource = componentElement ? getElementByTagFromComponent(componentElement, 'grid-pro-genesis-datasource') : undefined;
|
|
116
|
+
|
|
117
|
+
if (componentDatasource) {
|
|
118
|
+
{{#if tile.config.eventing.listener}}
|
|
119
|
+
componentDatasource.criteria = datasourceConfig.criteria;
|
|
120
|
+
{{/if}}
|
|
121
|
+
{{#if tile.config.reqrep}}
|
|
122
|
+
componentDatasource.requestAutoSetup = datasourceConfig.requestAutoSetup;
|
|
123
|
+
componentDatasource.pollingInterval = datasourceConfig.pollingInterval;
|
|
124
|
+
{{/if}}
|
|
125
|
+
}
|
|
126
|
+
}, [datasourceConfig]);
|
|
127
|
+
{{/ifEquals}}
|
|
63
128
|
{{/if}}
|
|
64
|
-
{{#if tile.
|
|
65
|
-
|
|
129
|
+
{{#if tile.componentType}}
|
|
130
|
+
{{#ifEquals tile.componentType 'manager'}}
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
const componentElement = layoutComponentsMap.get(LayoutComponentNames.{{constantCase tile.componentName}});
|
|
133
|
+
const componentDatasource = componentElement ? getElementByTagFromComponent(componentElement, 'entity-management') : undefined;
|
|
134
|
+
|
|
135
|
+
if (componentDatasource) {
|
|
136
|
+
componentDatasource.datasourceConfig = datasourceConfig;
|
|
137
|
+
}
|
|
138
|
+
}, [datasourceConfig]);
|
|
139
|
+
{{/ifEquals}}
|
|
66
140
|
{{/if}}
|
|
67
|
-
|
|
141
|
+
|
|
142
|
+
{{#if tile.config.type}}
|
|
68
143
|
const chartConfig: {
|
|
69
|
-
{{#ifEquals tile.config.type 'pie'
|
|
144
|
+
{{#ifEquals tile.config.type 'pie'}}
|
|
70
145
|
radius: number;
|
|
71
146
|
angleField: string;
|
|
72
147
|
colorField: string;
|
|
@@ -75,7 +150,7 @@ export const {{pascalCase tile.componentName}}: React.FC = () => {
|
|
|
75
150
|
yField: string;
|
|
76
151
|
{{/ifEquals}}
|
|
77
152
|
} = {
|
|
78
|
-
{{#ifEquals tile.config.type 'pie'
|
|
153
|
+
{{#ifEquals tile.config.type 'pie'}}
|
|
79
154
|
radius: 0.75,
|
|
80
155
|
angleField: 'value',
|
|
81
156
|
colorField: 'groupBy',
|