Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Ajit_K_Panda
Product and Topic Expert
Product and Topic Expert

Introduction:

Sometime back, I had the opportunity to delve into the world of Fiori Elements, documenting my understandings that highlighted some of its key features in following blog post:

CAP with Fiori Elements: Side Effects, Custom Actions, Dynamic Expressions

Building upon that exploration, in this blogpost,  I aim to explain different options available for presenting table in a List Report and how can we use these features to enhance user experience when showcasing data in a tabular format.

Example of POC Scenario and Its resources:

We will use the sample project “cap-fe-lr-table-views” that I have shared on GitHub here to explain the concepts. Let's briefly examine the project and some of its essential files.

Ajit_K_Panda_0-1707111808604.png
  • db/ : Data model is defined in schema.cds
  • srv/ : 
    Services are defined in service.cds
    Capabilities of services are defined in annotations.cds
  • app/ : This has 5 ui frontends.
  • app/ui01 : Single Table - Segmented View scenario
  • app/ui02 : Multiple Table - Tab View scenario
  • app/ui03 : Multiple Table & Chart - Tab View scenario
  • app/ui04 : Multiple Table - Tab & Segmented View scneario
  • app/ui05 : Multiple Table - Multiple EntitySet scenario

Service cap_fe_lr_table_views_service” proivides following data set: Orders, Order Items, Order Types, Customers, Products, ItemTotals, CustomerTotals.

Please be aware that in this blog post, my emphasis is on illustrating the functionality of presenting tables in various configurations. It's worth noting that the service utilized for demonstration purposes may not be flawless and is solely used to explain the functionalities.

Detailed Explanation:

Before diving into various combination of configurations to achieve different visualizations, it is crucial to understand following couple of things:

  1. Relevant Annotations
  2. Table Modes

1. Relevant Annotations:

  • SelectionVariant – With the use of this annotation, we can provide default filters that are sent as queries for the annotated entity set. Essentially, this annotation helps in determining which data should be displayed in a view.
  • PresentationVariant – With the use of this annotation, we can provide how the result/data is displayed e.g. as a Table or Chart, how the table is sorted or grouped etc.
  • SelectionPresentationVariant – Combines Selection Variant and PresentationVariant.

In addition to annotations mentioned above, some configurations are also added in Application Descriptor File (manifest.json).


Note: @UI.LineItem and @UI.Chart annotation are used to bring up tables and charts respectively in SAP Fiori Elements.

2.Table Modes:

  • Single Table Mode: UI contains a single table instance and to switch between views, a segmented button is used.
  • Multiple Table Mode: UI contains multiple table instance and a Tab bar is used to switch between views.

Now Let’s look at some examples to understand a bit more.

Scenario 1: Single Table - Segmented View

In this scenario, single insatnce of table is used to offer a segmented view. For example, within a segmented view of sales orders, one view displays return orders, while another view showcases other types of orders.


To achieve above functionality following anotations and configirations are added:

/app/ui01/annotations.cds
annotate service.Orders with @(
    UI.SelectionVariant #SelVarRO: {
        $Type        : 'UI.SelectionVariantType',
        Text         : 'Return Orders',
        SelectOptions: [{
            $Type       : 'UI.SelectOptionType',
            PropertyName: type.ID,
            Ranges      : [{
                $Type : 'UI.SelectionRangeType',
                Sign  : #I,
                Option: #EQ,
                Low   : 'RO'
            }]
        }]
    },
    UI.SelectionVariant #SelVarSO: {
        $Type        : 'UI.SelectionVariantType',
        Text         : 'Sales Orders',
        SelectOptions: [{
            $Type       : 'UI.SelectOptionType',
            PropertyName: type.ID,
            Ranges      : [{
                $Type : 'UI.SelectionRangeType',
                Sign  : #I,
                Option: #NE,
                Low   : 'RO'
            }]
        }]
    }
);
 /app/ui01/webapp/manifest.json
"@com.sap.vocabularies.UI.v1.LineItem": {
  "tableSettings": {
    "quickVariantSelection": {
      "hideTableTitle": false,
      "showCounts": true,
      "paths": [
        {"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#SelVarSO"},
        {"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#SelVarRO"}
      ]
    }
  }
}


Here we have defined two selection variants labeled as #SelVarRO and #SelVarSO using annotations. These variants incorporate select options that are essentially act as filters on the defined entityset. These are subsequently added to the table configuration under quickVariantSelection in the manifest.json file. Additionally, you have the option to specify whether each view should indicate the number of rows it displays by setting showCounts to true.
Note-1: multiple filters defined as ranges can be provided in select option.
Note-2: If you define more than three selection variants, a drop down menu will be displayed instead of segmented button.

