Skip to Content
Technical Articles
Author's profile photo Mahesh Palavalli

MyInbox UI generation using CDS views and UI.facet annotation

This blogpost content has been removed as this is not officially supported by SAP :(.

I will update this when it is officially supported.

Assigned Tags

      46 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Nabheet Madan
      Nabheet Madan

      Super blog your this blog and the one referred enhanced my understanding of the structure thanks. Annotations are being used in the big way whether it is ABAP Programming model for Fiori or CAPM.

       

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Thanks for the feedback Nabheet Madan !!  CDS and annotations are sure playing a major role.. in the UI5 it's the XML templating, which is used to generate the UI dynamically.. I think i will start digging that topic and maybe will write a blog as well 🙂

      Author's profile photo Nabheet Madan
      Nabheet Madan

      yes that will be great!

      Author's profile photo Ragini Upadhyay
      Ragini Upadhyay

      Hey Mahesh

      Excellent blog!! Thanks for sharing knowledge on UI facets...really helps!!!

      Thanks,

      Ragini

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Thanks Ragini!!

      Author's profile photo Pawan Kalyan
      Pawan Kalyan

      Excellent Blog...!!!  I very much liked the way you presented it too...

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Thanks Pawan 🙂

      Author's profile photo Krishna Kishor Kammaje
      Krishna Kishor Kammaje

      Great blog Mahesh. This will be a very good reference. Wanted to share my experience here quick.

      I had done this sometime back but on a non-HANA lower than 740 NW system. So went for a regular OData service (not CDS based). I created all my annotations in an XML file, uploaded it as a BSP project in GW system so that I have a URL to access the annotation file (to mention in the SWFIVISU). Another use case to do this way is in a case where you already have an OData service and you just want to reuse it for My-Inbox with annotations.

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Thanks Krishna Kishor Kammaje

      I never thought of this approach, cool way to do this 🙂  I will include your comment in the blog 🙂

      BTW any reason why you have not extended the MPC_EXT class to provide the metadata annotations? (The only reason I think of is the vocabulary annotations are not available, please correct me if I am wrong)

      BR,

      Mahesh

      Author's profile photo Krishna Kishor Kammaje
      Krishna Kishor Kammaje

      That's right. Annotations which you can add using MPC_EXT are limited.

      Author's profile photo Edson Bravo Zapata
      Edson Bravo Zapata

      Hi Mahesh

      I read your blog, and I found it very informative but confusing, I still have many doubts, for example, how do I start an annotation or how do I configure it and which directly affects my inbox, in the view I need?

      Also, does the fact that some things take them without much explanation cause me conflict, I do not know if it would be possible some indication or some brief explanation of how it was that it was possible to reach that?

      I hope not to cause a lot of hassle, since in this of the extensions of standard apps on Fiori, I am a novice, reason why I am very lost.

      Regards
      Edson.

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Hi Edson Bravo Zapata

      Actually this blog is aimed for the people who have a good understanding of the ABAP Programming model for Fiori. I am not giving much information on facets and all as it is a common term for those who has already created the List report template based apps(As already mentioned in the blog).

      I would strongly recommend you to go through all the blogs about the CDS View annotations, Fiori Elements, List report template based apps etc.., then it will be very easy for you to understand this.

      https://blogs.sap.com/2017/04/21/how-to-add-annotations-to-an-odata-service-using-code-based-implementation/

      https://wiki.scn.sap.com/wiki/display/Fiori/Fiori+elements

      Many blogs are there just a search away.. If you get any questions you can always create a question in the community 🙂

      BR,
      Mahesh

      Author's profile photo Edson Bravo Zapata
      Edson Bravo Zapata

      Hi Mahesh

      As I said, I'm new to extending Fiori's applications, so I did not know where to start looking or what to look for to start extending.

      Thanks for your response, now I have a hint how to start.

      Regards

      Edson.

      Author's profile photo Dhiraj Kumar Barnwal
      Dhiraj Kumar Barnwal

      Hi Mahesh,

       

      Nice blog…! Thanks for sharing.

      I have gone through the blog and took the reference of @UI.facet, But I am not getting correct output(In landing page getting the label for table column, but when navigating to Object page that time not getting label which I have written in @Ui.identification.

      I have attached the CDS view code ,metadata extension file and output screen.

      Please could you check if I am missing anything.

      Thanks in advance.

       

      Thanks & Regards,

      Dhiraj

       

       

       

      Header Consumption View(Employee)
      --------------------------------------
      @AbapCatalog.sqlViewName: 'ZCEMPLOYEE'
      @AbapCatalog.compiler.compareFilter: true
      @AbapCatalog.preserveKey: true
      @AccessControl.authorizationCheck: #NOT_REQUIRED
      @EndUserText.label: 'Employee Details'
      @VDM: {
          viewType: #CONSUMPTION
      }
      @ObjectModel: {
          usageType:{
              dataClass: #TRANSACTIONAL,
              serviceQuality: #C,
              sizeCategory: #L
          },
          transactionalProcessingDelegated: true,
          compositionRoot: true,
          semanticKey: ['EMPLOYEEID'],
          draftEnabled: true,
          createEnabled: true,
          updateEnabled : true,
          deleteEnabled : true
      }
      
      @Metadata.allowExtensions : true
      
      define view ZC_EMPLOYEE as select from ZTP_Employee as _empInfo
      association[0..*] to ZC_SKILLS as _skillInfo on _skillInfo.EmployeeID = $projection.EMPLOYEEID
      {
      //     @UI: {        
      //            lineItem: [{position: 10, label:'Employee ID' }],
      //            identification: [{position:10 }]            
      //        }
          @ObjectModel.readOnly : true
          key _empInfo.EMPLOYEEID,
          
           
      //        @UI: {        
      //            lineItem: [{position: 20, label: 'First Name' }],
      //            identification: [{position:20, label: 'First Name' }] 
      //        } 
          _empInfo.EMPLOYEENAME,
           
      //      @UI: {        
      //            lineItem: [{position: 30, label: 'Last Name' }],
      //            identification: [{position:30, label: 'Last Name' }]
      //        }
          _empInfo.EMPNAME,
          
      //     @UI: {        
      //            lineItem: [{position: 40, label: 'Mobile'}],
      //            identification: [{position:40, label: 'Mobile' }]            
      //        } 
          _empInfo.MOBILE,
           
      //     @UI: {        
      //            lineItem: [{position: 50, label:'Age'}],
      //            identification: [{position:50, label: 'Age' }]            
      //        }
          _empInfo.AGE,
         @ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
         _skillInfo
      }
      
      
      --------------
      Line Item (ZC_SKILL View)
      @AbapCatalog.sqlViewName: 'ZCSKILLS'
      @AbapCatalog.compiler.compareFilter: true
      @AbapCatalog.preserveKey: true
      @AccessControl.authorizationCheck: #CHECK
      @EndUserText.label: 'Skills Details - Consumption'
      @VDM: {
          viewType : #CONSUMPTION
      }
      @ObjectModel:{
          transactionalProcessingDelegated: true,
          semanticKey: ['EmployeeID','SkillID'],
          createEnabled : true,
          updateEnabled : true,
          deleteEnabled : true
      }   
      
      //@Metadata.allowExtensions: true
      
      define view ZC_SKILLS as select from ZT_SKILLS as _skillInfo
      association[1..1] to ZC_EMPLOYEE as _empInfo on _empInfo.EMPLOYEEID = $projection.EmployeeID
      association[0..1] to ZP_SKLCODE as _skillCodeValueHelp on _skillCodeValueHelp.skillcode = $projection.SKillCode
       {
      
           @ObjectModel.readOnly: true
          key _skillInfo.EmployeeID, 
          
          @UI: {
              lineItem: {position:20, label: 'SkillID'},
              identification : {position: 20, label: 'SkillID'}
          }
          @ObjectModel.readOnly: true
          key _skillInfo.SkillID, 
          
          @UI: {
              lineItem: [{position: 30, label: 'Skill Code'}],
              identification: [{position: 30, label: 'Skill Code'}]
          }
          @Consumption.valueHelp: '_skillCodeValueHelp'
          _skillInfo.SKillCode, 
              
          _skillInfo.Experience, 
          
          _skillInfo.Description,
          
          @ObjectModel.association.type: [#TO_COMPOSITION_ROOT,#TO_COMPOSITION_PARENT]
          _empInfo,
          _skillCodeValueHelp
      }
      
      ----------------------------
      Metadata Extension Code
      @Metadata.layer: #CORE
      annotate view ZC_EMPLOYEE
      with 
      {
         @UI.facet: [  {
                  label : 'General Information',
                  id : 'GeneralInformation',
                  isSummary : true,
                  type : #COLLECTION
              },
              {
                  label: 'Basic Data',
                  id : 'BasicData',
                  parentId : 'GeneralInformation',
                  type : #FIELDGROUP_REFERENCE,
                  targetQualifier : 'one'
              },
              {
                  label: 'Skills Details',
                  id  : 'EMPSKILL',
                  type : #LINEITEM_REFERENCE,
                  targetElement: '_skillInfo'
              }]
             
              @UI.fieldGroup : [{
                  qualifier : 'one',
                  position : 10
              }] 
              @UI.lineItem: [{position: 10, label: 'Employee ID', importance: #HIGH }]
              @UI.identification : [{position: 10, label: 'Employee ID'}]
              EMPLOYEEID;
              
              @UI.fieldGroup : [{
                  qualifier : 'one',
                  position : 20
              }]
              @UI.lineItem: [{position: 20, label: 'First Name', importance: #HIGH }]
              @UI.identification : [{position: 20,  label: 'First Name'}]
              EMPLOYEENAME;
              
              @UI.fieldGroup : [{
                  qualifier : 'one',
                  position : 30
              }]
              @UI.lineItem: [{position: 30, label: 'Last Name', importance: #HIGH }]
              @UI.identification : [{position: 30, label: 'Last Name'}]
              EMPNAME;
              
              @UI.fieldGroup : [{
                  qualifier : 'one',
                  position : 40
              }]
              @UI.lineItem: [{position: 40, label: 'Mobile', importance: #HIGH }]
              @UI.identification : [{position: 40, label: 'Mobile'}]
              MOBILE;
              
              @UI.fieldGroup : [{
                  qualifier : 'one',
                  position : 50
              }]
              @UI.lineItem: [{position: 50, label: 'Age', importance: #HIGH}]
              @UI.identification : [{position: 50, label: 'Age'}]
              AGE;
              
      }
      
      
      

       

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      You are welcome 🙂

      It is not picking from the identification as you are showing the UI using the field group and so the label should be maintained in the field group else it will pick from the table field.

        @UI.fieldGroup : [{
                  qualifier : 'one',
                  position : 50,
                  label:'Test Label'
              }]

      BR,

      Mahesh

      Author's profile photo Dhiraj Kumar Barnwal
      Dhiraj Kumar Barnwal

      Thanks! Its working.

       

      I want to hide the facet based on user name. I have added the hiden: #(Enable) in facet.

      {
      label: 'Skills Details',
      id : 'EMPSKILL',
      type : #LINEITEM_REFERENCE,
      targetElement: '_skillInfo',
      //hidden: true
      hidden: #(EMPSKILLFacetIsHidden)
      }

       

      Please could you suggest how to control the facet.

       

      Regards,

      Dhiraj

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Hi Dhiraj Kumar Barnwal

      Sorry.. I've never tried this scenario.. You can create a question for this in the community, surely someone might help you.. Meanwhile If i get time, I will try this out.

      BR,

      Mahesh

      Author's profile photo K Shiva
      K Shiva

      Hey Mahesh,

       

      Excellent blog!! Very well portrayed and is really useful!!

       

      Regards,

      Shiva Shankar

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

       

      ?  Thanks for the feedback Shiva!!

      Author's profile photo Alex Caruntu
      Alex Caruntu

      Hi Mahesh,

      I`m trying to create a transactional app with a header with 2 children (one item table and one text table) only by using annotations like: (@ObjectModel.association.type: [#TO_COMPOSITION_CHILD] / [#TO_COMPOSITION_PARENT, #TO_COMPOSITION_ROOT]) and @UI.facet options.

      After creating the project in WebIDE and choosing my consumption view + to_item navigation I get the following behavior:

      The item (Handle Part Type) has the navigation to the detail screen + the insert functionality but my Text table, so the second child, doesn`t have it. By any chance do you know if this is a normal behavior? Did I miss some annotations in order to enable this insert and navigation for my Text Table?

      Thanks in advance!

      Alex

       

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      can you check if your interface view(BO view) for the texts entity has the create enabled annotation defined? Also check in the BOPF BO for that entity if the create enabled check box is checked.

      Author's profile photo Alex Caruntu
      Alex Caruntu

      Hi Mahesh,

      My text interface view has the createEnable set to true.

      Also my BOPF -> Text entity has the create enabled.

      Also I`ve checked and generate my bopf and deleted and re-created my fiori app using the same OData.

      In one testing scenario I`ve created the project in WebIDE with OData collection YFIORI_FB_C_300 and OData Navigation: to_Htext (my text table). In result I got my navigation from header to item -> text table working fine, also with insert functionality but my other child C_310 was missing the "insert" functionality. That is why I`ve thought I miss some annotation to activate the third facet... Or maybe is not possible?

      Thanks

      Alex

       

       

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      This looks weird, as far as i know it should display the create button without any additional annotations to be passed.. just for testing, can you remove the 2 navigation and only use the c_310 navigation only and see if it's working or not(i know  it is dumb 😀 but let's try that)

      Author's profile photo Alex Caruntu
      Alex Caruntu

      Hi Mahesh,

      Yes, I agree, it looks weird. 🙂

      I have tried the following:

      1. Header C_300 with navigation towards C_310 --> this works
      2. Header C_300 with navigation towards C_300T --> this works also
      3. Header C_300 with navigation C_300T + facet added from MDE for C_310 --> CRUD operations for C_300T works but no insert functionality for C_310 ..
      4. Header C_300 with no navigation selected in the WebIDE, only annotations regarding ([#TO_COMPOSITION_CHILD] / [#TO_COMPOSITION_PARENT, #TO_COMPOSITION_ROOT] + adding both facets in MDE file) --> result: both children are visible with no "insert" functionality ....

      I`m pretty confused .. :))

      Regards

      Alex

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Is it due to the facets being from MDE?

      Author's profile photo Alex Caruntu
      Alex Caruntu

      I`ve managed to make it work!! 🙂

      From what I`ve learned is that when creating the project in WebIDE and selecting the OData with its navigation, example to_Item, then this will generate coding only for that particular navigation.

      In my case I have 2 children: to_Item and to_HText and only to_Item navigation was enabled.

      What I`ve did to enable the to_HText navigation and CRUD operations, beside the coding related to UI.facet from MDE file:

      • In the ‘manifest.json’ file of the WebIDE project, add the missing navigation for the Text entity.
      • In the ‘annotation.xml’ file of the WebIDE project add annotations UI.facets for the Text entity.

      As result:

      Thanks for your replies Mahesh!

      Alex

       

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Awesome Alex Caruntu

      I don't know why it din't cross my mind.. Actually for enabling the navigation to the sub page we need that config in manifest.json and yeah if you try to add an item, it will obviously needs to go to the second page(so that config is mandatory).
      Br,

      Mahesh

      Author's profile photo Jinin Thomas
      Jinin Thomas

      Hello Mahesh and Alex,

      I have the same issue , my third facet creation button is not displaying , everything else is working fine , I did all changes that ALEX mentioned but still not displaying ,

      I edited manifest.json and annotation file.

      First change was not clear for me what do you mean by this

      enable the  to_HText navigation and CRUD operations, beside the coding related to UI.facet from MDE file

       

      Where i can find this MDE file, how to edit this ?

      can you please help me on this i am new to this UI world

       

      Thank you so much

       

       

      Author's profile photo IDMIR LEVI DE LA CRUZ CLEMENTE
      IDMIR LEVI DE LA CRUZ CLEMENTE
      Hello Alex, could you solve ??, I also have the same problem.
       
      Author's profile photo Mehmet Ozkafa
      Mehmet Ozkafa

      Hello Mahesh,
      First of all, thank you for this great blog.
      We have implemented My Inbox 2.0 on Hana 1610 SP06 and Approve Purchase Order and Approve Requisition works fine. But we want to add a custom field to both approving detail views. I read Ragini blog but my mind confuse. Which approach is the best practice for extending standard annotation? Could you share best practice tutorial or any official document about the modifying or extending of standard annotation file, especially adding new field? thanks

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Hi Mehmet Ozkafa,

      Thank you for the positive feedback 🙂 You can follow the Ragini approach.. This blog is for a new solution which has to be designed from the ground up(new cds odata workflow and stuff).
      For your solution, you might have to extend the CDS view and add annoations to it as ragini did.
      BR,
      Mahesh
      Author's profile photo Ayham Tanbari
      Ayham Tanbari

      Hello Mahesh,

       

      Thanks for this blog post. Actually, I'm new to ABAP  programming model. I created a consumption view and consume it in Web  IDE using list report template.

      Everything is fine but I had a problem displaying the facets.

       

      I defined the required annotations in the same way as you. Everything looks fine and right, but I don't get any section displayed on the Object page even the section title:

      Here is my code:

      ....
      @UI.facet: [
      {
      label: ‘General Information’,
      id:’GeneralInformation’,
      isSummary: true,
      type: #COLLECTION,
      position: 10
      },
      {
      label: ‘Customer Info’,
      id: ‘CustomerInfo’,
      parentId: ‘GeneralInformation’,
      type: #FIELDGROUP_REFERENCE,
      position: 20,
      targetQualifier: ‘Company’
      }
      ]
      key Item.SalesOrder,

      key Item.SalesOrderItem as ItemPosition,

      @UI.fieldGroup: [{
      qualifier: ‘Company’,
      position: 10
      }]
      @UI.selectionField.position: 20
      @Search: {defaultSearchElement: true, fuzzinessThreshold: 0.7}

      @UI.lineItem.position: 20
      Item._SalesOrder._Customer.CompanyName as CompanyName,

      .....

      Do you think, this code should be enough to display a section or I missed something.

       

      I checked different blog posts, and in all of them, we just need like the above definition. in my app, I don't see anything displayed even the title of the section.

      Thanks for your help,

      Ayham

      Author's profile photo Ayham Tanbari
      Ayham Tanbari

      I attached a picture of the updated code.

      @UI.identification and @UI.fieldGroup are defined also in the code:

       

      @UI.identification.position: 10
      Item._Supplier.Country,

       

      @UI.identification.position: 20
      Item._Supplier.CityName,

      @UI.fieldGroup: { qualifier: ‘Product’, position: 10}
      Item.Supplier,

      @UI.fieldGroup: { qualifier: ‘Product’, position: 20}
      Item.ProductType,

      @UI.fieldGroup: { qualifier: ‘Product’, position: 30}
      Item.ProductCategory,

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Maybe when you generated the List report template app, it will auto generate the facet annotations, try removing them in the fiori app and see once/

      Author's profile photo Ayham Tanbari
      Ayham Tanbari

      Hello Mahesh,

       

      Thanks very much. It works perfectly.

      The Web IDE generates default facets which overwrite my UI.facet.

       

      Again Thanks very much for your help and your great Blog Post

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Thanks Ayham 🙂

      Author's profile photo Sarbjeet Singh
      Sarbjeet Singh

      Thanks a lot for sharing this Mahesh,

      Really useful.  Saved a lot of time.

       

      Regards,

      Sarbjeet Singh

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Thanks Sarbjeet for the feedback!!..

      Author's profile photo Suwandi Cahyadi
      Suwandi Cahyadi

      Hi,

      Thank you for the nice blog.

      I want to ask for the annotation, how do you get the name the annotation name ZC_CARRIER_CDS_VAN to be maintained in SWFVISU QUERY_PARAM01?

      Thank you

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Hi Suwandi Cahyadi, really appreciate the feedback.. Thank you so much 🙂

      THe annotation service name can be found in the /n/Iwfnd/mant_service.. for there you can navigate to annotation service by clicking some button with will take you to DPC classes and stuff,, from there a button at the bottom i think.. Don;t remember exacly..

      BR,

      Mahesh

       

      Author's profile photo Sreehari V Pillai
      Sreehari V Pillai

      Awesome post Mahesh.

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      🙂 Thanks for the feedback Sreehari V Pillai

      Author's profile photo p surabhi
      p surabhi

      Hi Mahesh,

      Did you try adding a new tab using annotations?

      Thanks & BR, P

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Sorry, just saw ur comment. I don't think we can add a new tab, and it's been sometime since I checked it, so no idea if it is possible now. 🙁 But you can always add a new section, kinda looks like a tab.

      Author's profile photo Cristiano Marques
      Cristiano Marques

      Mahesh Palavalli great blog. I have a question, from where the CARRIER_ID in entity=/ZC_Carrier(‘{&CARRIER_ID&}’) came from? because in your cds this is not the field name.

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Thanks 🙂

      That variable is part of SAP Workflow container