@eui/cli 23.0.0-alpha.1 → 23.0.0-alpha.3
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/README.md +36 -3
- package/bin/eui-cli.js +9 -0
- package/bin/scripts/new.js +8 -0
- package/lib/build.js +3 -11
- package/lib/cli.js +84 -7
- package/lib/generators.js +18 -0
- package/lib/skeletons/_angular/base/package.json +2 -2
- package/lib/skeletons/_angular/base/src/app/app.component.spec.ts +5 -5
- package/lib/skeletons/_angular/base/src/app/app.component.ts +2 -2
- package/lib/skeletons/_angular/base/src/app/app.config.ts +2 -2
- package/lib/skeletons/_angular/base/src/app/features/home/home.component.ts +2 -2
- package/lib/skeletons/_angular/base-mobile/angular.json +4 -4
- package/lib/skeletons/_angular/base-mobile/package.json +29 -15
- package/lib/skeletons/_angular/base-mobile/src/app/app-routing.module.ts +5 -5
- package/lib/skeletons/_angular/base-mobile/src/app/app.component.html +41 -19
- package/lib/skeletons/_angular/base-mobile/src/app/app.component.ts +24 -24
- package/lib/skeletons/_angular/base-mobile/src/app/app.config.ts +0 -80
- package/lib/skeletons/_angular/base-mobile/src/app/app.module.ts +2 -0
- package/lib/skeletons/_angular/base-mobile/src/app/core/core.module.ts +2 -17
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/about.component.html +8 -3
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/about.component.ts +5 -1
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/{about-routing.module.ts → about.routes.ts} +2 -13
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/change-log/changelog.component.ts +5 -1
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/help-support/help-support.component.ts +12 -8
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/legal-notice/legal-notice.component.html +1 -1
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/legal-notice/legal-notice.component.ts +6 -4
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/licence-details/licence-details.component.ts +6 -3
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/opensource-licences/opensource-licences.component.ts +5 -1
- package/lib/skeletons/_angular/base-mobile/src/app/features/home/home.component.html +44 -5
- package/lib/skeletons/_angular/base-mobile/src/app/features/home/home.component.ts +69 -0
- package/lib/skeletons/_angular/base-mobile/src/app/features/home/home.routes.ts +6 -0
- package/lib/skeletons/_angular/base-mobile/src/app/features/module1/components/page1/page1.component.html +24 -5
- package/lib/skeletons/_angular/base-mobile/src/app/features/module1/components/page1/page1.component.ts +5 -4
- package/lib/skeletons/_angular/base-mobile/src/app/features/module1/components/page2/page2.component.html +24 -5
- package/lib/skeletons/_angular/base-mobile/src/app/features/module1/components/page2/page2.component.ts +5 -3
- package/lib/skeletons/_angular/base-mobile/src/app/features/module1/module1.component.html +2 -2
- package/lib/skeletons/_angular/base-mobile/src/app/features/module1/module1.component.ts +4 -4
- package/lib/skeletons/_angular/base-mobile/src/app/features/module1/{module1-routing.module.ts → module1.routes.ts} +2 -10
- package/lib/skeletons/_angular/base-mobile/src/app/features/welcome/welcome.component.html +32 -0
- package/lib/skeletons/_angular/base-mobile/src/app/features/welcome/welcome.component.ts +9 -0
- package/lib/skeletons/_angular/base-mobile/src/app/features/welcome/welcome.routes.ts +6 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/docs/sample-pdf-mobile.pdf +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-1024.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-114.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-120.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-128.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-144.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-152.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-16.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-180.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-192.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-32.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-36.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-384.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-48.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-512.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-57.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-60.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-72.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-76.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/app-icon-96.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1125-2436.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1170-2532.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1179-2556.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1242-2208.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1242-2688.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1284-2778.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1290-2796.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1488-2266.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1536-2048.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1620-2160.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1640-2360.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1668-2224.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-1668-2388.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-2048-2732.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-640-1136.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-750-1334.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-landscape-828-1792.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1125-2436.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1170-2532.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1179-2556.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1242-2208.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1242-2688.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1284-2778.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1290-2796.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1488-2266.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1536-2048.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1620-2160.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1640-2360.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1668-2224.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-1668-2388.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-2048-2732.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-640-1136.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-750-1334.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/icons/apple-splash-portrait-828-1792.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/images/app-icon.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/images/image.png +0 -0
- package/lib/skeletons/_angular/base-mobile/src/index.html +1 -1
- package/lib/skeletons/_angular/base-mobile/src/main.ts +5 -0
- package/lib/skeletons/_angular/options/ecl-ec/src/app/app.component.html +57 -34
- package/lib/skeletons/_angular/options/ecl-ec/src/app/app.component.ts +2 -2
- package/lib/skeletons/_angular/options/ecl-ec/src/app/app.config.ts +2 -2
- package/lib/skeletons/_angular/options/ecl-ec/src/app/features/home/home.component.ts +1 -3
- package/lib/skeletons/_angular/options/ecl-eu/src/app/app.component.html +39 -19
- package/lib/skeletons/_angular/options/ecl-eu/src/app/app.component.ts +2 -2
- package/lib/skeletons/_angular/options/ecl-eu/src/app/app.config.ts +2 -2
- package/lib/skeletons/_angular/options/ecl-eu/src/app/features/home/home.component.ts +1 -3
- package/lib/skeletons/_angular/options/ecl-eu/src/app/shared/shared.module.ts +2 -2
- package/lib/skeletons/_angular/options/pnpm/package.json +28 -28
- package/package.json +3 -6
- package/lib/skeletons/_angular/base-mobile/src/app/core/reducers/index.ts +0 -32
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/about.module.ts +0 -30
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/privacy-statement/privacy-statement.component.html +0 -11
- package/lib/skeletons/_angular/base-mobile/src/app/features/about/privacy-statement/privacy-statement.component.ts +0 -103
- package/lib/skeletons/_angular/base-mobile/src/app/features/home/home-routing.module.ts +0 -15
- package/lib/skeletons/_angular/base-mobile/src/app/features/home/home.module.ts +0 -18
- package/lib/skeletons/_angular/base-mobile/src/app/features/module1/module1.module.ts +0 -21
- package/lib/skeletons/_angular/base-mobile/src/app/features/module2/module2-routing.module.ts +0 -16
- package/lib/skeletons/_angular/base-mobile/src/app/features/module2/module2.component.html +0 -11
- package/lib/skeletons/_angular/base-mobile/src/app/features/module2/module2.component.ts +0 -7
- package/lib/skeletons/_angular/base-mobile/src/app/features/module2/module2.module.ts +0 -17
- package/lib/skeletons/_angular/base-mobile/src/assets/docs/pdf-test.pdf +0 -0
- package/lib/skeletons/_angular/base-mobile/src/assets/images/app-icon.svg +0 -10
package/README.md
CHANGED
|
@@ -48,13 +48,40 @@ The CLI will prompt you to configure your application:
|
|
|
48
48
|
|
|
49
49
|
4. **Dependency Installation**: Choose whether to install dependencies automatically
|
|
50
50
|
5. **Package Manager**: Select Yarn 1.x or Pnpm (experimental)
|
|
51
|
+
6. **eui-skills Setup**: Optionally install [eui-skills](https://sdlc.webcloud.ec.europa.eu/csdr/eui-skills.git) after generation
|
|
52
|
+
- **Install all** (`--all`): install all skills to all agents without prompts
|
|
53
|
+
- Or configure individually:
|
|
54
|
+
- **Agent(s)**: target specific agents (e.g. `cursor`, `claude-code`, or `*` for all)
|
|
55
|
+
- **Skill(s)**: specific skill names to install (or `*` for all)
|
|
56
|
+
- **Global**: install at user-level instead of project-level
|
|
57
|
+
- **Skip confirmations**: auto-confirm all skills prompts
|
|
58
|
+
|
|
59
|
+
#### CLI Flags
|
|
60
|
+
|
|
61
|
+
Skip prompts by passing flags directly:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
# Generate with skills setup (interactive sub-prompts)
|
|
65
|
+
eui-cli new --skills
|
|
66
|
+
|
|
67
|
+
# Install all skills to all agents without prompts
|
|
68
|
+
eui-cli new --skills --skillsAll
|
|
69
|
+
|
|
70
|
+
# Target specific agents and skip confirmations
|
|
71
|
+
eui-cli new --skills --skillsAgent "cursor claude-code" --skillsYes
|
|
72
|
+
|
|
73
|
+
# Install a specific skill globally
|
|
74
|
+
eui-cli new --skills --skillsSkill "pr-review" --skillsGlobal
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
> Skills sub-options (`--skillsAgent`, `--skillsSkill`, `--skillsGlobal`, `--skillsYes`, `--skillsAll`) require `--skills` to be set, otherwise the CLI will exit with an error.
|
|
51
78
|
|
|
52
79
|
#### Automated Mode
|
|
53
80
|
|
|
54
|
-
Generate an application without prompts using a configuration
|
|
81
|
+
Generate an application without prompts using a configuration string:
|
|
55
82
|
|
|
56
83
|
```sh
|
|
57
|
-
eui-cli new --config <
|
|
84
|
+
eui-cli new --config <config-string> --targetPath <output-directory>
|
|
58
85
|
```
|
|
59
86
|
|
|
60
87
|
Configuration format:
|
|
@@ -70,6 +97,12 @@ Available options:
|
|
|
70
97
|
- `appOptionsEclTheme`: `ecl-ec`, `ecl-eu`
|
|
71
98
|
- `npmInstall`: `true`, `false`
|
|
72
99
|
- `packageManager`: `yarn`, `pnpm`
|
|
100
|
+
- `skills`: `true`, `false`
|
|
101
|
+
- `skillsAll`: `true`, `false`
|
|
102
|
+
- `skillsAgent`: agent name(s), space-separated or `*`
|
|
103
|
+
- `skillsSkill`: skill name(s), space-separated or `*`
|
|
104
|
+
- `skillsGlobal`: `true`, `false`
|
|
105
|
+
- `skillsYes`: `true`, `false`
|
|
73
106
|
|
|
74
107
|
### Build application
|
|
75
108
|
|
|
@@ -82,7 +115,7 @@ Options:
|
|
|
82
115
|
- `--skipTest` - Skip testing step
|
|
83
116
|
- `--skipCompile` - Skip compilation step
|
|
84
117
|
- `-c, --configuration <config>` - Angular build configuration
|
|
85
|
-
- `--baseHref <href>` - Base href for the application
|
|
118
|
+
- `--baseHref, --base-href <href>` - Base href for the application
|
|
86
119
|
- `--statsJson` - Generate stats.json file
|
|
87
120
|
- `--sourceMap` - Generate source maps
|
|
88
121
|
|
package/bin/eui-cli.js
CHANGED
|
@@ -53,6 +53,15 @@ program
|
|
|
53
53
|
.description('Generate a new eUI application')
|
|
54
54
|
.option('-c, --config <path>', 'Path to configuration file')
|
|
55
55
|
.option('-t, --targetPath <path>', 'Target path for the generated application')
|
|
56
|
+
.option('--skills', 'Setup eui-skills after generation')
|
|
57
|
+
.option('--skillsAgent <agents>', 'Agents to install skills to, requires --skills (e.g. "claude-code cursor", or "*" for all)')
|
|
58
|
+
.option('--skillsSkill <skills>', 'Skill names to install, requires --skills (e.g. "pr-review commit", or "*" for all)')
|
|
59
|
+
.option('--skillsGlobal', 'Install skills globally instead of project-level, requires --skills')
|
|
60
|
+
.option('--skillsYes', 'Skip skills confirmation prompts, requires --skills')
|
|
61
|
+
.option('--skillsAll', 'Install all skills to all agents without prompts, requires --skills')
|
|
62
|
+
.addHelpText('after', `
|
|
63
|
+
Skills sub-options (require --skills):
|
|
64
|
+
--skillsAgent, --skillsSkill, --skillsGlobal, --skillsYes, --skillsAll`)
|
|
56
65
|
.action((options, command) => handleCommand('./scripts/new', options, command));
|
|
57
66
|
|
|
58
67
|
program
|
package/bin/scripts/new.js
CHANGED
|
@@ -11,6 +11,14 @@ module.exports = function run() {
|
|
|
11
11
|
utils.logBigTitle('eUI CLI');
|
|
12
12
|
utils.logAccent(` --- v${config.version} ---\n`);
|
|
13
13
|
|
|
14
|
+
// Validate skills sub-options dependency
|
|
15
|
+
const skillsSubOptions = ['skillsAgent', 'skillsSkill', 'skillsGlobal', 'skillsYes', 'skillsAll'];
|
|
16
|
+
const usedSkillsSubOptions = skillsSubOptions.filter(opt => args[opt] !== undefined && args[opt] !== false);
|
|
17
|
+
if (usedSkillsSubOptions.length > 0 && !args.skills) {
|
|
18
|
+
utils.logError(`The following options require --skills to be set: --${usedSkillsSubOptions.join(', --')}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
14
22
|
// remapping config if passed as argument - automated mode
|
|
15
23
|
let inputConfig = config.parseInputConfig(args.config);
|
|
16
24
|
|
package/lib/build.js
CHANGED
|
@@ -63,17 +63,9 @@ const copyAngular = (targetPath, cliConfig, overwrite = true) => {
|
|
|
63
63
|
utils.copydir(config.angularBaseMobilePath, targetPath, overwrite);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
if (cliConfig.appOptions
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
console.log('Applying option : ' + item);
|
|
70
|
-
utils.copydir(config.optionsPath[item], targetPath, true);
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
if (cliConfig.appOptions.includes('ecl') && cliConfig.appOptionsEclTheme) {
|
|
74
|
-
console.log(`eUI ECL theme selected : ` + cliConfig.appOptionsEclTheme);
|
|
75
|
-
utils.copydir(config.optionsPath[cliConfig.appOptionsEclTheme], targetPath, true);
|
|
76
|
-
}
|
|
66
|
+
if (cliConfig.appOptions === 'ecl') {
|
|
67
|
+
console.log(`eUI ECL theme selected : ` + cliConfig.appOptionsEclTheme);
|
|
68
|
+
utils.copydir(config.optionsPath[cliConfig.appOptionsEclTheme], targetPath, true);
|
|
77
69
|
}
|
|
78
70
|
|
|
79
71
|
if (cliConfig.packageManager === 'pnpm') {
|
package/lib/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ const defaultConfig = {
|
|
|
4
4
|
appName: 'my-app',
|
|
5
5
|
appScope: '@app',
|
|
6
6
|
appType: 'angular',
|
|
7
|
-
appOptions:
|
|
7
|
+
appOptions: 'eui',
|
|
8
8
|
appOptionsEclTheme: 'ecl-ec',
|
|
9
9
|
appFeatures: [],
|
|
10
10
|
groupId: 'ec.europa.digit',
|
|
@@ -12,6 +12,12 @@ const defaultConfig = {
|
|
|
12
12
|
packageManager: 'yarn',
|
|
13
13
|
npmInstall: true,
|
|
14
14
|
appStart: true,
|
|
15
|
+
skills: false,
|
|
16
|
+
skillsAgent: null,
|
|
17
|
+
skillsSkill: null,
|
|
18
|
+
skillsGlobal: false,
|
|
19
|
+
skillsYes: false,
|
|
20
|
+
skillsAll: false,
|
|
15
21
|
};
|
|
16
22
|
|
|
17
23
|
module.exports.start = async (options) => {
|
|
@@ -83,20 +89,21 @@ module.exports.start = async (options) => {
|
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
if (answers.appType !== 'mobile') {
|
|
86
|
-
const appOptionsPrompt = new
|
|
92
|
+
const appOptionsPrompt = new Select({
|
|
87
93
|
name: 'appOptions',
|
|
88
94
|
message: 'Select one or more additional configuration options :',
|
|
89
95
|
choices: [
|
|
90
|
-
{ name: 'eUI
|
|
96
|
+
{ name: 'eUI default app-shell', value: '' },
|
|
97
|
+
{ name: 'eUI ECL app-shell - for ec.europa.eu apps', value: 'ecl' }
|
|
91
98
|
],
|
|
92
|
-
initial:
|
|
93
|
-
result(
|
|
94
|
-
return
|
|
99
|
+
initial: 0,
|
|
100
|
+
result(name) {
|
|
101
|
+
return this.find(name).value;
|
|
95
102
|
}
|
|
96
103
|
});
|
|
97
104
|
answers.appOptions = await appOptionsPrompt.run();
|
|
98
105
|
|
|
99
|
-
if (answers.appOptions
|
|
106
|
+
if (answers.appOptions === 'ecl') {
|
|
100
107
|
const eclThemePrompt = new Select({
|
|
101
108
|
name: 'appOptionsEclTheme',
|
|
102
109
|
message: 'Select which eUI ECL theme flavor you need :',
|
|
@@ -143,6 +150,76 @@ module.exports.start = async (options) => {
|
|
|
143
150
|
answers.packageManager = await packageManagerPrompt.run();
|
|
144
151
|
}
|
|
145
152
|
|
|
153
|
+
const skillsPrompt = new Select({
|
|
154
|
+
name: 'skills',
|
|
155
|
+
message: 'Setup eui-skills for this project :',
|
|
156
|
+
choices: [
|
|
157
|
+
{ name: 'Yes', value: true },
|
|
158
|
+
{ name: 'No', value: false }
|
|
159
|
+
],
|
|
160
|
+
initial: 1,
|
|
161
|
+
result(name) {
|
|
162
|
+
return this.find(name).value;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
answers.skills = await skillsPrompt.run();
|
|
166
|
+
|
|
167
|
+
if (answers.skills === true) {
|
|
168
|
+
const skillsAllPrompt = new Select({
|
|
169
|
+
name: 'skillsAll',
|
|
170
|
+
message: 'Install all skills to all agents without prompts :',
|
|
171
|
+
choices: [
|
|
172
|
+
{ name: 'Yes (--all)', value: true },
|
|
173
|
+
{ name: 'No, let me configure', value: false }
|
|
174
|
+
],
|
|
175
|
+
initial: 0,
|
|
176
|
+
result(name) { return this.find(name).value; }
|
|
177
|
+
});
|
|
178
|
+
answers.skillsAll = await skillsAllPrompt.run();
|
|
179
|
+
|
|
180
|
+
if (!answers.skillsAll) {
|
|
181
|
+
const skillsAgentPrompt = new Input({
|
|
182
|
+
name: 'skillsAgent',
|
|
183
|
+
message: 'Agents to install to (space-separated, * for all, leave empty for default) :',
|
|
184
|
+
initial: ''
|
|
185
|
+
});
|
|
186
|
+
const agentVal = await skillsAgentPrompt.run();
|
|
187
|
+
answers.skillsAgent = agentVal.trim() || null;
|
|
188
|
+
|
|
189
|
+
const skillsSkillPrompt = new Input({
|
|
190
|
+
name: 'skillsSkill',
|
|
191
|
+
message: 'Skill names to install (space-separated, * for all, leave empty for all) :',
|
|
192
|
+
initial: ''
|
|
193
|
+
});
|
|
194
|
+
const skillVal = await skillsSkillPrompt.run();
|
|
195
|
+
answers.skillsSkill = skillVal.trim() || null;
|
|
196
|
+
|
|
197
|
+
const skillsGlobalPrompt = new Select({
|
|
198
|
+
name: 'skillsGlobal',
|
|
199
|
+
message: 'Install skills globally (user-level) :',
|
|
200
|
+
choices: [
|
|
201
|
+
{ name: 'No', value: false },
|
|
202
|
+
{ name: 'Yes', value: true }
|
|
203
|
+
],
|
|
204
|
+
initial: 0,
|
|
205
|
+
result(name) { return this.find(name).value; }
|
|
206
|
+
});
|
|
207
|
+
answers.skillsGlobal = await skillsGlobalPrompt.run();
|
|
208
|
+
|
|
209
|
+
const skillsYesPrompt = new Select({
|
|
210
|
+
name: 'skillsYes',
|
|
211
|
+
message: 'Skip skills confirmation prompts :',
|
|
212
|
+
choices: [
|
|
213
|
+
{ name: 'Yes', value: true },
|
|
214
|
+
{ name: 'No', value: false }
|
|
215
|
+
],
|
|
216
|
+
initial: 0,
|
|
217
|
+
result(name) { return this.find(name).value; }
|
|
218
|
+
});
|
|
219
|
+
answers.skillsYes = await skillsYesPrompt.run();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
146
223
|
const outputConfig = {
|
|
147
224
|
...defaultConfig,
|
|
148
225
|
...answers
|
package/lib/generators.js
CHANGED
|
@@ -39,6 +39,24 @@ const appGenerate = (options) => {
|
|
|
39
39
|
config: cliConfig,
|
|
40
40
|
targetPath: options.targetPath,
|
|
41
41
|
});
|
|
42
|
+
// Setup eui-skills
|
|
43
|
+
// ----------------
|
|
44
|
+
if (cliConfig.skills) {
|
|
45
|
+
utils.logInfo('*****************************************************************');
|
|
46
|
+
utils.logInfo(' Setting up eui-skills...');
|
|
47
|
+
utils.logInfo('*****************************************************************');
|
|
48
|
+
const wd = path.resolve(utils.getAngularPath(options.targetPath, cliConfig.appName, cliConfig.appType, cliConfig.artifactId));
|
|
49
|
+
const skillsArgs = ['add', 'https://sdlc.webcloud.ec.europa.eu/csdr/eui-skills.git'];
|
|
50
|
+
if (cliConfig.skillsAll) {
|
|
51
|
+
skillsArgs.push('--all');
|
|
52
|
+
} else {
|
|
53
|
+
if (cliConfig.skillsAgent) skillsArgs.push('--agent', cliConfig.skillsAgent);
|
|
54
|
+
if (cliConfig.skillsSkill) skillsArgs.push('--skill', cliConfig.skillsSkill);
|
|
55
|
+
if (cliConfig.skillsGlobal) skillsArgs.push('--global');
|
|
56
|
+
if (cliConfig.skillsYes) skillsArgs.push('--yes');
|
|
57
|
+
}
|
|
58
|
+
execSync(`npx skills ${skillsArgs.join(' ')}`, { cwd: wd, stdio: 'inherit' });
|
|
59
|
+
}
|
|
42
60
|
// starting app
|
|
43
61
|
if (!cliConfig.appStart || typeof cliConfig.npmInstall !== 'boolean' || !cliConfig.npmInstall) {
|
|
44
62
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eui-angular-app",
|
|
3
|
-
"version": "23.0.0-alpha.
|
|
3
|
+
"version": "23.0.0-alpha.3",
|
|
4
4
|
"license": "EUPL-1.1",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"ng": "ng",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"private": true,
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@eui/deps-base": "23.0.0-alpha.
|
|
23
|
+
"@eui/deps-base": "23.0.0-alpha.3"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"npm-run-all": "4.1.5",
|
|
@@ -6,10 +6,10 @@ import { routes } from './app.routes';
|
|
|
6
6
|
import { provideHttpClientTesting } from '@angular/common/http/testing';
|
|
7
7
|
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
|
8
8
|
import { AppStarterService } from './app-starter.service';
|
|
9
|
-
import { CONFIG_TOKEN, I18nService, I18nState, UserService} from '@eui/core';
|
|
9
|
+
import { CONFIG_TOKEN, I18nService, I18nState, translateConfig, UserService } from '@eui/core';
|
|
10
10
|
import { EuiAppConfig } from '@eui/core';
|
|
11
11
|
import { Observable, of } from 'rxjs';
|
|
12
|
-
import {
|
|
12
|
+
import { provideTranslateService } from '@ngx-translate/core';
|
|
13
13
|
import { describe, it, beforeEach, expect, vi } from 'vitest';
|
|
14
14
|
|
|
15
15
|
// eslint-disable-next-line
|
|
@@ -26,8 +26,8 @@ describe('AppComponent', () => {
|
|
|
26
26
|
type GetStateReturnType<T> = T extends keyof I18nState ? Observable<I18nState[T]> : Observable<I18nState>;
|
|
27
27
|
|
|
28
28
|
userServiceMock = { init: vi.fn() } as SpyObj<UserService>;
|
|
29
|
-
i18nServiceMock = {
|
|
30
|
-
init: vi.fn(),
|
|
29
|
+
i18nServiceMock = {
|
|
30
|
+
init: vi.fn(),
|
|
31
31
|
getState: vi.fn(<K extends keyof I18nState>(key?: K): GetStateReturnType<K> => {
|
|
32
32
|
if (typeof key === 'string') {
|
|
33
33
|
return of({ activeLang: 'en' }[key]) as GetStateReturnType<K>;
|
|
@@ -41,7 +41,7 @@ describe('AppComponent', () => {
|
|
|
41
41
|
imports: [
|
|
42
42
|
RouterModule.forRoot(routes),
|
|
43
43
|
...EUI_LAYOUT,
|
|
44
|
-
|
|
44
|
+
provideTranslateService(translateConfig),
|
|
45
45
|
],
|
|
46
46
|
providers: [
|
|
47
47
|
provideHttpClient(withInterceptorsFromDi()),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Component } from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { TranslatePipe } from '@ngx-translate/core';
|
|
3
3
|
import { EUI_LANGUAGE_SELECTOR } from '@eui/components/eui-language-selector';
|
|
4
4
|
import { EUI_USER_PROFILE } from '@eui/components/eui-user-profile';
|
|
5
5
|
import { EUI_ICON } from '@eui/components/eui-icon';
|
|
@@ -10,7 +10,7 @@ import { EUI_LAYOUT } from '@eui/components/layout';
|
|
|
10
10
|
selector: 'app-root',
|
|
11
11
|
templateUrl: './app.component.html',
|
|
12
12
|
imports: [
|
|
13
|
-
|
|
13
|
+
TranslatePipe,
|
|
14
14
|
...EUI_LAYOUT,
|
|
15
15
|
...EUI_ICON,
|
|
16
16
|
...EUI_USER_PROFILE,
|
|
@@ -6,7 +6,7 @@ import { Observable } from 'rxjs';
|
|
|
6
6
|
import { routes } from './app.routes';
|
|
7
7
|
import { AppStarterService } from './app-starter.service';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { provideTranslateService } from '@ngx-translate/core';
|
|
10
10
|
|
|
11
11
|
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
|
12
12
|
import {
|
|
@@ -75,8 +75,8 @@ export const appConfig: ApplicationConfig = {
|
|
|
75
75
|
provideHttpClient(withInterceptorsFromDi()),
|
|
76
76
|
importProvidersFrom(
|
|
77
77
|
EuiCoreModule.forRoot(),
|
|
78
|
-
TranslateModule.forRoot(translateConfig)
|
|
79
78
|
),
|
|
79
|
+
provideTranslateService(translateConfig),
|
|
80
80
|
AppStarterService,
|
|
81
81
|
provideRouter(routes),
|
|
82
82
|
provideAnimations(),
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Component, inject } from '@angular/core';
|
|
2
2
|
import { CONFIG_TOKEN, EuiAppConfig } from '@eui/core';
|
|
3
3
|
import { EUI_PAGE } from '@eui/components/eui-page';
|
|
4
|
-
import {
|
|
4
|
+
import { TranslatePipe } from '@ngx-translate/core';
|
|
5
5
|
|
|
6
6
|
@Component({
|
|
7
7
|
templateUrl: './home.component.html',
|
|
8
8
|
imports: [
|
|
9
|
-
|
|
9
|
+
TranslatePipe,
|
|
10
10
|
...EUI_PAGE,
|
|
11
11
|
],
|
|
12
12
|
})
|
|
@@ -118,18 +118,18 @@
|
|
|
118
118
|
"serve": {
|
|
119
119
|
"builder": "@angular-devkit/build-angular:dev-server",
|
|
120
120
|
"options": {
|
|
121
|
-
"
|
|
121
|
+
"buildTarget": "app:build"
|
|
122
122
|
},
|
|
123
123
|
"configurations": {
|
|
124
124
|
"proxy-mock": {
|
|
125
|
-
"
|
|
125
|
+
"buildTarget": "app:build:development",
|
|
126
126
|
"proxyConfig": "proxy-mock.conf.json"
|
|
127
127
|
},
|
|
128
128
|
"production": {
|
|
129
|
-
"
|
|
129
|
+
"buildTarget": "app:build:production"
|
|
130
130
|
},
|
|
131
131
|
"development": {
|
|
132
|
-
"
|
|
132
|
+
"buildTarget": "app:build:development"
|
|
133
133
|
}
|
|
134
134
|
},
|
|
135
135
|
"defaultConfiguration": "development"
|
|
@@ -1,27 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eui-angular-app",
|
|
3
|
-
"version": "23.0.0-alpha.
|
|
3
|
+
"version": "23.0.0-alpha.3",
|
|
4
4
|
"license": "EUPL-1.1",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"ng": "ng",
|
|
7
7
|
"start-mock-server": "nodemon --watch ./mock ./mock/server.js",
|
|
8
|
-
"start-serve": "eui-
|
|
8
|
+
"start-serve": "eui-cli serve-app --configuration=proxy-mock --configEnvTarget=mock",
|
|
9
9
|
"start": "npm-run-all --parallel start-mock-server start-serve",
|
|
10
|
-
"start-proxy": "eui-
|
|
11
|
-
"start-local": "eui-
|
|
12
|
-
"build": "eui-
|
|
13
|
-
"build-dev": "eui-
|
|
14
|
-
"build-prod": "eui-
|
|
15
|
-
"build-prod-skip-test": "eui-
|
|
16
|
-
"build-prod-stats": "eui-
|
|
17
|
-
"app:build": "eui-
|
|
18
|
-
"app:inject-config": "eui-
|
|
19
|
-
"generate-
|
|
10
|
+
"start-proxy": "eui-cli serve-app --configuration=proxy",
|
|
11
|
+
"start-local": "eui-cli serve-app",
|
|
12
|
+
"build": "eui-cli build-app",
|
|
13
|
+
"build-dev": "eui-cli build-app --configuration=development --configEnvTarget=dev",
|
|
14
|
+
"build-prod": "eui-cli build-app --configuration=production-optimized --configEnvTarget=prod",
|
|
15
|
+
"build-prod-skip-test": "eui-cli build-app --configuration=production-optimized --configEnvTarget=prod --skipTest",
|
|
16
|
+
"build-prod-stats": "eui-cli build-app --configuration=production-optimized --configEnvTarget=prod",
|
|
17
|
+
"app:build": "eui-cli build-app",
|
|
18
|
+
"app:inject-config": "eui-cli inject-config-app",
|
|
19
|
+
"generate-sprite": "eui-cli generate-sprite"
|
|
20
20
|
},
|
|
21
21
|
"private": true,
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@eui/deps-base": "
|
|
24
|
-
"@eui/mobile-core": "
|
|
25
|
-
"@eui/mobile-styles": "
|
|
23
|
+
"@eui/deps-base-next": "19.3.17",
|
|
24
|
+
"@eui/mobile-core": "20.0.2",
|
|
25
|
+
"@eui/mobile-styles": "20.0.2"
|
|
26
|
+
},
|
|
27
|
+
"resolutions": {
|
|
28
|
+
"js-yaml": ">=3.13.1",
|
|
29
|
+
"pdfjs-dist": "4.10.38",
|
|
30
|
+
"tar": ">=6.2.1",
|
|
31
|
+
"katex": ">=0.16.10",
|
|
32
|
+
"follow-redirects": ">=1.15.4",
|
|
33
|
+
"word-wrap": ">=1.2.4",
|
|
34
|
+
"postcss": ">=8.4.31",
|
|
35
|
+
"semver": ">=7.5.2",
|
|
36
|
+
"express": "4.21.2",
|
|
37
|
+
"path-to-regexp": "1.9.0",
|
|
38
|
+
"tablesort": "5.6.0",
|
|
39
|
+
"yargs": "17.7.2"
|
|
26
40
|
}
|
|
27
41
|
}
|
|
@@ -2,12 +2,12 @@ import { NgModule } from '@angular/core';
|
|
|
2
2
|
import { RouterModule, Routes } from '@angular/router';
|
|
3
3
|
|
|
4
4
|
const routes: Routes = [
|
|
5
|
-
{ path: '', redirectTo: 'screen/
|
|
5
|
+
{ path: '', redirectTo: 'screen/welcome', pathMatch: 'full' },
|
|
6
6
|
{ path: 'index.jsp', redirectTo: 'screen/home' },
|
|
7
|
-
{ path: 'screen/home', loadChildren: () => import('./features/home/home.
|
|
8
|
-
{ path: 'screen/module1', loadChildren: () => import('./features/module1/module1.
|
|
9
|
-
{ path: 'screen/
|
|
10
|
-
{ path: 'screen/
|
|
7
|
+
{ path: 'screen/home', loadChildren: () => import('./features/home/home.routes').then(m => m.HOME_ROUTES) },
|
|
8
|
+
{ path: 'screen/module1', loadChildren: () => import('./features/module1/module1.routes').then(m => m.MODULE1_ROUTES) },
|
|
9
|
+
{ path: 'screen/about', loadChildren: () => import('./features/about/about.routes').then(m => m.ABOUT_ROUTES) },
|
|
10
|
+
{ path: 'screen/welcome', loadChildren: () => import('./features/welcome/welcome.routes').then(m => m.WELCOME_ROUTES) },
|
|
11
11
|
];
|
|
12
12
|
|
|
13
13
|
@NgModule({
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<euim-sidebar id="mainSidebar">
|
|
3
3
|
<euim-user-profile>
|
|
4
4
|
<euim-user-profile-avatar>
|
|
5
|
-
<euim-avatar color="branding"
|
|
5
|
+
<euim-avatar color="branding">
|
|
6
6
|
<euim-avatar-icon>
|
|
7
7
|
<ion-icon name="person-circle"></ion-icon>
|
|
8
8
|
</euim-avatar-icon>
|
|
@@ -21,26 +21,48 @@
|
|
|
21
21
|
</euim-user-profile-action>
|
|
22
22
|
</euim-user-profile>
|
|
23
23
|
<euim-sidebar-content>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<ion-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<ion-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
@for (item of items; track item) {
|
|
25
|
+
@if (item?.isSection) {
|
|
26
|
+
<ion-item-divider>
|
|
27
|
+
<ion-label>{{item?.label}}</ion-label>
|
|
28
|
+
</ion-item-divider>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@if (!item?.isSection) {
|
|
32
|
+
<ion-item (click)="onItemClick(item)"
|
|
33
|
+
button
|
|
34
|
+
lines="none">
|
|
35
|
+
<ion-icon [name]="item.icon"
|
|
36
|
+
slot="start"></ion-icon>
|
|
37
|
+
<ion-label>
|
|
38
|
+
<div euimLabel>{{item?.label}}</div>
|
|
39
|
+
</ion-label>
|
|
40
|
+
|
|
41
|
+
@if (item.hasBadge) {
|
|
42
|
+
<ion-badge color="light" slot="end">v21</ion-badge>
|
|
43
|
+
}
|
|
44
|
+
</ion-item>
|
|
45
|
+
}
|
|
46
|
+
}
|
|
39
47
|
</euim-sidebar-content>
|
|
40
48
|
<ion-footer>
|
|
41
|
-
<ion-item>
|
|
42
|
-
<
|
|
43
|
-
<
|
|
49
|
+
<ion-item button lines="none" href="screen/about">
|
|
50
|
+
<ion-icon name="phone-portrait-outline" slot="start"></ion-icon>
|
|
51
|
+
<ion-label>
|
|
52
|
+
<div euimLabel>About</div>
|
|
53
|
+
</ion-label>
|
|
54
|
+
</ion-item>
|
|
55
|
+
<ion-item button lines="none" href="screen/welcome">
|
|
56
|
+
<ion-icon name="bulb-outline" slot="start"></ion-icon>
|
|
57
|
+
<ion-label>
|
|
58
|
+
<div euimLabel>Welcome</div>
|
|
59
|
+
</ion-label>
|
|
60
|
+
</ion-item>
|
|
61
|
+
<ion-item button lines="none">
|
|
62
|
+
<ion-icon name="power-outline" slot="start"></ion-icon>
|
|
63
|
+
<ion-label>
|
|
64
|
+
<div euimLabel>Sign Out</div>
|
|
65
|
+
</ion-label>
|
|
44
66
|
</ion-item>
|
|
45
67
|
</ion-footer>
|
|
46
68
|
</euim-sidebar>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Component, OnDestroy } from '@angular/core';
|
|
2
|
-
import { Store } from '@ngrx/store';
|
|
3
2
|
import {
|
|
4
3
|
getUserState,
|
|
5
4
|
UserState,
|
|
@@ -10,6 +9,7 @@ import { NavController } from "@ionic/angular";
|
|
|
10
9
|
@Component({
|
|
11
10
|
selector: 'app-root',
|
|
12
11
|
templateUrl: './app.component.html',
|
|
12
|
+
standalone: false,
|
|
13
13
|
})
|
|
14
14
|
export class AppComponent implements OnDestroy {
|
|
15
15
|
userInfos: UserState;
|
|
@@ -18,43 +18,42 @@ export class AppComponent implements OnDestroy {
|
|
|
18
18
|
// an array to keep all subscriptions and easily unsubscribe
|
|
19
19
|
subs: Subscription[] = [];
|
|
20
20
|
|
|
21
|
-
public
|
|
21
|
+
public items: MenuItem[] = [
|
|
22
22
|
{
|
|
23
23
|
label: 'Home', url: 'screen/home', icon: 'home-outline',
|
|
24
|
-
iconColor: 'dark',
|
|
25
24
|
},
|
|
26
25
|
{
|
|
27
26
|
isSection: true,
|
|
28
|
-
label: '
|
|
27
|
+
label: 'DOCUMENTATION',
|
|
29
28
|
},
|
|
30
|
-
{ label: '
|
|
31
|
-
|
|
32
|
-
{ label: '
|
|
33
|
-
icon: '
|
|
34
|
-
{ label: '
|
|
35
|
-
icon: '
|
|
29
|
+
{ label: 'Design System', url: 'https://eui.ecdevops.eu/eui-showcase-ux-components-21.x/showcase-design-system/home',
|
|
30
|
+
icon: 'color-palette-outline', hasBadge: true, },
|
|
31
|
+
{ label: 'Components', url: 'https://eui.ecdevops.eu/eui-showcase-mobile-20.x/home/components?segment=alphabetical',
|
|
32
|
+
icon: 'cube-outline', },
|
|
33
|
+
{ label: 'Patterns', url: 'https://eui.ecdevops.eu/eui-showcase-mobile-patterns-20.x/home',
|
|
34
|
+
icon: 'library-outline', },
|
|
35
|
+
{ label: 'Applications', url: 'https://eui.ecdevops.eu/eui-showcase-mobile-patterns-20.x/home/patterns?segment=apps',
|
|
36
|
+
icon: 'apps-outline', },
|
|
37
|
+
{ label: 'Plugins & Services', url: 'https://eui.ecdevops.eu/eui-showcase-mobile-20.x/home/plugins-services',
|
|
38
|
+
icon: 'hardware-chip-outline', },
|
|
36
39
|
{
|
|
37
40
|
isSection: true,
|
|
38
|
-
label: '
|
|
41
|
+
label: 'SAMPLE CONTENT',
|
|
39
42
|
},
|
|
40
|
-
{ label: 'Module Page', url: 'screen/
|
|
41
|
-
icon: 'document-outline',
|
|
43
|
+
{ label: 'Module Page', url: 'screen/module1',
|
|
44
|
+
icon: 'document-outline', },
|
|
42
45
|
{
|
|
43
|
-
label: '
|
|
44
|
-
icon: '
|
|
46
|
+
label: 'Page One', url: 'screen/module1/page1',
|
|
47
|
+
icon: 'reader-outline',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
label: 'Page Two', url: 'screen/module1/page2',
|
|
51
|
+
icon: 'reader-outline',
|
|
45
52
|
},
|
|
46
53
|
|
|
47
54
|
];
|
|
48
55
|
|
|
49
|
-
constructor(
|
|
50
|
-
private store: Store<any>,
|
|
51
|
-
private navCtrl:NavController,
|
|
52
|
-
) {
|
|
53
|
-
this.userState = this.store.select(getUserState);
|
|
54
|
-
this.subs.push(this.userState.subscribe((user: UserState) => {
|
|
55
|
-
this.userInfos = { ...user };
|
|
56
|
-
}));
|
|
57
|
-
}
|
|
56
|
+
constructor(private navCtrl:NavController,) {}
|
|
58
57
|
|
|
59
58
|
ngOnDestroy() {
|
|
60
59
|
this.subs.forEach((s: Subscription) => s.unsubscribe());
|
|
@@ -78,4 +77,5 @@ export interface MenuItem {
|
|
|
78
77
|
label: string;
|
|
79
78
|
url?: string;
|
|
80
79
|
isSection?: boolean;
|
|
80
|
+
hasBadge?: boolean;
|
|
81
81
|
}
|