Scenario 2: Multiple Table - Tab View

In this scenario, multiple instances of the table are employed to provide a tabbed view. If there are n views, then n instances of the table are utilized. However, only one view is rendered at a time. An icon tab is presented to facilitate switching between views. For instance, in a tab view of sales orders, one view shows return orders, while another view highlights other types of orders.


To achieve above functionality following anotations and configirations are added:

/app/ui02/annotations.cds
annotate service.Orders with @(
    UI.SelectionPresentationVariant #SelPreVarRO: {
        $Type              : 'UI.SelectionPresentationVariantType',
        Text               : 'Return Orders',
        SelectionVariant   : {
            $Type        : 'UI.SelectionVariantType',
            Text         : 'Return Orders',
            SelectOptions: [{
                $Type       : 'UI.SelectOptionType',
                PropertyName: type.ID,
                Ranges      : [{
                    $Type : 'UI.SelectionRangeType',
                    Sign  : #I,
                    Option: #EQ,
                    Low   : 'RO'
                }]
            }]
        },
        PresentationVariant: {
            $Type         : 'UI.PresentationVariantType',
            Visualizations: ['@UI.LineItem#ROrders'],
            SortOrder     : [{
                $Type     : 'Common.SortOrderType',
                Property  : ID,
                Descending: false
            }],
            GroupBy       : [customer_ID]
        }
    },
    UI.SelectionPresentationVariant #SelPreVarSO: {
        $Type              : 'UI.SelectionPresentationVariantType',
        Text               : 'Sales Orders',
        SelectionVariant   : {
            $Type        : 'UI.SelectionVariantType',
            Text         : 'Return Orders',
            SelectOptions: [{
                $Type       : 'UI.SelectOptionType',
                PropertyName: type.ID,
                Ranges      : [{
                    $Type : 'UI.SelectionRangeType',
                    Sign  : #I,
                    Option: #NE,
                    Low   : 'RO'
                }]
            }]
        },
        PresentationVariant: {
            $Type         : 'UI.PresentationVariantType',
            Visualizations: ['@UI.LineItem#SOrders'],
            SortOrder     : [{
                $Type     : 'Common.SortOrderType',
                Property  : totalamount,
                Descending: false
            }],
            GroupBy       : [type_ID]
        }
    }
);
 /app/ui02/webapp/manifest.json
"views": {
  "paths": [
    {
      "key": "tab0",
      "annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SelPreVarSO"
    },
    {
      "key": "tab1",
      "annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SelPreVarRO"
    }
  ],
  "showCounts": true
}


Here we have used two selection presentation variants labeled as #SelPreVarRO and #SelPreVarSO using annotations. Each of these variants incorporates selection variant and presentation variant. Each presentation variant includes references to visualizations @UI.LineItem labeled with #SOrders and #ROrders, along with specified sort order and group-by settings. These selection presentation variants are subsequently added to the table configuration under views in the manifest.json file.

Scenario 3: Multiple Table & Chart - Tab View

This scenario is simillar to previous scenario. In this scenario, one table and one chart is displayed in a tabbed view.


To achieve above functionality following anotations and configirations are added:

/app/ui03/annotations.cds
annotate service.Orders with @(
  UI.SelectionPresentationVariant #SPVSOTable  : {
        $Type              : 'UI.SelectionPresentationVariantType',
        Text               : 'Sales Orders (Table)',
        SelectionVariant   : {
            $Type        : 'UI.SelectionVariantType',
            Text         : 'Sales Orders (Table)',
            SelectOptions: [{
                $Type       : 'UI.SelectOptionType',
                PropertyName: type_ID,
                Ranges      : [{
                    $Type : 'UI.SelectionRangeType',
                    Sign  : #I,
                    Option: #NE,
                    Low   : 'RO'
                } ],
            } ],
        },
        PresentationVariant: {
            $Type         : 'UI.PresentationVariantType',
            Visualizations: ['@UI.LineItem#SOTable']
        }
  },
  UI.SelectionPresentationVariant #SPVROChart  : {
        $Type              : 'UI.SelectionPresentationVariantType',
        Text               : 'Return Orders (Chart)',
        SelectionVariant   : {
            $Type        : 'UI.SelectionVariantType',
            Text         : 'Sales Orders (Table)',
            SelectOptions: [{
                $Type       : 'UI.SelectOptionType',
                PropertyName: type_ID,
                Ranges      : [{
                    $Type : 'UI.SelectionRangeType',
                    Sign  : #I,
                    Option: #EQ,
                    Low   : 'RO'
                } ]
            } ]
        },
        PresentationVariant: {
            $Type         : 'UI.PresentationVariantType',
            Visualizations: ['@UI.Chart#ROChart']
        }
  }
);

