In Fiori Elements – Develop a List Report Basic Approach we looked at the simplest way to create a List Report using an OData service based on a purpose built CDS view with all of the annotations pre-set.  In this blog we look at alternate approach when you have an OData service without any pre-set annotations.  You can also use this approach to override or supplement pre-set annotations.

Find other Fiori Elements blogs on the Fiori Elements wiki

What are annotations?

In my first blog I described them as … “comments on the OData service that provides the data”.

The official OData site gives them a formal definition as:

Metadata annotations can be used to define additional characteristics or capabilities of a metadata element, such as a service, entity type, property, function, action or parameter.”

I find it more helpful to think of them as adding formalised semantic meaning to OData entities. In other words the annotations describe the purpose and intent of the OData entity and its attributes in a way that can be used directly by programs (and, happily, humans).

As mentioned in previous blogs, annotations are an optional part of OData.  The available annotations are described using an OData vocabulary.  For example, SAP has a vocabulary of all annotations that can be used in ABAP CDS views.  Some of these annotations are UI annotations that we can use to build our List Report.  Other annotations have other purposes such as @OData.Publish:true which exposes a CDS view as an OData Service. When it comes to UI Annotations, there are quite a lot of them… so we’ll start with a focus on the essentials for List Reports.

Creating a Fiori Element List Report with Annotations XML

Before we start, it’s worth noting that while its UI annotations let us control most of the List Report, not everything can be controlled by UI annotations. Certain features depend on what the OData Service itself provides, e.g. we can only provide a keyword search in the List Report Filter bar if the OData Service EntitySet contains the semantic marker sap:searchable=”true”. Features such as create, update, delete are provided in a similar way.

So how does using an annotations XML file change our process for creating a List Report which in Fiori  Elements – How to develop a List Report – Basic Approach as:

  1. Prepare the OData service
  2. Prepare the UI Annotations
  3. Create the Fiori App using the Fiori Elements List Report template

The pre-requisites are still the same, and the process itself is essentially the same, it’s just a slight change in the order of the steps:

  1. Prepare the OData service
  2. Create the Fiori App using the Fiori Elements List Report template
  3. Prepare the UI Annotations

So to show how this works, we’ll start with an OData Service without any UI annotations.  To demonstrate that this is really the only difference we will again use an OData Service based on a CDS view, although as mentioned in my previous blog, CDS views are not a pre-requisites – just very easy to use.

This time our OData Service is similar to our previous example but without any UI annotations and looks like this:

Creating the Fiori App in the HCP Web IDE using the Fiori Elements List Report wizard works exactly the same way. The only difference is which service and entity we select for the report. Now if you are using a SAP system that supports annotations it will still show you an annotation file, it’s just that the file will be generated with a  very basic XML structure.

Because there are no annotations yet, if you run the Component.js file of your app it will look something like this:

Working with the Annotations XML file

To work with our local annotations file we first need to check we have one. If you have used the wizard then it should exist already, but not everyone has access to HCP Web IDE or Personal Web IDE, so let’s review again where this lives in the recommended SAPUI5 app structure.

In our app we should see a folder called “annotations”. This should be a sub-folder of “webapp”.  If not we can always create one, e.g. using the context menu of folder “webapp” and selecting New > Folder.

Next we check there is a file called annotations.xml in our project’s annotations folder. If not we can create one using the context menu of folder “annotations” and selecting New > Annotation File.

Tip: It’s important to use the New > Annotation file wizard, and not just create the file using New > File.  The Annotation file wizard will not only create an annotations xml file, it will fill it with the basic edmx tags needed to start annotating. This is an example of an annotations.xml file generated this way:

The annotation file wizard will also update the manifest.json file to make sure our app:

  1. Knows where the annotation file sits in the project hierarchy and exactly what the file is called
  2. Knows where to find text resources (i18n.properties) related to your annotations file
  3. Links the OData Service to the related annotation xml file

As a reminder, we looked at the manifest.json file and its contents in the Fiori  Elements – How to develop a List Report – Basic Approach blog.

Tip: The annotations file doesn’t need to be called annotations.xml – although it does need to be a XML file.  If we use a different file name then we need to adjust the manifest.json file to match.

