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. + +![Fiori UI with hierarchical tree view.](assets/hierarchical-tree-view.png) {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 -