annotate service.Orders with @(
  UI.LineItem #SOTable : [
    {
        $Type: 'UI.DataField',
        Label: 'ID',
        Value: ID
    },
    {
        $Type: 'UI.DataField',
        Label: 'Description',
        Value: descr
    },
    {
        $Type: 'UI.DataField',
        Label: 'Order Type',
        Value: type_ID
    },
    {
        $Type: 'UI.DataField',
        Label: 'Total Amount',
        Value: totalamount
    },
    {
        $Type: 'UI.DataField',
        Label: 'Customer',
        Value: customer_ID
    }
  ]
);

annotate service.Orders with @(
  Analytics.AggregatedProperty #totalamount_sum: {
    $Type : 'Analytics.AggregatedPropertyType',
    Name : 'totalamount_sum',
    AggregatableProperty: totalamount,
    AggregationMethod : 'sum',
    ![@Common.Label] : 'totalamount (Sum)',
  },
  UI.Chart #ROChart : {
    $Type : 'UI.ChartDefinitionType',
    Title : 'Return Orders by Customers',
    ChartType : #Bar,
    Dimensions : [customer_ID, ],
    DimensionAttributes: [{
      $Type    : 'UI.ChartDimensionAttributeType',
      Dimension: customer_ID,
      Role     : #Category
    }],
    DynamicMeasures : [
      '@Analytics.AggregatedProperty#totalamount_sum'
    ]
  }
);
 /app/ui03/webapp/manifest.json
"views": { "paths": [
  {
    "key": "tab0",
    "annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SPVSOTable"
  },
  {
    "key": "tab1",
    "annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SPVROChart"
  }
  ],
  "showCounts": true
}


Here one sepection presentation variant contains a chart visualization as shown above. Rest of the settings remain same.

Scenario 4: Multiple Table - Tab & Segmented View

In this scenario, we combine scenario 1 and 2, incorporating multiple tables within a tabbed view, and one of the views includes a segmented view within itself.

 

/app/ui04/annotations.cds
Similar to the annotations explained earlier, two selection presentation variants labeled as #SPVSO and #SPVRO are defined which referrs to two tables with labels #SO and #RO respectively. Additionally, there are three selection variants defined with labels #SVSS, #SVCS, #SVRS.
 /app/ui04/webapp/manifest.json
"views": {
  "paths": [
    {
      "key": "tab0",
      "annotationPath":"com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SPVSO"
    },
    {
      "key": "tab1",
      "annotationPath":"com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SPVRO"
    }
  ],
  "showCounts": true
},
"controlConfiguration": {
  "@com.sap.vocabularies.UI.v1.LineItem#SO": { "tableSettings": {
    "quickVariantSelection": {
      "showCounts": true,
      "paths": [
        {
          "annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#SVSS"
        },
        {
          "annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#SVCS"
        },
        {
          "annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#SVRS"
        }
      ]
    }
  } }
}


Annotations are applied in same way as previous scenario. The only difference is in configurations added in manifest.json. Selection presentation variants are added in views and selection variants are added in quickVariantSelection. However, quickVariantSelection is added under the table configuration labelled as "@com.sap.vocabularies.UI.v1.LineItem#SO".

Scenario 5: Multiple Table - Multiple EntitySet

In this final scenario, all the previously mentioned scenarios are combined. Furthermore, different datasets are showcased. For instance, the first tab view displays a list of orders, the second one presents the total orders by item, and the last one exhibits order totals by customers.


To achieve above functionality following anotations and configirations are added:

/app/ui05/annotations.cds

 /app/ui05/webapp/manifest.json


Annotations are applied in the same manner as previously demonstrated. However, they are defined for different entity sets such as Orders, ItemTotals, and CustomerTotals. Additionally, configurations are incorporated in manifest.json. Since selection presentation variants are relevant to different datasets, the entitySet property must be specified for each variant in manifest.json (as highlighted in red).

Conclusion:

In this blog post, we have explored how various annotations and configurations can be utilized to depict diverse datasets through multiple views in a List Report.

Together, the Cloud Application Programming Model and Fiori Elements improve developer experience while also boosting productivity and accelerating the development of enterprise-ready applications.

More information about Fiori Elements with cloud application programming model can be found here. You can follow my profile to get notification of the next blog post on CAP or Fiori Elements. Please feel free to provide any feedback you have in the comments section below and ask your questions about the topic in sap community using this link.

6 Comments