@openmfp/webcomponents 0.6.1 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/mfp-wc-dashboard.js +153 -0
  2. package/mfp-webcomponents.js +573 -0
  3. package/package.json +14 -68
  4. package/.github/workflows/pipeline.yaml +0 -41
  5. package/.storybook/main.ts +0 -34
  6. package/.storybook/preview.ts +0 -29
  7. package/.storybook/tsconfig.json +0 -11
  8. package/AGENTS.md +0 -153
  9. package/CODEOWNERS +0 -6
  10. package/CONTRIBUTING.md +0 -95
  11. package/LICENSE +0 -201
  12. package/LICENSES/Apache-2.0.txt +0 -73
  13. package/README.md +0 -91
  14. package/REUSE.toml +0 -9
  15. package/angular.json +0 -157
  16. package/docs/dashboard.md +0 -358
  17. package/docs/declarative-form.md +0 -178
  18. package/docs/declarative-table-card.md +0 -235
  19. package/docs/declarative-table.md +0 -315
  20. package/eslint.config.js +0 -41
  21. package/projects/ngx/cards/favorites/favorites.component.html +0 -12
  22. package/projects/ngx/cards/favorites/favorites.component.scss +0 -50
  23. package/projects/ngx/cards/favorites/favorites.component.ts +0 -19
  24. package/projects/ngx/cards/public-api.ts +0 -4
  25. package/projects/ngx/cards/service-status/service-status-card.component.html +0 -15
  26. package/projects/ngx/cards/service-status/service-status-card.component.scss +0 -87
  27. package/projects/ngx/cards/service-status/service-status-card.component.ts +0 -36
  28. package/projects/ngx/cards/stories/visited-service-card.stories.ts +0 -149
  29. package/projects/ngx/cards/visited-service-card/visited-service-card.component.html +0 -17
  30. package/projects/ngx/cards/visited-service-card/visited-service-card.component.scss +0 -34
  31. package/projects/ngx/cards/visited-service-card/visited-service-card.component.ts +0 -22
  32. package/projects/ngx/cards/whats-new/whats-new.component.html +0 -10
  33. package/projects/ngx/cards/whats-new/whats-new.component.scss +0 -25
  34. package/projects/ngx/cards/whats-new/whats-new.component.ts +0 -46
  35. package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.html +0 -28
  36. package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.scss +0 -44
  37. package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.spec.ts +0 -85
  38. package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.ts +0 -58
  39. package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.html +0 -29
  40. package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.scss +0 -63
  41. package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.spec.ts +0 -255
  42. package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.ts +0 -75
  43. package/projects/ngx/declarative-ui/dashboard/card/utils/dashboard-card-registry.spec.ts +0 -76
  44. package/projects/ngx/declarative-ui/dashboard/card/utils/dashboard-card-registry.ts +0 -109
  45. package/projects/ngx/declarative-ui/dashboard/card/utils/index.ts +0 -4
  46. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-angular-card.spec.ts +0 -141
  47. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-angular-card.ts +0 -44
  48. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-sap-card.spec.ts +0 -142
  49. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-sap-card.ts +0 -52
  50. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-wc-card.spec.ts +0 -107
  51. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-wc-card.ts +0 -22
  52. package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.html +0 -134
  53. package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.scss +0 -88
  54. package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.spec.ts +0 -354
  55. package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.ts +0 -238
  56. package/projects/ngx/declarative-ui/dashboard/dashboard/index.ts +0 -1
  57. package/projects/ngx/declarative-ui/dashboard/index.ts +0 -5
  58. package/projects/ngx/declarative-ui/dashboard/models/constants.ts +0 -2
  59. package/projects/ngx/declarative-ui/dashboard/models/dashboard.model.ts +0 -50
  60. package/projects/ngx/declarative-ui/dashboard/models/index.ts +0 -1
  61. package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.html +0 -28
  62. package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.scss +0 -85
  63. package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.spec.ts +0 -104
  64. package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.ts +0 -23
  65. package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.html +0 -62
  66. package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.scss +0 -12
  67. package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.spec.ts +0 -301
  68. package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.ts +0 -166
  69. package/projects/ngx/declarative-ui/form/declarative-form/index.ts +0 -1
  70. package/projects/ngx/declarative-ui/form/index.ts +0 -2
  71. package/projects/ngx/declarative-ui/form/models/form-field-definition.ts +0 -15
  72. package/projects/ngx/declarative-ui/form/models/index.ts +0 -1
  73. package/projects/ngx/declarative-ui/form/utils/set-property-by-path.ts +0 -30
  74. package/projects/ngx/declarative-ui/models/index.ts +0 -2
  75. package/projects/ngx/declarative-ui/models/resource.ts +0 -5
  76. package/projects/ngx/declarative-ui/models/ui-definition.ts +0 -95
  77. package/projects/ngx/declarative-ui/public-api.ts +0 -4
  78. package/projects/ngx/declarative-ui/stories/add-card-dialog.stories.ts +0 -91
  79. package/projects/ngx/declarative-ui/stories/background-lightblue.png +0 -0
  80. package/projects/ngx/declarative-ui/stories/dashboard.cards.ts +0 -107
  81. package/projects/ngx/declarative-ui/stories/dashboard.stories.ts +0 -296
  82. package/projects/ngx/declarative-ui/stories/declarative-form.stories.ts +0 -149
  83. package/projects/ngx/declarative-ui/stories/declarative-table-card.stories.ts +0 -358
  84. package/projects/ngx/declarative-ui/stories/declarative-table.stories.ts +0 -363
  85. package/projects/ngx/declarative-ui/stories/pods-table.config.ts +0 -188
  86. package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.html +0 -138
  87. package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.scss +0 -21
  88. package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.spec.ts +0 -345
  89. package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.ts +0 -61
  90. package/projects/ngx/declarative-ui/table/declarative-table/index.ts +0 -1
  91. package/projects/ngx/declarative-ui/table/index.ts +0 -2
  92. package/projects/ngx/declarative-ui/table/models/index.ts +0 -14
  93. package/projects/ngx/declarative-ui/table/models/table.model.ts +0 -17
  94. package/projects/ngx/declarative-ui/table/utils/cssRules.engine.spec.ts +0 -146
  95. package/projects/ngx/declarative-ui/table/utils/cssRules.engine.ts +0 -69
  96. package/projects/ngx/declarative-ui/table/utils/field-definition.utils.spec.ts +0 -70
  97. package/projects/ngx/declarative-ui/table/utils/field-definition.utils.ts +0 -13
  98. package/projects/ngx/declarative-ui/table/utils/proccess-fields.spec.ts +0 -511
  99. package/projects/ngx/declarative-ui/table/utils/proccess-fields.ts +0 -71
  100. package/projects/ngx/declarative-ui/table/utils/resource-field-by-path.spec.ts +0 -372
  101. package/projects/ngx/declarative-ui/table/utils/resource-field-by-path.ts +0 -98
  102. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-cell.constants.ts +0 -5
  103. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.html +0 -1
  104. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.scss +0 -0
  105. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.spec.ts +0 -119
  106. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.ts +0 -35
  107. package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.html +0 -7
  108. package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.scss +0 -0
  109. package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.spec.ts +0 -114
  110. package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.ts +0 -19
  111. package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.html +0 -7
  112. package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.scss +0 -10
  113. package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.spec.ts +0 -188
  114. package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.ts +0 -16
  115. package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.html +0 -59
  116. package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.scss +0 -33
  117. package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.spec.ts +0 -316
  118. package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.ts +0 -115
  119. package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.html +0 -156
  120. package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.scss +0 -123
  121. package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.spec.ts +0 -786
  122. package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.ts +0 -286
  123. package/projects/ngx/declarative-ui/table-card/index.ts +0 -2
  124. package/projects/ngx/declarative-ui/table-card/models/configs.ts +0 -46
  125. package/projects/ngx/declarative-ui/tsconfig.lib.json +0 -11
  126. package/projects/ngx/declarative-ui/tsconfig.lib.prod.json +0 -9
  127. package/projects/ngx/declarative-ui/tsconfig.spec.json +0 -9
  128. package/projects/ngx/ng-package.json +0 -8
  129. package/projects/ngx/package.json +0 -22
  130. package/projects/ngx/public-api.ts +0 -2
  131. package/projects/ngx/tsconfig.lib.json +0 -11
  132. package/projects/ngx/tsconfig.lib.prod.json +0 -9
  133. package/projects/webcomponents/main.ts +0 -92
  134. package/projects/webcomponents/tsconfig.app.json +0 -9
  135. package/projects/webcomponents-dashboard/main.ts +0 -15
  136. package/projects/webcomponents-dashboard/tsconfig.app.json +0 -9
  137. package/renovate.json +0 -6
  138. package/scripts/bundle-wc.mjs +0 -79
  139. package/tsconfig.json +0 -37
  140. package/tsconfig.spec.json +0 -8
  141. package/tsconfig.storybook.json +0 -16
  142. package/vitest.config.ts +0 -26
