Product Information
Annotating annotations in SAP Cloud Application Programming (CAP) with code completion
I’ve heard from several developers that specifying annotations is the most challenging part when developing applications based on the SAP Fiori elements framework. This is especially true if you have no tools support, as many of us felt trying to add annotations in .cds files of CAP (SAP Cloud Application Programming) projects. We recently introduced code completion for OData annotations in CAP, so even the trickiest things, such as applying annotations to an existing annotation or its part can be achieved with a few clicks.
In this blog post, I will show you how it works with a couple of examples.
Example 1: Annotating UI.DataField records to control table responsiveness
In this example, I have a table of safety incidents represented by the annotation “UI.LineItem”.
annotate service.SafetyIncidents with @UI.LineItem : [
{
$Type : 'UI.DataField',
Value : title,
},
{
$Type : 'UI.DataField',
Value : priority_code,
},
{
$Type : 'UI.DataField',
Value : category_code,
},
{
$Type : 'UI.DataField',
Value : incidentStatus_code,
},
];
On small screens, such as a typical smartphone, the first three columns keep their places by default, and all the other columns move to the second line. But, sometimes you want to show the important information in the right part of the table on large screens and still keep them distinctly visible on the small screens too. In this case, the columns in the middle should slide down to the second line: note the Priority column in the right screenshot below.
To implement this, I applied the annotation “UI.Importance” to UI.DataField records in my LineItem. So, I annotate the data fields for incident title, category and status with High importance, to keep them always distinctly visible. The only non-high value now moves to the second line, giving its space to the VIPs.
annotate service.SafetyIncidents with @UI.LineItem : [
{
$Type : 'UI.DataField',
Value : title,
![@UI.Importance] : #High,
},
{
$Type : 'UI.DataField',
Value : priority_code,
},
{
$Type : 'UI.DataField',
Value : category_code,
![@UI.Importance] : #High,
},
{
$Type : 'UI.DataField',
Value : incidentStatus_code,
![@UI.Importance] : #High,
},
];
Even if you forget the correct syntax for this annotation/value or do not have this example in front of you, use the code completion (CTRL+Space) next to the Value and select a suggestion from the list – it could be even faster than copying!
In this video, you can see it yourself:
Note: Alternatively, I could have annotated the priority_code record with the low importance rather than the 3 records with high, but with the real-life tables having much more than 4 columns it makes more sense to mark those that are more important and ignore the remaining ones.
Example 2: Annotating UI.LineItem to highlight table rows based on criticality
In this example, I would like to highlight the rows in my table based on the incident priority. Thus, priority would still be easily visible, even when the value appears in the second row.
According to the SAP UI5 documentation, I need to apply the annotation “UI.Criticality” to the whole Ui.LineItem annotation.
This is really tricky in cds syntax, even for experienced users: the LineItem annotation should be wrapped in curly brackets { } with $value and then annotated with UI.Criticality in ![ ] syntax. Finally, the value pointing to the entity element containing criticality information should be added:
annotate service.SafetyIncidents with @UI.LineItem : {
![@UI.Criticality] : priority.criticality,
$value: [
{
$Type : 'UI.DataField',
Value : title,
![@UI.Importance] : #High,
},
{
$Type : 'UI.DataField',
Value : priority_code,
},
{
$Type : 'UI.DataField',
Value : category_code,
![@UI.Importance] : #High,
},
{
$Type : 'UI.DataField',
Value : incidentStatus_code,
![@UI.Importance] : #High,
},
]
};
Thankfully, with code completion all this is achieved with just a few clicks: use CTRL+Space right before the collection brackets [] of the LineItem and choose UI.Criticality – all the wrapping and formatting will be done automatically. Now use the code completion again to select the value and you are done:
Try it out and provide feedback
You can try this out yourself in Visual Studio Code with SAP Cloud Platform core data services plug-in for Visual Studio Code (v 3.0.0 or higher) any time, as it is already enhanced with the @sap/ux-cds-odata-language-server-extension.
If you use SAP Business Application Studio, you can find it in the SAP Cloud Business Application dev space.
Once you try it, share your experience with OData annotation support in the comments: what works well, what requires improvement and what else you like to know about LSP features for OData annotations (code completion, diagnostics, etc).
More information on OData annotation support in CAP CDS
- SAP CAP documentation https://cap.clhttps://cap.cloud.sap/docs/advanced/fiorioud.sap/docs/guides/fiori
- SAP CAP release notes https://cap.cloud.sap/docs/releases/sep20#editing-odata-annotations
- My previous blog post introducing annotation LSP for CAP: https://blogs.sap.com/2020/10/14/maintaining-annotations-in-cap-cds-projects-becomes-easier-with-new-lsp-features/
Please note, the link to the documentation has been updated
Great!
Are there any plans to make the CAP open source or usable outside the SAP Cloud Platform (e.g. on premise with postgres)
thanks!
Martin
Hi,
wrt open sourcing CAP: yes, we would like to do it and ponder about it every now and then. Still no concrete plans yet, mainly due to the high load on the dev teams here.
For PostgreSQL, see the community works on it: https://blogs.sap.com/2020/08/20/postgresql-persistence-adapter-for-cap-node.js/
Regards, Christian
Hi Christian
thanks for the info!
It would be great if it will be open sourced. The CAP is a fantastic programming model.
We are a SAP Partner developing SaaS apps - currently in plain Spring / Spring Boot but we are thinking about switching to CAP / node.js
Regards,
Martin
Thanks so much! 🙂
Please note that SAP Cloud Platform core data services plug-in for Visual Studio Code is now renamed to SAP CDS Language Support but it still provides the annotation LSP features described in this post
Dear Mariana,
I have a self developed bookshop Odata Service Fiori Elements App in my Business Application Staudio, code can be seen here --> miyasuta/central-launchpad-cap (github.com)
Now I am trying to extend it via Fiori tools with an additional button (action). I also have been following your video : https://www.youtube.com/watch?v=p1f0Albi7eE
and documentation. Code is added to manifest and the extension controller file but the extensions won't show up in the app. Do you have any idea why this is not working? Do the extensions for instance only work for fiori standard apps with an OData Service from Backend etc.?
I would highly appreciate your answer:)
Best Regards
Max
Hello Max,
Could you please share more information on how you use Fiori tools to add an custom action? Where exactly are you adding this button?
In the attached github repo, I couldn't find your extension coding.
Best Regards,
Hitesh
Hi Hitesh Parmar
thanks for your response:)
this was the template that i used to implement the extension. All I added was the extension in my manifest file plus the extension controller ( both in the app/fiori/webapp folder)
I uploaded my extension project here:
SnarkWay/bookshopapp (github.com)
Do you find an issue?
Do the annotations from the service file overwrite my extension?
Best Regards
Max
Hello Max Schnürle ,
Thank you for updating your project.
I see that you are using OData V2 syntax for adding extensions which is incorrect as your application is based on OData V4.
Kindly refer to this documentation and use the syntax mentioned for OData V4 https://sapui5.hana.ondemand.com/#/topic/dd78acad2f164560ad6b0e24ed2cd8ee
I hope this will solve your issue.
Best Regards,
Hitesh
Hi Hitesh Parmar
thank you:) the OData v4 coding does not show up when doing this via the guided development approach. there only the v2 approach appears.
Nevertheless I updated my manifest(starting line 105) but the button still won't appear:
SnarkWay/bookshopapp (github.com)
I am not sure what the issue is there. I would be thankful if you could take a look.
Best Regards
Max
Hi Max Schnürle ,
Yes, you are correct, currently the Guided Development only supports OData V2. To see the guides only applicable to OData V4 you can group guides by OData Version.
We will take this up to improve the UX.
Group guides by OData version
Your coding looks correct to me. Let me take a deeper look into this.
Best Regards,
Hitesh
Hi Max Schnürle ,
I tried with your application and I can see that the button is rendered properly. I have a feeling that you overlooked the button in the UI. With your current coding in manfiest.json, global action will be added.
See here: https://sapui5.hana.ondemand.com/#/topic/7619517a92414e27b71f02094bd08d06
Custom Global Action
Additionally make sure to make use of the following controller code (as mentioned in the documentation).
Best Regards,
Hitesh
Hi Hitesh Parmar
thank you so much:)
I indeed overlooked the button and now changed its position to the header of the lineItems.
Never the less the 'message' action is not yet called correctly. Can you see why?
code is updated here:
SnarkWay/bookshop (github.com)
Hi Hitesh Parmar
I fogured out how the customAction.js File has to be confugred to call the message Action:
customActions.js
Hitesh Parmar
now the question is how I can start a workflow instance from that customEvent?
I am using Archana's blog post for that:
https://blogs.sap.com/2020/08/27/starting-workflow-from-custom-fiori-application-in-cloud-foundry/
but the $ajax call throws an error because it doesnt find the XSRF Token(502-BadGatewayError)
i thought its because Im calling from SAP Fiori Elements App but it should work the same as in UI5.
Do you have any idea?
Best Regards
Max
Hitesh Parmar
approach works similar to https://blogs.sap.com/2020/08/27/starting-workflow-from-custom-fiori-application-in-cloud-foundry/. I just had to correct the url. Thank you!
Hi @Hitesh Parmar,in OData V2 was an annotation loadDataOnAppLaunch to eliminate Go button,
I can not find the way to do it in V4, could you please help?
"dataLoadSettings": {
"loadDataOnAppLaunch": "always"
}
thx in advance,
Pavel
HI Pavel Belski ,
In OData V4, the manifest property is called initialLoad, which can have values
Auto
,Disabled
, andEnabled
. To see the same in Page Editor as shown below, you need to have specificatoin version 1.90.0 which will be released in few days, you can check it here https://www.npmjs.com/package/@sap/ux-specification.For now, you should see boolean values.
Page editor
Please have a look here https://sapui5.hana.ondemand.com/#/topic/1cf5c7f5b81c4cb3ba98fd14314d4504 , you need to
expand section SAP Fiori Elements for OData V4.
Best regards,
Hitesh
Hi Mariana Naboka,
we are struggling with the UI.Hidden annotation. We can set it to a property of our entity, but our requirement is to control actions that mark a Product as Favourite if it is not marked as favourite and to remove it from the Favourites if it is marked as a Favourite.
In one case it's easy, the annotation is "![@UI.Hidden]: isFavourite", but in the second case we would like to use an expression to negate the isFavourite property of the entity. Is this possbile with the CAP Annotation Syntax?
As a workaround we have introduced a second property "isNotFavourite", but this is a rather ugly workaround.
We were not able to find any examples of documentation regarding expressions for CAP CDS Annotations.
Kind regards,
Sebastian
Hi Sebastian Esch,
SAP Fiori elements floorplans for OData v4 support OData annotation expressions. Not at all places yet but at least all the usages of hidden are enabled for expressions.
But: unfortunately CAP CDS does not yet support annotation expressions.
Until then you can help you with local annotations, like:
The issue with having local annotations in this case means you would need to override on a term level, so for example if this is an action in a table the whole UI.LineItem. So this is actually not a very good example of having local annotations if you have all the annotations in your CDS.
Can you tell me if you use CAP JAVA or CAP Node? I will try to reach the product owner to see if when this can be expected.
Best regards,
Marcel
Hi Marcel Waechter,
thanks for the hint with the local annotations. We are using CAP on Node.js.
Kind regards,
Sebastian
Please note that this feature is not yet available externally. It is planned to come with the next CAP release, probably beginning of July.
Hi Mariana Naboka,
cool, I would have never guessed the syntax. 🙂
That means with $edmJson I can emulate the annotation XML structure?
Kind regards,
Sebastian
Ah, good to know.
Steffen Weinstock
Sorry, my fault. Got lost in compiler versions 🙁
Sebastian Esch
So you can either use the xml, or wait for the compiler version containing this feature.
BTW, Fiori tools already provide the code completion for logical operators in xml annotation files - by default they are sorted out to the end of the code completion list.
Once it is released, we will do our best to provide the code completion to simplify it for the end users also in CAP cds.
Hi Mariana Naboka,
we will patiently wait for the July release of CAP and then remove our workaround. 🙂
I haven't used the Fiori Tools XML Editor yet - the last time I did Fiori Elements with local annotations, Web IDE was the tool of choice and BAS / Fiori Tools was not around yet.
Cheers,
Sebastian
how to add annotations for value help, I didn't find any example till now, Can you suggest, please.
Please see my answer here: https://blogs.sap.com/2020/10/14/maintaining-annotations-in-cap-cds-projects-becomes-easier-with-new-lsp-features/comment-page-1/#comment-604407
is there any tool to edit the xml annotation file directly in BAS like the one in webide?
The tool in webide for editing the annotation is really great, but I could not find it in the BAS.
Hi Wei,
SAP Fiori tools is the new tooling for Fiori development in BAS or VSC. Based on the feedback we had heard from Web IDE customers, we took many steps to make annotations simpler with the extensions in SAP Fiori tools. For example, we built a collection of guides in Guided Development to enable the developer to build annotation snippets to configure features in SAP Fiori elements. We also invested heavily on the LSP capabilities to make text editing convenient and fast for those who are more experienced with annotations. For SAP Fiori elements OData V4, there are also feature based annotation support built into the Page Editor. I encourage you to look into these capabilities in BAS to see if they fit your needs. Please feel free to reach out to me or Mariana for a discussion as well.