Skip to content

Commit c61e0b7

Browse files
authored
feat(ui5): Add Smart & MDC Controls best practices skill (#91)
Add ui5-best-practices-smart-controls skill covering the sap.ui.comp library offering annotation-driven controls for OData V2 (SmartField, SmartForm, SmartFilterBar, SmartChart, SmartLink, SmartMultiInput, FilterBar, ValueHelpDialog). Add ui5-best-practices-mdc skill covering the sap.ui.mdc library offering delegate-based controls for OData V4 and JSON models (FilterBar, Chart, Field, FilterField, ValueHelp, Link, MultiValueField). JIRA: BGSOFUISAKAR-1630
1 parent 7cf7363 commit c61e0b7

19 files changed

Lines changed: 1713 additions & 0 deletions

plugins/ui5/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ Development guidelines for UI Integration Cards (also known as UI5 Integration C
5555
- **i18n** - Bind all user-facing strings to the i18n model; never hardcode
5656
- **Actions** - Use the `actions` property for links and interactions; never inline `<a>` tags or hand-roll URL handlers
5757

58+
#### ui5-best-practices-mdc
59+
60+
Development guidelines for `sap.ui.mdc` model-driven controls with OData V4 and JSON models (SAPUI5 1.136+ LTS):
61+
62+
- **Delegate pattern** - Base delegates, `fetchProperties`, `updateBindingInfo`, PropertyInfo structure
63+
- **Per-control references** - FilterBar, Chart, Field, FilterField, ValueHelp, Link, MultiValueField
64+
- **JSON model support** - Custom delegates, TypeMap registration, manual PropertyInfo
65+
- **Core rules** - Delegate configuration, `p13nMode`, condition handling, type namespaces
66+
5867
#### ui5-best-practices-opa5
5968

6069
Guidelines and debugging workflow for OPA5 integration tests:
@@ -64,6 +73,15 @@ Guidelines and debugging workflow for OPA5 integration tests:
6473
- **Page object organization** - Placement of actions and assertions across views
6574
- **App teardown** - Cleanup patterns in OPA5 journey tests
6675

76+
#### ui5-best-practices-smart-controls
77+
78+
Development guidelines for `sap.ui.comp` annotation-driven smart controls with OData V2 (SAPUI5 1.136+ LTS):
79+
80+
- **Per-control references** - SmartField, SmartForm, SmartFilterBar, SmartChart, SmartLink, SmartMultiInput, FilterBar, ValueHelpDialog
81+
- **Core rules** - Annotation requirements, `entitySet` binding, `initialise` event, SmartForm hierarchy
82+
- **Selection matrix** - When to use each smart control vs. alternatives
83+
- **Common errors** - Annotation mistakes, rendering issues, binding problems
84+
6785
#### ui5-best-practices-tables
6886

6987
Authoritative development guidelines for all UI5 table controls (SAPUI5 1.136+ LTS):
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
name: ui5-best-practices-mdc
3+
description: |
4+
UI5 MDC (Model-Driven Controls) best practices and authoritative development guidelines for OData V4 delegate-based controls. Use when the user asks to "create an MDC FilterBar", "implement MDC Chart", "add MDC Field", "use MDC FilterField", "implement ValueHelp", "add MDC Link", "MDC MultiValueField", "sap.ui.mdc", "delegate pattern", "fetchProperties", "OData V4 freestyle controls", "MDC personalization", "p13nMode", "PropertyInfo", "MDC delegate", "FilterBarDelegate", "ChartDelegate", "ValueHelpDelegate", "LinkDelegate", "MDC field not rendering", "MDC chart not binding", "MDC conditions", "Condition.createCondition", "MDC Table delegate", or is writing any UI5 freestyle application using OData V4 with model-driven controls from sap.ui.mdc. Covers: delegate pattern, PropertyInfo structure, mandatory rules, common error patterns, and per-control API reference for FilterBar, Chart, Field, FilterField, ValueHelp, Link, and MultiValueField.
5+
6+
Keywords: sap.ui.mdc, MDC, FilterBar, Chart, Field, FilterField, ValueHelp, Link, MultiValueField, delegate, fetchProperties, updateBindingInfo, PropertyInfo, OData V4, JSON model, JSONModel, custom delegate, TypeMap, DefaultTypeMap, base delegate, non-OData, addItem, getFilters, p13nMode, autoBindOnInit, conditions, TypeMap, FieldBase, FilterBarBase, ChartDelegate, ValueHelpDelegate, LinkDelegate, FilterBarDelegate, MultiValueFieldDelegate, Condition.createCondition
7+
---
8+
9+
# UI5 MDC Controls Best Practices
10+
11+
Apply these guidelines whenever generating, reviewing, or troubleshooting MDC control code in freestyle applications using OData V4 services.
12+
13+
**UI5 version baseline:** SAPUI5 1.136+ LTS. All features mentioned are available from this version unless noted.
14+
15+
## When to load each reference
16+
17+
| Trigger | Load |
18+
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
19+
| Working on or planning a `sap.ui.mdc.FilterBar` | [`references/mdc-filter-bar.md`](references/mdc-filter-bar.md) |
20+
| Working on or planning a `sap.ui.mdc.Chart` | [`references/mdc-chart.md`](references/mdc-chart.md) |
21+
| Working on or planning a `sap.ui.mdc.Field` | [`references/mdc-field.md`](references/mdc-field.md) |
22+
| Working on or planning a `sap.ui.mdc.FilterField` | [`references/mdc-filter-field.md`](references/mdc-filter-field.md) |
23+
| Working on or planning a `sap.ui.mdc.ValueHelp` | [`references/mdc-value-help.md`](references/mdc-value-help.md) |
24+
| Working on or planning a `sap.ui.mdc.Link` | [`references/mdc-link.md`](references/mdc-link.md) |
25+
| Working on or planning a `sap.ui.mdc.MultiValueField` | [`references/mdc-multi-value-field.md`](references/mdc-multi-value-field.md) |
26+
| Using MDC controls with JSON model (non-OData) | [`references/mdc-json-delegates.md`](references/mdc-json-delegates.md) |
27+
| Working on or planning a `sap.ui.mdc.Table` | See `ui5-best-practices-tables` skill, [`references/mdc-table.md`](../ui5-best-practices-tables/references/mdc-table.md) |
28+
29+
Load before producing any output. Do not work from memory.
30+
31+
---
32+
33+
## The Delegate Pattern
34+
35+
All MDC controls use a **delegate** to decouple the control from data-source-specific logic. App developers must:
36+
37+
1. Specify the delegate in XML: `delegate="{name: 'my/app/delegate/MyDelegate', payload: {entitySet: 'Products'}}"`
38+
2. Implement the delegate module extending the appropriate base delegate
39+
3. Override key methods (at minimum `fetchProperties`)
40+
41+
**Base delegates for OData V4:**
42+
43+
| Control | Base Delegate |
44+
| --------------- | ------------------------------------------ |
45+
| Table | `sap/ui/mdc/odata/v4/TableDelegate` |
46+
| FilterBar | `sap/ui/mdc/odata/v4/FilterBarDelegate` |
47+
| Chart | `sap/ui/mdc/odata/v4/vizChart/Delegate` |
48+
| ValueHelp | `sap/ui/mdc/ValueHelpDelegate` |
49+
| Link | `sap/ui/mdc/LinkDelegate` |
50+
| MultiValueField | `sap/ui/mdc/field/MultiValueFieldDelegate` |
51+
52+
**JSON model usage:** MDC controls also work with JSON models. Extend the base delegates directly (`sap/ui/mdc/TableDelegate`, `sap/ui/mdc/FilterBarDelegate`) — not the OData V4 variants. See [`references/mdc-json-delegates.md`](references/mdc-json-delegates.md) for details.
53+
54+
**PropertyInfo** — the core metadata format returned by `fetchProperties`:
55+
56+
```javascript
57+
{
58+
key: "propertyName", // Unique identifier (required)
59+
label: "Display Label", // User-visible label (required)
60+
dataType: "sap.ui.model.odata.v4.type.String" // Data type (required)
61+
}
62+
```
63+
64+
---
65+
66+
## Core Rules
67+
68+
### Mandatory
69+
70+
- Every MDC control requires a `delegate` property pointing to a valid module path.
71+
- Implement `fetchProperties` in the delegate returning `PropertyInfo[]` with at minimum: `key`, `label`, `dataType`.
72+
- Extend the appropriate OData V4 base delegate (see table above) for OData V4 services. For JSON/other models, extend the generic base delegate directly.
73+
- Use `p13nMode` to enable personalization (Column, Sort, Filter, Group for Table; Item, Sort, Filter, Type for Chart; Item for FilterBar).
74+
- Use `sap.ui.mdc.condition.Condition.createCondition()` to construct conditions programmatically.
75+
- Use `sap.ui.model.odata.v4.type.*` types in PropertyInfo `dataType` field for OData V4 models. Use `sap.ui.model.type.*` with JSON models. Register types in the TypeMap.
76+
- Set `ariaLabelledBy` on FilterBar and Chart for accessibility.
77+
- Prefer Fiori elements building blocks over freestyle MDC. Use MDC only when Fiori elements is out of scope.
78+
- Use `get_api_reference` MCP tool to verify control APIs. Use `run_ui5_linter` to validate code.
79+
80+
### Prohibitions
81+
82+
- Do not use MDC controls with OData V2 models. Use Smart controls (`sap.ui.comp`) instead. MDC works with OData V4 and JSON models.
83+
- Do not access inner controls directly (e.g., inner `sap.chart.Chart` or `sap.m.Table`). Use the delegate or MDC control's public API.
84+
- Do not omit `key` from PropertyInfo objects (formerly `name`, now deprecated).
85+
- Do not construct condition objects manually as plain JSON. Always use `Condition.createCondition(operator, values)`.
86+
- Do not skip delegate implementation for production code (built-in defaults are for demos only).
87+
- Do not use inline styles or scripts (CSP compliance).
88+
- Do not use global access (`sap.ui.mdc.FilterBar`). Use `sap.ui.define` or ES6 imports.
89+
90+
---
91+
92+
## Selection Matrix
93+
94+
| Control | Use when | Do not use when |
95+
| --------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- |
96+
| `MDC FilterBar` | OData V4 or JSON model, delegate-driven filter UI, MDC Table/Chart | OData V2 (use SmartFilterBar), simple search bar |
97+
| `MDC Chart` | OData V4, delegate-driven chart visualization, drill-down | OData V2 (use SmartChart), simple static charts, no analytical data |
98+
| `MDC Field` | OData V4 or JSON, single field with auto-rendering by data type | OData V2 (use SmartField), purely custom rendering needed |
99+
| `MDC FilterField` | Inside MDC FilterBar for individual filter conditions | Standalone filtering outside FilterBar context |
100+
| `MDC ValueHelp` | OData V4 or JSON, type-ahead + dialog value selection | OData V2 (use ValueHelpDialog), simple dropdowns without search |
101+
| `MDC Link` | OData V4, semantic object navigation, delegate-driven link targets | OData V2 (use SmartLink), simple static links |
102+
| `MDC MultiValueField` | OData V4 or JSON, multi-value token entry via items aggregation | OData V2 (use SmartMultiInput), simple single-value fields |
103+
104+
---
105+
106+
## Common Errors
107+
108+
| Symptom | Cause | Fix |
109+
| ------------------------------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
110+
| "Delegate module could not be loaded" | Wrong path in `delegate` property | Verify module path matches actual file location in project. |
111+
| Chart shows no data | `fetchProperties` returns wrong PropertyInfo (missing `groupable`/`aggregatable`) | Ensure dimensions have `groupable: true`, measures have `aggregatable: true`. |
112+
| FilterBar fields not appearing | PropertyInfo missing or `hiddenFilter: true` | Check delegate `fetchProperties` returns properties with correct visibility. |
113+
| Field shows wrong inner control | `dataType` in PropertyInfo doesn't match expected format | Verify `dataType` uses full qualified type name (e.g., `sap.ui.model.odata.v4.type.String`). |
114+
| Personalization dialog empty | `p13nMode` not set or PropertyInfo incomplete | Add `p13nMode="Column,Sort,Filter"` and ensure PropertyInfo has `sortable`/`filterable` flags. |
115+
| ValueHelp not opening | ValueHelp not connected to Field or containers missing | Verify `valueHelp` association on Field and that Popover/Dialog containers are defined. |
116+
| Conditions not applied to binding | `updateBindingInfo` not implemented in delegate | Implement `updateBindingInfo` to apply filter conditions to the OData binding. |
117+
| Link always rendered as text | `fetchLinkType` returns `LinkType.Text` or fails | Implement `fetchLinkType` returning `Popup` or `DirectLink` type. |
118+
119+
---
120+
121+
## Performance & Accessibility
122+
123+
### Anti-patterns to avoid
124+
125+
- Loading all PropertyInfo eagerly when only a subset is needed (return minimal set from `fetchProperties`).
126+
- Not implementing `updateBindingInfo` (conditions are never applied to the data binding).
127+
- Skipping `p13nMode` configuration (personalization features are disabled by default).
128+
- Creating large delegate modules (split complex logic into helper modules loaded on demand).
129+
- Using synchronous operations in delegate methods (all delegate methods should return Promises).
130+
131+
### Accessibility checklist
132+
133+
- Set `ariaLabelledBy` on FilterBar referencing a visible title.
134+
- Set `ariaLabelledBy` on Chart referencing a visible title.
135+
- Verify keyboard navigation works for personalization dialogs.
136+
- Test ValueHelp type-ahead and dialog with screen reader.
137+
- Ensure all FilterFields have meaningful labels via PropertyInfo `label`.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# sap.ui.mdc.Chart
2+
3+
API: https://ui5.sap.com/#/api/sap.ui.mdc.Chart
4+
5+
## Delegate pattern
6+
7+
`sap.ui.mdc.Chart` uses a delegate for chart initialization and data binding. Extend `sap/ui/mdc/odata/v4/vizChart/Delegate` for OData V4.
8+
9+
Minimal delegate:
10+
11+
```javascript
12+
sap.ui.define(
13+
["sap/ui/mdc/odata/v4/vizChart/Delegate"],
14+
function (ChartDelegate) {
15+
const MyChartDelegate = Object.assign({}, ChartDelegate)
16+
17+
MyChartDelegate.fetchProperties = function (oChart) {
18+
return Promise.resolve([
19+
{
20+
key: "category",
21+
label: "Category",
22+
dataType: "sap.ui.model.odata.v4.type.String",
23+
groupable: true,
24+
aggregatable: false,
25+
role: "category",
26+
},
27+
{
28+
key: "revenue",
29+
label: "Revenue",
30+
dataType: "sap.ui.model.odata.v4.type.Decimal",
31+
groupable: false,
32+
aggregatable: true,
33+
role: "axis1",
34+
},
35+
])
36+
}
37+
38+
return MyChartDelegate
39+
}
40+
)
41+
```
42+
43+
## PropertyInfo for Chart
44+
45+
| Field | Type | Purpose |
46+
| -------------- | ------- | ---------------------------------------------------------- |
47+
| `key` | string | Unique property identifier (required). |
48+
| `label` | string | Display label (required). |
49+
| `dataType` | string | Full type name (required). |
50+
| `groupable` | boolean | `true` = can be used as dimension. |
51+
| `aggregatable` | boolean | `true` = can be used as measure. |
52+
| `role` | string | `"category"`, `"series"`, `"axis1"`, `"axis2"`, `"axis3"`. |
53+
| `sortable` | boolean | Enable sorting. |
54+
| `filterable` | boolean | Enable filtering. |
55+
56+
## Chart usage
57+
58+
```xml
59+
<mdc:Chart id="myChart" header="Sales Overview"
60+
delegate="{name: 'my/app/delegate/ChartDelegate', payload: {entitySet: 'Sales'}}"
61+
p13nMode="Item,Sort,Type" height="400px"
62+
filter="filterBar" autoBindOnInit="true">
63+
<mdc:items>
64+
<mdcChart:Item propertyKey="category" type="groupable" role="category"/>
65+
<mdcChart:Item propertyKey="revenue" type="aggregatable" role="axis1"/>
66+
</mdc:items>
67+
</mdc:Chart>
68+
```
69+
70+
## Key properties
71+
72+
| Property | Purpose |
73+
| ---------------- | -------------------------------------------------------- |
74+
| `delegate` | Delegate module path and payload (required). |
75+
| `header` | Chart title. |
76+
| `height` | Explicit height (required — chart collapses without it). |
77+
| `p13nMode` | Personalization: `Item`, `Sort`, `Filter`, `Type`. |
78+
| `filter` | Association to MDC FilterBar for connected filtering. |
79+
| `autoBindOnInit` | Auto-bind data on initialization. |
80+
| `legendVisible` | Show/hide chart legend. |
81+
| `noDataText` | Custom text for empty state. |
82+
83+
## Key events
84+
85+
| Event | Purpose |
86+
| ------------------ | ------------------------------ |
87+
| `dataLoadComplete` | Inner chart data fully loaded. |
88+
89+
## Troubleshooting
90+
91+
- Chart not visible / height 0: set explicit `height` on Chart (e.g., `"400px"` or `"50vh"`).
92+
- No data displayed: verify `fetchProperties` returns properties with correct `groupable`/`aggregatable` flags.
93+
- Chart type unavailable: current data combination doesn't support it; verify dimensions/measures.
94+
- PersonalizationDialog empty: set `p13nMode` and ensure PropertyInfo has all required flags.
95+
- FilterBar not applying: verify `filter` association points to correct FilterBar ID.

0 commit comments

Comments
 (0)