diff --git a/advanced/assets/hierarchical-tree-view.png b/advanced/assets/hierarchical-tree-view.png
new file mode 100644
index 0000000000..aaf46c64e4
Binary files /dev/null and b/advanced/assets/hierarchical-tree-view.png differ
diff --git a/advanced/fiori.md b/advanced/fiori.md
index 1c96d54e1e..1f42cc9e1d 100644
--- a/advanced/fiori.md
+++ b/advanced/fiori.md
@@ -745,9 +745,9 @@ 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 as a direct report or manager.
+Recursive hierarchies are parent-child related structures: 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 as a direct report or manager.
-A generic hierarchy implementation for hierarchies is available on all relational datases supported by the CAP runtimes.
+A generic hierarchy implementation for hierarchies is available on all relational databases supported by the CAP runtimes.
::: warning
On H2, only small hierarchies should be used for performance reasons.
@@ -761,6 +761,7 @@ Let's assume we have the following domain model and its projection in a service:
namespace my.bookshop;
entity Genres { //...
+ ID : UUID;
parent : Association to Genres;
}
```
@@ -774,19 +775,67 @@ service AdminService {
```
:::
+In this example, there is a managed to-one association `parent` that defines the parent-child hierarchy
+based on a single key element. In such a situation you can define the Tree View via the annotation `@hierarchy`:
-Annotate/extend the entity in the service as follows:
+```cds
+annotate AdminService.Genres with @hierarchy : parent;
+```
+
+If the entity contains only one such association, you can even omit the value:
+
+```cds
+annotate AdminService.Genres with @hierarchy;
+```
+
+Configure the TreeTable in UI5's _manifest.json_ file:
+
+```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: construct the `hierarchyQualifier` with the following pattern:
+> `Hierarchy`
+
+You can now start the server with `cds watch` and see the hierarchical tree view in action in the [_Browse Genres_](http://localhost:4004/fiori-apps.html#Genres-display) app.
+
+ {style="filter: drop-shadow(0 2px 5px rgba(0,0,0,.40));"}
+
+The compiler automatically expands the shortcut annotation `@hierarchy` to the
+following `annotate` and `extend` statements.
+
+### Manual Approach
+
+The following documents what happens behind the scenes, done by the compiler as described before. You can also use it, if you cannot use the `@hierarchy` annotation, for example, because you only have an unmanaged parent association.
```cds
// declare a hierarchy with the qualifier "GenresHierarchy"
-annotate AdminService.Genres with @Aggregation.RecursiveHierarchy #GenresHierarchy : {
+annotate AdminService.Genres with @Aggregation.RecursiveHierarchy #GenresHierarchy: {
NodeProperty : ID, // identifies a node, usually the key
ParentNavigationProperty : parent // navigates to a node's parent
};
extend AdminService.Genres with @(
// The computed properties expected by Fiori to be present in hierarchy entities
- Hierarchy.RecursiveHierarchy #GenresHierarchy : {
+ Hierarchy.RecursiveHierarchy #GenresHierarchy: {
LimitedDescendantCount : LimitedDescendantCount,
DistanceFromRoot : DistanceFromRoot,
DrillState : DrillState,
@@ -797,7 +846,7 @@ extend AdminService.Genres with @(
'LimitedDescendantCount', 'DistanceFromRoot', 'DrillState', 'LimitedRank'
],
// Disallow sorting on these properties from Fiori UIs
- Capabilities.SortRestrictions.NonSortableProperties : [
+ Capabilities.SortRestrictions.NonSortableProperties: [
'LimitedDescendantCount', 'DistanceFromRoot', 'DrillState', 'LimitedRank'
],
) columns { // Ensure we can query these columns from the database
@@ -811,31 +860,5 @@ extend AdminService.Genres with @(
> Note: When naming the hierarchy qualifier, use the following pattern:
> `Hierarchy`
-Configure the TreeTable in UI5's _manifest.json_ file:
-
-```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 earlier
-