@openmfp/webcomponents 0.6.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.
- package/.github/workflows/pipeline.yaml +41 -0
- package/.storybook/main.ts +34 -0
- package/.storybook/preview.ts +29 -0
- package/.storybook/tsconfig.json +11 -0
- package/AGENTS.md +153 -0
- package/CODEOWNERS +6 -0
- package/CONTRIBUTING.md +95 -0
- package/LICENSE +201 -0
- package/LICENSES/Apache-2.0.txt +73 -0
- package/README.md +91 -0
- package/REUSE.toml +9 -0
- package/angular.json +157 -0
- package/docs/dashboard.md +358 -0
- package/docs/declarative-form.md +178 -0
- package/docs/declarative-table-card.md +235 -0
- package/docs/declarative-table.md +315 -0
- package/eslint.config.js +41 -0
- package/package.json +73 -0
- package/projects/ngx/cards/favorites/favorites.component.html +12 -0
- package/projects/ngx/cards/favorites/favorites.component.scss +50 -0
- package/projects/ngx/cards/favorites/favorites.component.ts +19 -0
- package/projects/ngx/cards/public-api.ts +4 -0
- package/projects/ngx/cards/service-status/service-status-card.component.html +15 -0
- package/projects/ngx/cards/service-status/service-status-card.component.scss +87 -0
- package/projects/ngx/cards/service-status/service-status-card.component.ts +36 -0
- package/projects/ngx/cards/stories/visited-service-card.stories.ts +149 -0
- package/projects/ngx/cards/visited-service-card/visited-service-card.component.html +17 -0
- package/projects/ngx/cards/visited-service-card/visited-service-card.component.scss +34 -0
- package/projects/ngx/cards/visited-service-card/visited-service-card.component.ts +22 -0
- package/projects/ngx/cards/whats-new/whats-new.component.html +10 -0
- package/projects/ngx/cards/whats-new/whats-new.component.scss +25 -0
- package/projects/ngx/cards/whats-new/whats-new.component.ts +46 -0
- package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.html +28 -0
- package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.scss +44 -0
- package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.spec.ts +85 -0
- package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.ts +58 -0
- package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.html +29 -0
- package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.scss +63 -0
- package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.spec.ts +255 -0
- package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.ts +75 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/dashboard-card-registry.spec.ts +76 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/dashboard-card-registry.ts +109 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/index.ts +4 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-angular-card.spec.ts +141 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-angular-card.ts +44 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-sap-card.spec.ts +142 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-sap-card.ts +52 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-wc-card.spec.ts +107 -0
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-wc-card.ts +22 -0
- package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.html +134 -0
- package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.scss +88 -0
- package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.spec.ts +354 -0
- package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.ts +238 -0
- package/projects/ngx/declarative-ui/dashboard/dashboard/index.ts +1 -0
- package/projects/ngx/declarative-ui/dashboard/index.ts +5 -0
- package/projects/ngx/declarative-ui/dashboard/models/constants.ts +2 -0
- package/projects/ngx/declarative-ui/dashboard/models/dashboard.model.ts +50 -0
- package/projects/ngx/declarative-ui/dashboard/models/index.ts +1 -0
- package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.html +28 -0
- package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.scss +85 -0
- package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.spec.ts +104 -0
- package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.ts +23 -0
- package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.html +62 -0
- package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.scss +12 -0
- package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.spec.ts +301 -0
- package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.ts +166 -0
- package/projects/ngx/declarative-ui/form/declarative-form/index.ts +1 -0
- package/projects/ngx/declarative-ui/form/index.ts +2 -0
- package/projects/ngx/declarative-ui/form/models/form-field-definition.ts +15 -0
- package/projects/ngx/declarative-ui/form/models/index.ts +1 -0
- package/projects/ngx/declarative-ui/form/utils/set-property-by-path.ts +30 -0
- package/projects/ngx/declarative-ui/models/index.ts +2 -0
- package/projects/ngx/declarative-ui/models/resource.ts +5 -0
- package/projects/ngx/declarative-ui/models/ui-definition.ts +95 -0
- package/projects/ngx/declarative-ui/public-api.ts +4 -0
- package/projects/ngx/declarative-ui/stories/add-card-dialog.stories.ts +91 -0
- package/projects/ngx/declarative-ui/stories/background-lightblue.png +0 -0
- package/projects/ngx/declarative-ui/stories/dashboard.cards.ts +107 -0
- package/projects/ngx/declarative-ui/stories/dashboard.stories.ts +296 -0
- package/projects/ngx/declarative-ui/stories/declarative-form.stories.ts +149 -0
- package/projects/ngx/declarative-ui/stories/declarative-table-card.stories.ts +358 -0
- package/projects/ngx/declarative-ui/stories/declarative-table.stories.ts +363 -0
- package/projects/ngx/declarative-ui/stories/pods-table.config.ts +188 -0
- package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.html +138 -0
- package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.scss +21 -0
- package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.spec.ts +345 -0
- package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.ts +61 -0
- package/projects/ngx/declarative-ui/table/declarative-table/index.ts +1 -0
- package/projects/ngx/declarative-ui/table/index.ts +2 -0
- package/projects/ngx/declarative-ui/table/models/index.ts +14 -0
- package/projects/ngx/declarative-ui/table/models/table.model.ts +17 -0
- package/projects/ngx/declarative-ui/table/utils/cssRules.engine.spec.ts +146 -0
- package/projects/ngx/declarative-ui/table/utils/cssRules.engine.ts +69 -0
- package/projects/ngx/declarative-ui/table/utils/field-definition.utils.spec.ts +70 -0
- package/projects/ngx/declarative-ui/table/utils/field-definition.utils.ts +13 -0
- package/projects/ngx/declarative-ui/table/utils/proccess-fields.spec.ts +511 -0
- package/projects/ngx/declarative-ui/table/utils/proccess-fields.ts +71 -0
- package/projects/ngx/declarative-ui/table/utils/resource-field-by-path.spec.ts +372 -0
- package/projects/ngx/declarative-ui/table/utils/resource-field-by-path.ts +98 -0
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-cell.constants.ts +5 -0
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.html +1 -0
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.scss +0 -0
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.spec.ts +119 -0
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.ts +35 -0
- package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.html +7 -0
- package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.scss +0 -0
- package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.spec.ts +114 -0
- package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.ts +19 -0
- package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.html +7 -0
- package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.scss +10 -0
- package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.spec.ts +188 -0
- package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.ts +16 -0
- package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.html +59 -0
- package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.scss +33 -0
- package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.spec.ts +316 -0
- package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.ts +115 -0
- package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.html +156 -0
- package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.scss +123 -0
- package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.spec.ts +786 -0
- package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.ts +286 -0
- package/projects/ngx/declarative-ui/table-card/index.ts +2 -0
- package/projects/ngx/declarative-ui/table-card/models/configs.ts +46 -0
- package/projects/ngx/declarative-ui/tsconfig.lib.json +11 -0
- package/projects/ngx/declarative-ui/tsconfig.lib.prod.json +9 -0
- package/projects/ngx/declarative-ui/tsconfig.spec.json +9 -0
- package/projects/ngx/ng-package.json +8 -0
- package/projects/ngx/package.json +22 -0
- package/projects/ngx/public-api.ts +2 -0
- package/projects/ngx/tsconfig.lib.json +11 -0
- package/projects/ngx/tsconfig.lib.prod.json +9 -0
- package/projects/webcomponents/main.ts +92 -0
- package/projects/webcomponents/tsconfig.app.json +9 -0
- package/projects/webcomponents-dashboard/main.ts +15 -0
- package/projects/webcomponents-dashboard/tsconfig.app.json +9 -0
- package/renovate.json +6 -0
- package/scripts/bundle-wc.mjs +79 -0
- package/tsconfig.json +37 -0
- package/tsconfig.spec.json +8 -0
- package/tsconfig.storybook.json +16 -0
- package/vitest.config.ts +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# OpenMFP Web Components Library
|
|
2
|
+
|
|
3
|
+
A modern Angular 21 web components library featuring declarative UI components built with the latest signal-based APIs.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- **Angular 21** - Built with the latest Angular features and signal-based APIs
|
|
10
|
+
- **Web Components Ready** - Exportable as native web components via Angular Elements
|
|
11
|
+
- **Declarative UI** - Intuitive generic ui component
|
|
12
|
+
- **Vitest Testing** - Fast, modern testing framework
|
|
13
|
+
- **TypeScript** - Full type safety with strict mode
|
|
14
|
+
- **Tree-Shakeable** - Optimized bundle size with ES modules
|
|
15
|
+
|
|
16
|
+
## 🚀 Getting Started
|
|
17
|
+
|
|
18
|
+
### Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Install dependencies
|
|
22
|
+
npm install
|
|
23
|
+
|
|
24
|
+
# Build the library
|
|
25
|
+
npm run build
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Build Commands
|
|
29
|
+
|
|
30
|
+
Run `npm run build` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Build once
|
|
34
|
+
npm run build
|
|
35
|
+
|
|
36
|
+
# Build in watch mode (for development)
|
|
37
|
+
npm run build:watch
|
|
38
|
+
|
|
39
|
+
# Build and publish to yalc (for local testing)
|
|
40
|
+
npm run build:watch:yalc
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Testing
|
|
44
|
+
|
|
45
|
+
Run `npm run test` to execute unit tests with Vitest.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Run tests once
|
|
49
|
+
npm test
|
|
50
|
+
|
|
51
|
+
# Run tests in watch mode
|
|
52
|
+
npm run test:watch
|
|
53
|
+
|
|
54
|
+
# Generate coverage report
|
|
55
|
+
npm run test:cov
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Code Quality
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Lint code
|
|
62
|
+
npm run lint
|
|
63
|
+
|
|
64
|
+
# Fix linting issues
|
|
65
|
+
npm run lint:fix
|
|
66
|
+
|
|
67
|
+
# Format code with Prettier
|
|
68
|
+
npm run format
|
|
69
|
+
|
|
70
|
+
# Check code formatting
|
|
71
|
+
npm run check-format
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Web Components Support
|
|
75
|
+
|
|
76
|
+
Components can be exported as native web components using Angular Elements, making them framework-agnostic.
|
|
77
|
+
|
|
78
|
+
## Components
|
|
79
|
+
|
|
80
|
+
| Angular tag | Web Component tag | Documentation |
|
|
81
|
+
|---|---|------------------------------------------------------------------|
|
|
82
|
+
| `<mfp-declarative-table>` | `<mfp-wc-declarative-table>` | [docs/declarative-table.md](docs/declarative-table.md) |
|
|
83
|
+
| `<mfp-declarative-form>` | `<mfp-wc-declarative-form>` | [docs/declarative-form.md](docs/declarative-form.md) |
|
|
84
|
+
| `<mfp-declarative-table-card>` | `<mfp-wc-declarative-table-card>` | [docs/declarative-table-card.md](docs/declarative-table-card.md) |
|
|
85
|
+
| `<mfp-dashboard>` | `<mfp-wc-dashboard>` | [docs/dashboard.md](docs/declarative-dashboard.md) |
|
|
86
|
+
|
|
87
|
+
## NeoNephos Foundation
|
|
88
|
+
|
|
89
|
+
This project is part of the [NeoNephos Foundation](https://neonephos.org), a Linux Foundation Europe initiative.
|
|
90
|
+
|
|
91
|
+
<p align="center"><img alt="Bundesministerium für Wirtschaft und Energie (BMWE)-EU funding logo" src="https://apeirora.eu/assets/img/BMWK-EU.png" width="400"/></p>
|
package/REUSE.toml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
SPDX-PackageName = "webcomponents"
|
|
3
|
+
SPDX-PackageDownloadLocation = "https://github.com/openmfp/webcomponents"
|
|
4
|
+
|
|
5
|
+
[[annotations]]
|
|
6
|
+
path = "**"
|
|
7
|
+
precedence = "aggregate"
|
|
8
|
+
SPDX-FileCopyrightText = "2026 openmfp contributors"
|
|
9
|
+
SPDX-License-Identifier = "Apache-2.0"
|
package/angular.json
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"newProjectRoot": "projects",
|
|
5
|
+
"projects": {
|
|
6
|
+
"ngx": {
|
|
7
|
+
"projectType": "library",
|
|
8
|
+
"schematics": {
|
|
9
|
+
"@schematics/angular:component": {
|
|
10
|
+
"style": "scss",
|
|
11
|
+
"path": "projects/ngx"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"root": "projects/ngx",
|
|
15
|
+
"sourceRoot": "projects/ngx",
|
|
16
|
+
"prefix": "mfp",
|
|
17
|
+
"architect": {
|
|
18
|
+
"build": {
|
|
19
|
+
"builder": "@angular/build:ng-packagr",
|
|
20
|
+
"options": {
|
|
21
|
+
"project": "projects/ngx/ng-package.json"
|
|
22
|
+
},
|
|
23
|
+
"configurations": {
|
|
24
|
+
"production": {
|
|
25
|
+
"tsConfig": "projects/ngx/tsconfig.lib.prod.json"
|
|
26
|
+
},
|
|
27
|
+
"development": {
|
|
28
|
+
"tsConfig": "projects/ngx/tsconfig.lib.json"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"defaultConfiguration": "production"
|
|
32
|
+
},
|
|
33
|
+
"lint": {
|
|
34
|
+
"builder": "@angular-eslint/builder:lint",
|
|
35
|
+
"options": {
|
|
36
|
+
"lintFilePatterns": [
|
|
37
|
+
"projects/ngx/**/*.ts",
|
|
38
|
+
"projects/ngx/**/*.html"
|
|
39
|
+
],
|
|
40
|
+
"eslintConfig": "eslint.config.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"test": {
|
|
44
|
+
"builder": "@angular/build:unit-test",
|
|
45
|
+
"options": {
|
|
46
|
+
"runnerConfig": "vitest.config.ts",
|
|
47
|
+
"tsConfig": "./tsconfig.spec.json"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"storybook": {
|
|
51
|
+
"builder": "@storybook/angular:start-storybook",
|
|
52
|
+
"options": {
|
|
53
|
+
"configDir": ".storybook",
|
|
54
|
+
"browserTarget": "ngx:build",
|
|
55
|
+
"tsConfig": "tsconfig.storybook.json",
|
|
56
|
+
"styles": [
|
|
57
|
+
"node_modules/@sap-theming/theming-base-content/content/Base/baseLib/sap_horizon/css_variables.css",
|
|
58
|
+
"node_modules/fundamental-styles/dist/theming/sap_horizon.css"
|
|
59
|
+
],
|
|
60
|
+
"port": 6006
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"build-storybook": {
|
|
64
|
+
"builder": "@storybook/angular:build-storybook",
|
|
65
|
+
"options": {
|
|
66
|
+
"configDir": ".storybook",
|
|
67
|
+
"browserTarget": "ngx:build",
|
|
68
|
+
"tsConfig": "tsconfig.storybook.json",
|
|
69
|
+
"styles": [
|
|
70
|
+
"node_modules/@sap-theming/theming-base-content/content/Base/baseLib/sap_horizon/css_variables.css",
|
|
71
|
+
"node_modules/fundamental-styles/dist/theming/sap_horizon.css"
|
|
72
|
+
],
|
|
73
|
+
"outputDir": "dist/storybook"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"webcomponents": {
|
|
79
|
+
"projectType": "application",
|
|
80
|
+
"root": "projects/webcomponents",
|
|
81
|
+
"sourceRoot": "projects/webcomponents",
|
|
82
|
+
"architect": {
|
|
83
|
+
"build": {
|
|
84
|
+
"builder": "@angular/build:application",
|
|
85
|
+
"options": {
|
|
86
|
+
"outputPath": {
|
|
87
|
+
"base": "dist/webcomponents",
|
|
88
|
+
"browser": ""
|
|
89
|
+
},
|
|
90
|
+
"browser": "projects/webcomponents/main.ts",
|
|
91
|
+
"tsConfig": "projects/webcomponents/tsconfig.app.json",
|
|
92
|
+
"index": false,
|
|
93
|
+
"outputHashing": "none",
|
|
94
|
+
"inlineStyleLanguage": "scss"
|
|
95
|
+
},
|
|
96
|
+
"configurations": {
|
|
97
|
+
"production": {
|
|
98
|
+
"optimization": true
|
|
99
|
+
},
|
|
100
|
+
"development": {
|
|
101
|
+
"optimization": false,
|
|
102
|
+
"sourceMap": true
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"defaultConfiguration": "production"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"webcomponents-dashboard": {
|
|
110
|
+
"projectType": "application",
|
|
111
|
+
"root": "projects/webcomponents-dashboard",
|
|
112
|
+
"sourceRoot": "projects/webcomponents-dashboard",
|
|
113
|
+
"architect": {
|
|
114
|
+
"build": {
|
|
115
|
+
"builder": "@angular/build:application",
|
|
116
|
+
"options": {
|
|
117
|
+
"outputPath": {
|
|
118
|
+
"base": "dist/webcomponents-dashboard",
|
|
119
|
+
"browser": ""
|
|
120
|
+
},
|
|
121
|
+
"browser": "projects/webcomponents-dashboard/main.ts",
|
|
122
|
+
"tsConfig": "projects/webcomponents-dashboard/tsconfig.app.json",
|
|
123
|
+
"index": false,
|
|
124
|
+
"outputHashing": "none",
|
|
125
|
+
"inlineStyleLanguage": "scss"
|
|
126
|
+
},
|
|
127
|
+
"configurations": {
|
|
128
|
+
"production": {
|
|
129
|
+
"optimization": true
|
|
130
|
+
},
|
|
131
|
+
"development": {
|
|
132
|
+
"optimization": false,
|
|
133
|
+
"sourceMap": true
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"defaultConfiguration": "production"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"cli": {
|
|
142
|
+
"analytics": false,
|
|
143
|
+
"schematicCollections": ["angular-eslint"]
|
|
144
|
+
},
|
|
145
|
+
"schematics": {
|
|
146
|
+
"@schematics/angular:component": {
|
|
147
|
+
"type": "component",
|
|
148
|
+
"addTypeToClassName": false
|
|
149
|
+
},
|
|
150
|
+
"@schematics/angular:directive": {
|
|
151
|
+
"type": "directive"
|
|
152
|
+
},
|
|
153
|
+
"@schematics/angular:service": {
|
|
154
|
+
"type": "service"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
# Dashboard
|
|
2
|
+
|
|
3
|
+
An Angular dashboard layout component that combines editable sections with draggable loose cards. Cards can render either registered Angular components or pre-registered web components through the same `component` field.
|
|
4
|
+
|
|
5
|
+
## Tags
|
|
6
|
+
|
|
7
|
+
| Usage | Tag |
|
|
8
|
+
| ----------------- | -------------------- |
|
|
9
|
+
| Angular component | `<mfp-dashboard>` |
|
|
10
|
+
| Web component | `<mfp-wc-dashboard>` |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Usage as a web component
|
|
15
|
+
|
|
16
|
+
The dashboard is shipped as a **dedicated standalone bundle** `mfp-wc-dashboard.js`, separate from the main `mfp-webcomponents.js`. Load it independently — it does not depend on the main bundle.
|
|
17
|
+
|
|
18
|
+
```html
|
|
19
|
+
<script type="module" src="/mfp-wc-dashboard.js"></script>
|
|
20
|
+
|
|
21
|
+
<mfp-wc-dashboard id="dashboard"></mfp-wc-dashboard>
|
|
22
|
+
|
|
23
|
+
<script type="module">
|
|
24
|
+
const el = document.getElementById('dashboard');
|
|
25
|
+
el.config = { title: 'Platform Overview' };
|
|
26
|
+
el.sections = [{ id: 'runtime', title: 'Runtime', w: 12 }];
|
|
27
|
+
el.cards = [
|
|
28
|
+
{
|
|
29
|
+
id: 'pods-card',
|
|
30
|
+
component: 'mfp-wc-declarative-table-card',
|
|
31
|
+
w: 12,
|
|
32
|
+
h: 5,
|
|
33
|
+
componentInputs: { header: 'Pods' },
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
</script>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
All inputs (`config`, `sections`, `cards`, `availableCards`) and the `saved` event work the same as the Angular component.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Usage as an Angular component
|
|
44
|
+
|
|
45
|
+
Register Angular card components once before rendering the dashboard. The dashboard reads each Angular component selector and uses that selector string from `CardConfig.component`.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import {
|
|
49
|
+
CardConfig,
|
|
50
|
+
Dashboard,
|
|
51
|
+
DashboardConfig,
|
|
52
|
+
SectionConfig,
|
|
53
|
+
VisitedServiceCard,
|
|
54
|
+
} from '@openmfp/webcomponents';
|
|
55
|
+
|
|
56
|
+
Dashboard.registerAngularComponents([VisitedServiceCard]);
|
|
57
|
+
|
|
58
|
+
@Component({
|
|
59
|
+
imports: [Dashboard],
|
|
60
|
+
template: `
|
|
61
|
+
<mfp-dashboard
|
|
62
|
+
[config]="config"
|
|
63
|
+
[sections]="sections"
|
|
64
|
+
[cards]="cards"
|
|
65
|
+
[availableCards]="availableCards"
|
|
66
|
+
(saved)="onSaved($event)"
|
|
67
|
+
/>
|
|
68
|
+
`,
|
|
69
|
+
})
|
|
70
|
+
export class DashboardPage {
|
|
71
|
+
config: DashboardConfig = {
|
|
72
|
+
title: 'Platform Overview',
|
|
73
|
+
description: 'Service health and team activity',
|
|
74
|
+
backgroundImageUrl: '/assets/dashboard-bg.png',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
sections: SectionConfig[] = [
|
|
78
|
+
{ id: 'favorites', title: 'Favorites', editable: false },
|
|
79
|
+
{ id: 'runtime', title: 'Runtime', w: 12 },
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
cards: CardConfig[] = [
|
|
83
|
+
{
|
|
84
|
+
id: 'recent-service-card',
|
|
85
|
+
sectionId: 'favorites',
|
|
86
|
+
component: 'mfp-visited-service-card',
|
|
87
|
+
type: 'angular',
|
|
88
|
+
w: 6,
|
|
89
|
+
h: 2,
|
|
90
|
+
componentInputs: {
|
|
91
|
+
serviceType: 'SAP HANA Cloud',
|
|
92
|
+
serviceName: 'orders-db',
|
|
93
|
+
serviceDescription: 'Production / europe',
|
|
94
|
+
serviceIcon: 'database',
|
|
95
|
+
path: '/hana/orders-db',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 'pods-card',
|
|
100
|
+
component: 'mfp-wc-declarative-table-card',
|
|
101
|
+
type: 'wc',
|
|
102
|
+
w: 12,
|
|
103
|
+
h: 5,
|
|
104
|
+
x: 0,
|
|
105
|
+
y: 0,
|
|
106
|
+
componentInputs: {
|
|
107
|
+
header: 'Pods',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
availableCards: CardConfig[] = [
|
|
113
|
+
{
|
|
114
|
+
id: 'service-status-template',
|
|
115
|
+
component: 'mfp-wc-service-status-card',
|
|
116
|
+
type: 'wc',
|
|
117
|
+
label: 'Service Status',
|
|
118
|
+
w: 4,
|
|
119
|
+
h: 2,
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
onSaved(event: { sections: SectionConfig[]; cards: CardConfig[] }) {
|
|
124
|
+
console.log(event.cards);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`componentInputs` behaviour depends on `type`:
|
|
130
|
+
|
|
131
|
+
- For `type: 'angular'`, values are applied with Angular `setInput(...)`.
|
|
132
|
+
- For Angular input aliases, both the class property name and the public alias are accepted.
|
|
133
|
+
- Unknown Angular input names are ignored and logged as a development warning.
|
|
134
|
+
- For `type: 'wc'` (or when `type` is omitted), values are set as DOM properties.
|
|
135
|
+
- For `type: 'sap-ui'`, values are forwarded as `settings` to `ComponentContainer`.
|
|
136
|
+
|
|
137
|
+
Example with an aliased Angular input:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
@Component({
|
|
141
|
+
selector: 'app-card',
|
|
142
|
+
template: '{{ title() }}',
|
|
143
|
+
})
|
|
144
|
+
export class AppCard {
|
|
145
|
+
title = input('', { alias: 'cardTitle' });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
Dashboard.registerAngularComponents([AppCard]);
|
|
149
|
+
|
|
150
|
+
const card: CardConfig = {
|
|
151
|
+
id: 'app-card',
|
|
152
|
+
component: 'app-card',
|
|
153
|
+
type: 'angular',
|
|
154
|
+
componentInputs: {
|
|
155
|
+
// Class property name works.
|
|
156
|
+
title: 'Runtime',
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const sameCardUsingAlias: CardConfig = {
|
|
161
|
+
id: 'app-card-alias',
|
|
162
|
+
component: 'app-card',
|
|
163
|
+
type: 'angular',
|
|
164
|
+
componentInputs: {
|
|
165
|
+
// Public alias works too.
|
|
166
|
+
cardTitle: 'Runtime',
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Usage with web components
|
|
172
|
+
|
|
173
|
+
Custom elements are still supported. They must be registered in the browser before the dashboard renders them.
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const cards: CardConfig[] = [
|
|
177
|
+
{
|
|
178
|
+
id: 'pods-card',
|
|
179
|
+
component: 'mfp-wc-declarative-table-card',
|
|
180
|
+
componentInputs: {
|
|
181
|
+
header: 'Pods',
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
];
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## API
|
|
190
|
+
|
|
191
|
+
### Inputs
|
|
192
|
+
|
|
193
|
+
| Input | Type | Required | Default | Description |
|
|
194
|
+
| ---------------- | ----------------- | -------- | ------- | ----------------------------------------------------------- |
|
|
195
|
+
| `config` | `DashboardConfig` | yes | — | Header text and optional background image |
|
|
196
|
+
| `sections` | `SectionConfig[]` | no | `[]` | Named dashboard sections rendered above the loose-card grid |
|
|
197
|
+
| `cards` | `CardConfig[]` | no | `[]` | All cards shown in sections or in the grid |
|
|
198
|
+
| `availableCards` | `CardConfig[]` | no | `[]` | Card templates that can be added in edit mode |
|
|
199
|
+
|
|
200
|
+
### Outputs
|
|
201
|
+
|
|
202
|
+
| Output | Payload | Description |
|
|
203
|
+
| ------- | ---------------------------------------------------- | ------------------------------- |
|
|
204
|
+
| `saved` | `{ sections: SectionConfig[]; cards: CardConfig[] }` | Emits when the user saves edits |
|
|
205
|
+
|
|
206
|
+
### Static methods
|
|
207
|
+
|
|
208
|
+
| Method | Description |
|
|
209
|
+
| ----------------------------- | --------------------------------------------------------------------------- |
|
|
210
|
+
| `registerAngularComponents()` | Registers standalone Angular card components by their element selector name |
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Configuration types
|
|
215
|
+
|
|
216
|
+
### `DashboardConfig`
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
interface DashboardConfig {
|
|
220
|
+
title: string;
|
|
221
|
+
description?: string;
|
|
222
|
+
backgroundImageUrl?: string;
|
|
223
|
+
buttonsSettings?: DashboardButtonsSettings;
|
|
224
|
+
customActions?: ButtonSettings[];
|
|
225
|
+
editable?: boolean;
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### `DashboardButtonSettings`
|
|
230
|
+
|
|
231
|
+
Controls the appearance of the two built-in toolbar buttons. Both fields accept a `Partial<ButtonSettings>` that is **merged on top of the defaults** — any property you omit keeps its default value.
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
interface DashboardButtonsSettings {
|
|
235
|
+
editViewButton?: Partial<ButtonSettings>;
|
|
236
|
+
addCardButton?: Partial<ButtonSettings>;
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
| Button | Default `icon` | Default `design` | Default `tooltip` | Default `text` |
|
|
241
|
+
| ---------------- | ----------------- | ---------------- | ----------------- | --------------------- |
|
|
242
|
+
| `editViewButton` | `action-settings` | `Transparent` | `Edit View` | _(empty — icon only)_ |
|
|
243
|
+
| `addCardButton` | _(none)_ | `Default` | _(none)_ | `+ Add Card` |
|
|
244
|
+
|
|
245
|
+
**Example — text-only buttons without icons:**
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
const config: DashboardConfig = {
|
|
249
|
+
title: 'Platform Overview',
|
|
250
|
+
editable: true,
|
|
251
|
+
buttonsSettings: {
|
|
252
|
+
editViewButton: {
|
|
253
|
+
text: 'Edit View',
|
|
254
|
+
icon: '',
|
|
255
|
+
design: 'Default',
|
|
256
|
+
tooltip: '',
|
|
257
|
+
},
|
|
258
|
+
addCardButton: {
|
|
259
|
+
text: 'Add Card',
|
|
260
|
+
icon: '',
|
|
261
|
+
design: 'Emphasized',
|
|
262
|
+
tooltip: '',
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
The compact toolbar (viewport width < 726 px) collapses all actions into a burger menu. The Edit View menu item always uses the configured `icon` and falls back to the text `'Edit View'` when no `text` override is set.
|
|
269
|
+
|
|
270
|
+
### `ButtonSettings`
|
|
271
|
+
|
|
272
|
+
Used both for `customActions` entries and as the override type for `DashboardButtonSettings`.
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
interface ButtonSettings {
|
|
276
|
+
text?: string;
|
|
277
|
+
icon?: string;
|
|
278
|
+
endIcon?: string;
|
|
279
|
+
design?:
|
|
280
|
+
| 'Default'
|
|
281
|
+
| 'Positive'
|
|
282
|
+
| 'Negative'
|
|
283
|
+
| 'Transparent'
|
|
284
|
+
| 'Emphasized'
|
|
285
|
+
| 'Attention';
|
|
286
|
+
tooltip?: string;
|
|
287
|
+
action: 'openInModal' | 'navigate' | 'edit' | 'delete' | string;
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### `SectionConfig`
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
interface SectionConfig {
|
|
295
|
+
id: string;
|
|
296
|
+
w?: number;
|
|
297
|
+
title?: string;
|
|
298
|
+
editable?: boolean;
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### `CardConfig`
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
interface CardConfig {
|
|
306
|
+
id: string;
|
|
307
|
+
w?: number; // expressed in number of columns up to 12
|
|
308
|
+
h?: number; // expressed in hypothetical number of rows, where a row is 10px high, so the value of 27 translates to 270px
|
|
309
|
+
x?: number;
|
|
310
|
+
y?: number;
|
|
311
|
+
maxH?: number;
|
|
312
|
+
maxW?: number;
|
|
313
|
+
minH?: number;
|
|
314
|
+
minW?: number;
|
|
315
|
+
sectionId?: string;
|
|
316
|
+
component: string;
|
|
317
|
+
type?: 'wc' | 'angular' | 'sap-ui';
|
|
318
|
+
componentInputs?: Record<string, unknown>;
|
|
319
|
+
label?: string;
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
For sections, `w` controls the column span while height is determined by the section content.
|
|
324
|
+
For cards, `w` and `h` control the initial rendered grid span. `x` and `y` persist the loose-card position reported by drag and drop when edit mode is saved. `minH`/`minW` and `maxH`/`maxW` set hard resize bounds enforced by the grid — the user cannot drag a card below the minimum or above the maximum size in edit mode.
|
|
325
|
+
|
|
326
|
+
`component` and `type` work together to determine how the card is rendered:
|
|
327
|
+
|
|
328
|
+
| `type` | Render strategy |
|
|
329
|
+
| ----------- | ---------------------------------------------------------------------- |
|
|
330
|
+
| `'wc'` | Creates a custom element tag; sets `componentInputs` as DOM properties |
|
|
331
|
+
| omitted | Same as `'wc'` |
|
|
332
|
+
| `'angular'` | Looks up the Angular registry; warns and renders nothing if not found |
|
|
333
|
+
| `'sap-ui'` | Mounts via `window.sap.ui.require` + `ComponentContainer` |
|
|
334
|
+
|
|
335
|
+
Angular registry support intentionally accepts only single element selectors such as `mfp-visited-service-card`. Attribute selectors like `[my-card]`, class selectors like `.my-card`, and comma-separated selectors are rejected because dashboard card configs use `component` as a tag-like persisted key.
|
|
336
|
+
|
|
337
|
+
## Usage with SAP UI5 components
|
|
338
|
+
|
|
339
|
+
Cards with `type: 'sap-ui'` are rendered using the SAP UI5 `ComponentContainer` API. `window.sap.ui.require` must be available on the page (loaded via the SAP UI5 bootstrap script) before the dashboard renders.
|
|
340
|
+
|
|
341
|
+
`component` must be the SAP UI5 component name passed as `name` to `ComponentContainer`. `componentInputs` are forwarded as `settings` to the container constructor.
|
|
342
|
+
|
|
343
|
+
```ts
|
|
344
|
+
const cards: CardConfig[] = [
|
|
345
|
+
{
|
|
346
|
+
id: 'sap-component-card',
|
|
347
|
+
component: 'my.namespace.Component',
|
|
348
|
+
type: 'sap-ui',
|
|
349
|
+
w: 6,
|
|
350
|
+
h: 20,
|
|
351
|
+
componentInputs: {
|
|
352
|
+
env: 'production',
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
];
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
If `window.sap` is not available when the card is rendered, an error is logged and the card host element is left empty.
|