We can edit the annotations file directly using the Code Editor or, in the HCP Web IDE, we can use the Annotation Modeler tool. The Annotation Modeler uses a HCP Web IDE plugin so it is only available in the HCP Web IDE, so it’s always worth knowing the XML format itself.  In this blog for simplicity we will show the annotation modeler and related XML snippets.

You’ll find XML snippets for the different annotations in the SAPUI5 SDK in the section Developing Apps with SAP Fiori Elements > Annotations Relevant for List Reports and Object Pages, and Annotations Relevant for List Reports.

Annotations of the Fiori Element List Report

We can see in the SAPUI5 SDK that there are several UI annotations relevant to the List Report, but fortunately there are only 3 we need to create a basic List Report and these are:

  • UI.HeaderInfo – for the list table header
  • UI.LineItem – for the list table contents
  • UI.SelectionFields – for the filter bar fields

They relate to the List Report as follows:

Before we add any annotations our annotations.xml file looks like this in the annotation modeler.

In the Code Editor, if we’ve used the Fiori Elements List Report wizard, the relationship to our OData Service will already be added to the  tag of our annotations.xml file and will look like this:

All of our following annotations will need to be placed within a <Schema> tag for our OData Entity Set within the <edmx:DataServices> tag like this:

We use the + icon in the action columns to add extra annotations.

Adjusting the UI.HeaderInfo Annotations

The easiest annotation to add is the UI.HeaderInfo that adds the description and count to the table header of our List Report.  All we need to do is to enter the mandatory fields TypeName and TypeName Plural.  We can see in the Key Information column that these are immediately added to i18n property files.

It’s also mandatory to enter a value for the Title annotation which is a child of UI.HeaderInfo. This annotation will actually be used for the related Object Page which will we cover in a future blog.

In the code editor these annotations will look like this:

Adjusting the UI.LineItem Annotations

The UI.LineItem annotations denote which fields should be columns in our list report table.  There are different types of columns we can use – text, numbers, date/time, amount with currency, quantity with unit, urls, buttons, rating stars, progress bars, etc.  Once again we start with the simplest approach which is to use simple typed data fields, such as text and number fields.  For this we select the + action next in the UI.LineItem and choose the child annotation DataField.

In the DataField annotation we use the Value dropdown select the matching entity attribute and add a Label for the column header. The annotation modeler automatically adds the Labels to the @i18n properties file, or we can select an existing text from the file for our Label. We repeat this for as many columns as we want to add.

In the code editor these annotations will look like this:

Adjusting the UI.SelectionFields Annotations

We add the fields we want in our filter bar in the UI.SelectionFields annotations.  We use the SelectionFields dropdown to select attributes of our EntitySet. We use the Add Path option to add more filter fields.

In the code editor these annotations will look like this:

Running the app

Having saved all the UI annotations we have added, we can now run our App from the Component.js file. It should look like this:

Once again it’s a fully functioning production quality List Report app, complete with personalization settings (check out the gear wheel icon at the top right of the table) so users can adjust the filters, sort order, and groupings.

Basic vs. Alternate Approach

So which approach is preferred – basic approach or local annotations? Certainly if you have an environment capable of producing annotated CDS views and you are creating views explicitly for a given list report it makes sense to keep the annotations aligned against the CDS view. Otherwise local annotations work just fine.

In the next blog we’ll look at how we can make the list report even more useful.  We can control features such as the table type, single or multi-selection of rows, filter variant management, and default sort order.

We can also add some graphical visualizations to make the information in our report easier to understand such as thumbnail images, status icons, rating stars and progress bars.   These are techniques we’ll be able to reuse when we look at the Object Page in a future blog.

To report this post you need to login first.

15 Comments

