From 456b4763e8ff7d66d47b3b7f23791edf888461bb Mon Sep 17 00:00:00 2001 From: Evgeny Andreev Date: Tue, 5 Aug 2025 10:02:28 +0200 Subject: [PATCH 1/5] Document Tree Views --- advanced/fiori.md | 92 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/advanced/fiori.md b/advanced/fiori.md index a2f03918c..6b2201b27 100644 --- a/advanced/fiori.md +++ b/advanced/fiori.md @@ -714,8 +714,94 @@ The `max-age` is the elapsed time since the response was generated on the origin Cache Control feature is currently supported on the Java runtime only. ::: -
-
+## Hierarchical Tree Views -
+Recursive hierarchies are parent-child hierarchies, where each entity references its parent and through that defines the hierarchical structure. A common example is a company organization structure or HR reporting, where each employee entity references another employee a as direct report or manager. + +Generic implementation is supported on the following databases for both CAP runtimes: + +| Runtime\DB | SAP HANA | H2 | PostgreSQL | SQLite | +|-------------|----------|----|------------|--------| +| CAP Java | ✓ | ✓ | ✓ | | +| CAP Node.js | ✓ | |✓ |✓ | + +:::info +The source elements of the entity defining the recursive parent-child relation are identified by a naming convention or aliases `node_id` and `parent_id`. + + +### Configuration + +Given the following domain model: + +```cds +entity Genres { //... + parent : Association to Genres; +} +``` + +#### Configure the TreeTable in UI5's _manifest.json_ + +```jsonc + "sap.ui5": { ... + "routing": { ... + "targets": { ... + "GenresList": { ... + "options": { + "settings": { ... + "controlConfiguration": { + "@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "hierarchyQualifier": "GenresHierarchy", // [!code focus] + "type": "TreeTable" // [!code focus] + } + } + } + } + } + }, + }, + }, +``` + +> Note: `hierarchyQualifier` should be chosen as:
+> `"Hierarchy"` + +#### Annotate/extend the entity in the service as follows: + +```cds +annotate AdminService.Genres with @Aggregation.RecursiveHierarchy #GenresHierarchy : { + ParentNavigationProperty : parent, // navigates to a node's parent + NodeProperty : ID, // identifies a node, usually the key +}; + +// Fiori expects the following to be defined explicitly, even though they're always the same +extend AdminService.Genres with @( + // The columns expected by Fiori to be present in hierarchy entities + Hierarchy.RecursiveHierarchy #GenresHierarchy : { + LimitedDescendantCount : LimitedDescendantCount, + DistanceFromRoot : DistanceFromRoot, + DrillState : DrillState, + LimitedRank : LimitedRank + }, + // Disallow filtering on these properties from Fiori UIs + Capabilities.FilterRestrictions.NonFilterableProperties: [ + 'LimitedDescendantCount', + 'DistanceFromRoot', + 'DrillState', + 'LimitedRank' + ], + // Disallow sorting on these properties from Fiori UIs + Capabilities.SortRestrictions.NonSortableProperties : [ + 'LimitedDescendantCount', + 'DistanceFromRoot', + 'DrillState', + 'LimitedRank' + ], +) columns { // Ensure we can query these fields from database + null as LimitedDescendantCount : Int16, + null as DistanceFromRoot : Int16, + null as DrillState : String, + null as LimitedRank : Int16, +}; +``` From f004732cd5208e8048f54f9f14e55e06e3202b38 Mon Sep 17 00:00:00 2001 From: Evgeny Andreev Date: Mon, 11 Aug 2025 12:41:16 +0200 Subject: [PATCH 2/5] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adrian Görler --- advanced/fiori.md | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/advanced/fiori.md b/advanced/fiori.md index 6b2201b27..afe3effd5 100644 --- a/advanced/fiori.md +++ b/advanced/fiori.md @@ -719,16 +719,13 @@ Cache Control feature is currently supported on the Java runtime only. Recursive hierarchies are parent-child hierarchies, where each entity references its parent and through that defines the hierarchical structure. A common example is a company organization structure or HR reporting, where each employee entity references another employee a as direct report or manager. -Generic implementation is supported on the following databases for both CAP runtimes: +A generic implementation is supported on the following databases for the respective CAP runtimes: | Runtime\DB | SAP HANA | H2 | PostgreSQL | SQLite | |-------------|----------|----|------------|--------| | CAP Java | ✓ | ✓ | ✓ | | | CAP Node.js | ✓ | |✓ |✓ | -:::info -The source elements of the entity defining the recursive parent-child relation are identified by a naming convention or aliases `node_id` and `parent_id`. - ### Configuration @@ -775,9 +772,8 @@ annotate AdminService.Genres with @Aggregation.RecursiveHierarchy #GenresHierarc NodeProperty : ID, // identifies a node, usually the key }; -// Fiori expects the following to be defined explicitly, even though they're always the same extend AdminService.Genres with @( - // The columns expected by Fiori to be present in hierarchy entities + // The computed properties expected by Fiori to be present in hierarchy entities Hierarchy.RecursiveHierarchy #GenresHierarchy : { LimitedDescendantCount : LimitedDescendantCount, DistanceFromRoot : DistanceFromRoot, @@ -786,19 +782,13 @@ extend AdminService.Genres with @( }, // Disallow filtering on these properties from Fiori UIs Capabilities.FilterRestrictions.NonFilterableProperties: [ - 'LimitedDescendantCount', - 'DistanceFromRoot', - 'DrillState', - 'LimitedRank' + 'LimitedDescendantCount', 'DistanceFromRoot', 'DrillState', 'LimitedRank' ], // Disallow sorting on these properties from Fiori UIs Capabilities.SortRestrictions.NonSortableProperties : [ - 'LimitedDescendantCount', - 'DistanceFromRoot', - 'DrillState', - 'LimitedRank' + 'LimitedDescendantCount', 'DistanceFromRoot', 'DrillState', 'LimitedRank' ], -) columns { // Ensure we can query these fields from database +) columns { // Ensure we can query these columns from the database null as LimitedDescendantCount : Int16, null as DistanceFromRoot : Int16, null as DrillState : String, From 0cfa43d5b03338485ad1f228724cdf3743eb6302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20G=C3=B6rler?= Date: Mon, 11 Aug 2025 13:23:56 +0200 Subject: [PATCH 3/5] Update fiori.md --- advanced/fiori.md | 66 ++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/advanced/fiori.md b/advanced/fiori.md index afe3effd5..77f7e98e5 100644 --- a/advanced/fiori.md +++ b/advanced/fiori.md @@ -732,44 +732,28 @@ A generic implementation is supported on the following databases for the respect Given the following domain model: ```cds +namespace my.bookshop; + entity Genres { //... parent : Association to Genres; } ``` -#### Configure the TreeTable in UI5's _manifest.json_ +and this projection on service level -```jsonc - "sap.ui5": { ... - "routing": { ... - "targets": { ... - "GenresList": { ... - "options": { - "settings": { ... - "controlConfiguration": { - "@com.sap.vocabularies.UI.v1.LineItem": { - "tableSettings": { - "hierarchyQualifier": "GenresHierarchy", // [!code focus] - "type": "TreeTable" // [!code focus] - } - } - } - } - } - }, - }, - }, +```cds +service AdminService { + entity Genres as projection on my.bookshop.Genres; +} ``` -> Note: `hierarchyQualifier` should be chosen as:
-> `"Hierarchy"` - #### Annotate/extend the entity in the service as follows: ```cds +// declare a hierarchy with the qualifier "GenresHierarchy" annotate AdminService.Genres with @Aggregation.RecursiveHierarchy #GenresHierarchy : { - ParentNavigationProperty : parent, // navigates to a node's parent - NodeProperty : ID, // identifies a node, usually the key + NodeProperty : ID, // identifies a node, usually the key + ParentNavigationProperty : parent // navigates to a node's parent }; extend AdminService.Genres with @( @@ -795,3 +779,33 @@ extend AdminService.Genres with @( null as LimitedRank : Int16, }; ``` + +> Note: hierarchy qualifier should be chosen as:
+> `Hierarchy` + +#### Configure the TreeTable in UI5's _manifest.json_ + +```jsonc + "sap.ui5": { ... + "routing": { ... + "targets": { ... + "GenresList": { ... + "options": { + "settings": { ... + "controlConfiguration": { + "@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "hierarchyQualifier": "GenresHierarchy", // [!code focus] + "type": "TreeTable" // [!code focus] + } + } + } + } + } + }, + }, + }, +``` + +> Note: use the `hierarchyQualifier` declared above + From 255afccc4e6a9cc2ecf50ff61cf58c3ce1f78348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20G=C3=B6rler?= Date: Mon, 11 Aug 2025 13:24:51 +0200 Subject: [PATCH 4/5] Update advanced/fiori.md --- advanced/fiori.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advanced/fiori.md b/advanced/fiori.md index 77f7e98e5..c4fad99c8 100644 --- a/advanced/fiori.md +++ b/advanced/fiori.md @@ -776,7 +776,7 @@ extend AdminService.Genres with @( null as LimitedDescendantCount : Int16, null as DistanceFromRoot : Int16, null as DrillState : String, - null as LimitedRank : Int16, + null as LimitedRank : Int16 }; ``` From 7000dc6c4c7f61db5155a5ba7f0a9034af551d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20G=C3=B6rler?= Date: Tue, 12 Aug 2025 13:13:35 +0200 Subject: [PATCH 5/5] Update advanced/fiori.md Co-authored-by: Evgeny Andreev --- advanced/fiori.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advanced/fiori.md b/advanced/fiori.md index c4fad99c8..cfc6e1990 100644 --- a/advanced/fiori.md +++ b/advanced/fiori.md @@ -739,7 +739,7 @@ entity Genres { //... } ``` -and this projection on service level +and its projection on service level ```cds service AdminService {