package/docs/dashboard.md DELETED
@@ -1,358 +0,0 @@
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.
@@ -1,178 +0,0 @@
1
- # DeclarativeForm
2
-
3
- A dynamic form web component that renders fields from a declarative field definition. The component does not execute validation logic. It emits per-field change events based on each field's `validation` strategy, accepts host-owned field errors, and emits a nested value only when the host triggers submit.
4
-
5
- ## Tags
6
-
7
- | Usage | Tag |
8
- | ---------------------------------- | --------------------------- |
9
- | Angular component | `<mfp-declarative-form>` |
10
- | Web Component (framework-agnostic) | `<mfp-wc-declarative-form>` |
11
-
12
- ---
13
-
14
- ## Usage as a web component
15
-
16
- ```html
17
- <mfp-wc-declarative-form id="form"></mfp-wc-declarative-form>
18
-
19
- <script type="module">
20
- const form = document.getElementById('form');
21
-
22
- form.fields = [
23
- { name: 'metadata.name', label: 'Name', required: true, validation: 'onChange' },
24
- { name: 'metadata.namespace', label: 'Namespace', validation: 'onBlur' },
25
- ];
26
-
27
- form.addEventListener('fieldChange', (event) => {
28
- const { fieldProperty, value } = event.detail;
29
- const fieldErrors = { ...form.fieldErrors };
30
-
31
- if (fieldProperty === 'metadata.name' && !value) {
32
- fieldErrors[fieldProperty] = 'Name is required';
33
- } else {
34
- fieldErrors[fieldProperty] = null;
35
- }
36
-
37
- form.fieldErrors = fieldErrors;
38
- });
39
-
40
- form.addEventListener('formSubmit', (event) => {
41
- console.log(event.detail);
42
- // { metadata: { name: 'my-app', namespace: 'default' } }
43
- });
44
-
45
- // Trigger when the surrounding page decides the form should submit.
46
- form.submit();
47
- </script>
48
- ```
49
-
50
- > `fields`, `initialValues`, and `fieldErrors` are JavaScript properties, not HTML attributes.
51
-
52
- ---
53
-
54
- ## Usage as an Angular component
55
-
56
- ```ts
57
- import {
58
- DeclarativeForm,
59
- FormFieldChangeEvent,
60
- FormFieldDefinition,
61
- FormFieldErrors,
62
- } from '@openmfp/webcomponents';
63
-
64
- @Component({
65
- imports: [DeclarativeForm],
66
- template: `
67
- <mfp-declarative-form
68
- #form
69
- [fields]="fields"
70
- [initialValues]="initialValues"
71
- [fieldErrors]="fieldErrors"
72
- (fieldChange)="onFieldChange($event)"
73
- (formSubmit)="onSubmit($event)"
74
- />
75
-
76
- <button type="button" (click)="form.submit()">Save</button>
77
- `,
78
- })
79
- export class MyComponent {
80
- fields: FormFieldDefinition[] = [
81
- { name: 'metadata.name', label: 'Name', required: true, validation: 'onChange' },
82
- { name: 'metadata.namespace', label: 'Namespace', validation: 'onBlur' },
83
- ];
84
-
85
- initialValues = {
86
- 'metadata.name': 'my-app',
87
- 'metadata.namespace': 'default',
88
- };
89
-
90
- fieldErrors: FormFieldErrors = {};
91
-
92
- onFieldChange(event: FormFieldChangeEvent): void {
93
- const { fieldProperty, value } = event;
94
- this.fieldErrors = {
95
- ...this.fieldErrors,
96
- [fieldProperty]: !value ? 'Field is required' : null,
97
- };
98
- }
99
-
100
- onSubmit(value: Record<string, unknown>): void {
101
- // value is nested: { metadata: { name: 'my-app', namespace: 'default' } }
102
- }
103
- }
104
- ```
105
-
106
- ---
107
-
108
- ## API
109
-
110
- ### Inputs
111
-
112
- | Input | Type | Required | Default | Description |
113
- | --------------- | ------------------------- | -------- | ------- | ----------------------------------------------------------------------------- |
114
- | `fields` | `FormFieldDefinition[]` | yes | - | Field definitions to render |
115
- | `initialValues` | `Record<string, unknown>` | no | `{}` | Initial values keyed by exact `field.name` |
116
- | `fieldErrors` | `FormFieldErrors` | no | `{}` | Host-owned errors keyed by exact `field.name` |
117
- | `editMode` | `boolean` | no | `false` | Signals edit mode to consumers; does not change component behavior on its own |
118
-
119
- ### Outputs / Events
120
-
121
- | Event | Detail payload | Description |
122
- | ------------ | --------------------------- | ------------------------------------------------------------------ |
123
- | `fieldChange` | `FormFieldChangeEvent` | Fires per-field based on the field's `validation` strategy |
124
- | `formSubmit` | `Record<string, unknown>` | Fires when `submit()` is called; value is nested |
125
-
126
- ---
127
-
128
- ## Types
129
-
130
- ```ts
131
- interface FormFieldDefinition {
132
- name: string; // Field key; dots create nested submit output paths
133
- label?: string; // Display label shown above the field
134
- required?: boolean; // Visual required marker only
135
- values?: string[]; // Static select options
136
- disabled?: boolean; // Disables the field
137
- validation?: 'onBlur' | 'onChange'; // When to emit fieldChange for this field
138
- }
139
-
140
- interface FormFieldChangeEvent {
141
- fieldProperty: string; // The field property name (matches field.name)
142
- value: unknown; // Current value of the control
143
- }
144
-
145
- type FormFieldErrors = Record<string, string | null>;
146
- ```
147
-
148
- `fieldChange` emits a single field at a time:
149
-
150
- ```ts
151
- { fieldProperty: 'metadata.name', value: 'my-app' }
152
- ```
153
-
154
- `formSubmit` emits a nested object:
155
-
156
- ```ts
157
- {
158
- metadata: {
159
- name: 'my-app',
160
- namespace: 'default',
161
- },
162
- }
163
- ```
164
-
165
- ---
166
-
167
- ## Validation
168
-
169
- - The component never executes validators.
170
- - `required` only renders the required marker on the label/input.
171
- - The `validation` property on each field controls when `fieldChange` fires:
172
- - `'onChange'` — fires on every value change.
173
- - `'onBlur'` — fires when the field loses focus.
174
- - Not set — no `fieldChange` event is emitted for that field.
175
- - On initialization (and when `initialValues` changes), the component emits `fieldChange` for every field that has a `validation` strategy. This lets the host run validation immediately and disable the submit button before the user interacts.
176
- - The host validates the received `FormFieldChangeEvent` and updates `fieldErrors`.
177
- - A field shows `Negative` value state and the error message only when it is dirty or touched and `fieldErrors[field.name]` is a non-empty string.
178
- - Empty, missing, or `null` errors render as no error.