You must be Logged on to comment or reply to a post.

    1. Jocelyn Dart Post author

      Yes! That’s Object Page… only holding off a little as that gets us into deeper architecture discussions which will make more sense once we’ve discussed codeless navigation options

      (0) 
  1. Helmut Tammen

    Really a great tutorial. Thank you for that. I already waited for something like this.

    When I implemented an application with my own OData service everything worked fine except displaying the texts from ResourceModel (i18n.properties). The texts are simply not available even though ResourceModel is defined in manifest.json, texts are available in i18n.properties and annotation definition looks ok (see here for screenshots).
    Any ideas?

    Thanks Helmut

    (0) 
    1. Jocelyn Dart Post author

      Hi Helmut
      ok so I’m guessing you created you project structure & manifest.json by hand? Brave!
      When we generate using the wizard the i18n model itself is referenced with thd model name @i18n in the manifest.json as well.  Do that & your references to @i18n properties should come through
      Let us know how you go
      Jocelyn

      (0) 
      1. Helmut Tammen

        Hi Jocelyn,
        I also used the wizard to create the app.
        It created the i18n model like this (without the @):

        “i18n”: {
        “type”: “sap.ui.model.resource.ResourceModel”,
        “uri”: “i18n/i18n.properties”
        },

        When I changed the model name to “@i18n” the texts were displayed. Already wondered about the strange i18n model name :-D.

        Thanks a lot
        Helmut

        (1) 
          1. Emanuel Affatati

            Thanks for the information.

            I added the model @i18n to the manifest.json file and it worked correctly.

            “models”: {
            “i18n”: {
            “type”: “sap.ui.model.resource.ResourceModel”,
            “uri”: “i18n/i18n.properties”
            },
            “@i18n”: {
            “type”: “sap.ui.model.resource.ResourceModel”,
            “uri”: “i18n/i18n.properties”
            },

             

            Best Regards,

            Emanuel

            (0) 
  2. Abhishek Kaushal

    Hi Jocelyn,

    This is an awesome post and really helpful.

    I want to ask is there something different to be done when creating the application using a local mock service(Mock service created using edmx file).

    I created the List Report application using template and my mock service. I then tried to create the local annotation by following your blog but was unable to do so using the Annotation Modeller wizard as it was not detecting my local service.I then manually added the schema of the service in code editor of the Annotation modeler and was able to create annotations.

    The manifest.json  file was also updated accordingly to pick the annotation file.

    But when I test the application using Mock data the annotation file is not picked up. I had to manually add the column in the application.

    Can you please suggest if there is something different to be done when creating application using local Mock service?

    This would be really helpful as many folks are working on Demo apps,using the local mock service,to approach the respective clients.

    Cheers!!

    (1) 
  3. Emanuel Affatati

    Excellent article Jocelyn.
    It was very useful for me to decide which approach to take between “Local UI Annotations” and “Service UI Annotations”.

    Thanks!
    Best Regards,

    Emanuel

    (1) 
  4. Holger Schäfer

    Thank you for the great intro Jocelyn,

    i am currently working on some CDS on S/4HANA 1610 SP0 and run into issues with aggreations and the List Report Viewer.

    After some investigation the List Report Template seems to always use an OData merge select of the used columns and also the columns defined as UI.LineItem.

    If i later change visible columns to aggregate only on one column and get the @Agregation SUM for netvalue, i will get a lot of rows, because the odata request selects always all ListItem columns even if they are not shown on UI Table?!?

    Is this by design or mayber a bug?

    My current solution is skip using ListItems and later on add them manually, but from my point of view this is a bug and should be handled in the fiori list report viewer app, because you will get the wrong results using default ListItem.

    For me the ListItem should only define the initial set of shown columns, but when i change them and store the new set as variant in the LREP, i would expect the correct results.

    Maybe you are also familar with this topic and knows if this is a bug or behaves by design (for a reason that i do not know 😉

    Regards Holger

    (0) 
  5. Bhoomika Jain

    Thanks for the post Jocelvn.

    I am trying to implement UI annotation for smart table – the requirement is to restrict the columns appearing in the table personalization button. This I am trying to do by setting sap:visible to true. But where I need to do this is not clear.

    In backend oData entity I could not find any property like sap:visible (unlike for updatable, creatable, etc.). Also in UI annotations, I could not find any option like visible (unlike headerInfo, LineItem, etc.).

    Could you please help me in the same please.

     

    Thanks,

    Bhoomika

    (0) 

Leave a Reply