Introduction
Building upon those blogs, in this blogpost, i will document my insights in exploring actions on List Report and Object Page using annotations only.
This blog post has as a follow-up to the following subsequent post:
CAP with Fiori Elements: Actions on List Report / Object Page using Annotations – Part2
Explanation of POC scenario and Its resources
We will use the sample project “cap-fe-lr-op-actions” that I have shared on GitHub here to explain the concepts. Let’s briefly examine the project and some of its essential files.
Project Structure | Folder or File | Purpose |
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 contains UI app. | |
app/annotations | contains all annotation files. | |
annotations.cds | annotations to list report views | |
generic-actions.cds | annotations for generic actions (explained in section 1 of Detailed Explanation) | |
global-determining-actions.cds | annotations for global and determining actions | |
fieldgroup-actions.cds | annotations for actions in field group | |
table-actions.cds | annotations for actions in table | |
chart-actions.cds | annotations for actions in chart | |
action-varieties.cds | annotations for types of actions |
Service “cap_fe_lr_op_actions_service” proivides following data set: Roots, Items, Categories, Criticalities, Samples.
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
Note: This blog post does not delve into custom actions or navigating to other apps.
In SAP Fiori Elements, actions refer to specific operations or functionalities that users can perform within an application. These actions are typically associated with buttons allowing users to trigger specific behaviors or execute predefined tasks or navigate to other applications.
There are 2 ways actions can be added to Fiori Elements based applications.
Actions can be divided into 2 categories based on how they are added:
1. Generic Actions
In both the list report and on the object page, SAP Fiori Elements offers standard actions like Create (+), Delete, Edit, Export, Personalization etc. These actions can be customized by enabling or disabling them based on your application’s requirements.
//======>>Service Annotaions<<======
annotate service.Roots with @(
Capabilities.Insertable: false
);
//========>>UI Annotaions<<========
annotate service.Roots with @(
UI.CreateHidden: true
);
//======>>Service Annotaions<<======
annotate service.Roots with @(
Capabilities.Updatable: false
);
//========>>UI Annotaions<<========
annotate service.Roots with @(
UI.UpdateHidden: true
);
Disabling the edit action at the service level won’t hide the edit button on the UI; instead, it results in an error.
Additionally, it’s feasible to dynamically control the edit action based on a specific element of the entity or by using dynamic expressions.
/* disableUpdation,enableUpdation
are elements of Roots entity. */
//======>>By Property<<======
annotate service.Roots with @(
UI.UpdateHidden: disableUpdation
);
//======>>By Dynamic Expression<<======
annotate service.Roots with @(
UI.UpdateHidden : {$edmJson: {$Ne: [
{$Path: 'enableUpdation'},
true
]}}
);
This will dynamically hide the button whenever the condition is satisfied based on the value of entity.
//======>>Service Annotaions<<======
annotate service.Roots with @(
Capabilities.Deletable: false
);
//========>>UI Annotaions<<========
annotate service.Roots with @(
UI.DeleteHidden: true
);
Disabling the Deletion action based on property or dynamic expression is applicable exclusively on the object page.
/* disableDeletion,enableDeletion
are elements of Roots entity. */
//======>>By Property<<======
annotate service.Roots with @(
UI.DeleteHidden: disableDeletion
);
//======>>By Dynamic Expression<<======
annotate service.Roots with @(
UI.DeleteHidden : {$edmJson: {$Ne: [
{$Path: 'enableDeletion'},
true
]}}
);
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
"tableSettings": {
"enableExport": false,
"personalization": {
"sort" : false,
"filter": false,
"column": false
}
}
}
}
2. App-Specific Actions
Based on position or location, Following different kinds of action can be added on List Report or Object Pages using annotations:
annotate service.Roots with @(UI.Identification: [
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.ga_op_calculate',
Label : 'Trigger Calculation',
Criticality: #Negative
},
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.EntityContainer/ga_op_ub_replication',
Label : '(Unbound) Trigger Replication',
Criticality: #Positive
}
]);
/*==========>> Button on ToolBar <<==========*/
annotate service.Roots with @(UI.LineItem: [
{
$Type : 'UI.DataFieldForAction',
Action: 'cap_fe_lr_op_actions_service.ta_lr_toolbarAction',
Label : 'Toolbar Action',
}
]);
/*==========>> Button as Column <<==========*/
annotate service.Roots with @(UI.LineItem: [
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.ta_lr_inlineAction',
Label : 'Inline Action',
Inline : true,
Criticality: #Positive
}
]);
annotate service.Roots with @(UI.LineItem: [
{
$Type : 'UI.DataFieldForAction',
Action: 'cap_fe_lr_op_actions_service.EntityContainer/ta_lr_ub_toolbarAction',
Label : '(Unbound) Toolbar Action'
}
]);
In this case, selection of row does not have any impact and context is not passed, hence called context-independent actions. Also Action property refers to the unbound action from your service in the format ‘{ServiceName}.EntityContainer/{ActionName}’.
annotate service.Roots with @(UI.LineItem: [
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.ta_lr_inlineIconAction',
Label : 'Inline Icon Action',
Inline : true,
IconUrl : 'sap-icon://da',
Criticality: #Negative
}
]);
annotate service.Roots with @(UI.FieldGroup #Details: {
$Type: 'UI.FieldGroupType',
Data: [
{
$Type : 'UI.DataFieldForAction',
Action: 'cap_fe_lr_op_actions_service.EntityContainer/fg_op_ub_triggerRefresh',
Label : '(Unbound) Section Trigger'
},
{
$Type : 'UI.DataFieldForAction',
Action: 'cap_fe_lr_op_actions_service.fg_op_triggerInlineAction01',
Label : 'Inline Trigger 01',
Inline: true
}
]});
annotate service.Roots with @(UI.FieldGroup #MoreDetails: {
$Type: 'UI.FieldGroupType',
Data : [
{
$Type : 'UI.DataFieldForAction',
Action: 'cap_fe_lr_op_actions_service.fg_op_triggerAction',
Label : 'Section Trigger'
},
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.fg_op_triggerInlineAction02',
Label : 'Inline Trigger 02',
Inline: true
}
]});
Action buttons can also be added to the chart toolbar by defining the Actions property in the annotation term UI.Chart.
Here is an example:
UI.Chart #ROChart: {
$Type : 'UI.ChartDefinitionType',
Title : 'Amount By Item',
ChartType : #Bar,
Dimensions : [iname],
DimensionAttributes: [{
$Type : 'UI.ChartDimensionAttributeType',
Dimension: iname,
Role : #Category
}],
DynamicMeasures: ['@Analytics.AggregatedProperty#itemamount_sum'],
Actions : [
{
$Type : 'UI.DataFieldForAction',
Action : 'ca_op_ub_chartAction',
Label : '(Unbound) Chart Action',
Criticality: #Positive
}
]
}
Note: Only unbound actions can be added to the chart toolbar.
Determining Actions
annotate service.Roots with @(UI.Identification: [
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.da_op_clearParymentAction',
Label : 'Clear Payment Action',
Determining: true,
Criticality: #Negative
},
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.EntityContainer/da_op_ub_clearOutstanding',
Label : '(Unbound) Clear Outstanding',
Determining: true,
Criticality: #Positive
}
]);
Miscellanous features
annotate service.Roots with actions{
ta_lr_inlineAction @Core.OperationAvailable: disableUpdation;
ta_lr_inlineIconAction @Core.OperationAvailable: {
$edmJson: {$Gt: [{$Path: 'totalAmount'}, 1000]}
};
ta_lr_toolbarAction @Core.OperationAvailable: disableUpdation;
};
In above sample, ta_lr_inlineAction will be disabled or enabled (made clickable) based on the value in ‘disableUpdation’ element of Roots entity. Simillary ta_lr_inlineIconAction will be disabled or enabled if ‘totalAmount’ is greater than 100 of Roots entity.
annotate service.Items with @(UI.LineItem #Items: [
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.ta_op_item_inline',
Label : 'Item Inline Action',
Inline : true,
Criticality: #Positive,
![@UI.Hidden]: {$edmJson: {$Ne: [{$Path: 'enableItem'}, true]}}
}
]);
result:
annotate service.Items with @(UI.LineItem #Items: [
{
$Type : 'UI.DataFieldForAction',
Action : 'cap_fe_lr_op_actions_service.ta_op_item_inline2',
Label : 'Action on Edit',
Inline : true,
Criticality: #Negative,
![@UI.Hidden]: IsActiveEntity
}
]);
Please be aware that IsActiveEntity is a property within Fiori Elements, and it is set to false when the entity is in edit mode.
Conclusion
In this blog post, we have delved into the utilization of different annotations to incorporate actions at different positions on List Report and Object Pages along with some miscellanous features.
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.