manifest.json
file of the Fiori application, so that during deployment to Build Work Zone instead of a Static App Launcher, a dynamic one is created.{
"_version": "1.49.0",
"sap.app": {
...
"dataSources": {
"mainService": {
"uri": "odata/v4/catalog/",
"type": "OData",
"settings": {
"odataVersion": "4.0",
"annotations": [
"annotation"
]
}
},
"annotation": {
"type": "ODataAnnotation",
"uri": "annotations/annotation.xml",
"settings": {
"localUri": "annotations/annotation.xml"
}
}
},
"crossNavigation": {
"inbounds": {
"com-myapp-inbound": {
"signature": {
"parameters": {},
"additionalParameters": "allowed"
},
"semanticObject": "BO",
"action": "display",
"title": "{{flpTitle}}",
"subTitle": "{{flpSubtitle}}",
"icon": "sap-icon://inventory",
"indicatorDataSource": {
"dataSource": "mainService",
"path": "getTileInfo(appName='XO')",
"refresh": 600
}
}
}
}
}
...
}
indicatorDataSource
block. We tell the Launchpad Service from where to take the data to be displayed on the Tile.path
points to the resource in your service endpoint, which should return either a single number or an object in a dedicated format."path": "Orders/$count"
. You can add filters as well, just conform to the OData URI syntax.srv/service.cds
file.@requires: 'authenticated-user'
@protocol: 'odata'
service CatalogService {
type DynamicAppLauncher {
subtitle : String;
title : String;
icon : String;
info : String;
infoState : String;
number : Decimal(9, 2);
numberDigits : Integer;
numberFactor : String;
numberState : String;
numberUnit : String;
stateArrow : String;
}
// Delivers KPI Information for Launchpad Tiles
function getTileInfo(appName : String) returns DynamicAppLauncher;
}
DynamicAppLauncher
. This is the expected structure of the dynamic tile information. For more details look at the SAP help site. Second You see that properties defined statically in manifest.json
already present here as well. This is very flexible and a good feature from SAP. It means we can override static properties like title and subtitle with dynamic values. All you need to do is to include that property in the returned object, or omit if You are fine with the title defined in manifest.json
for example.srv/service.js
. const { TileInfo } = require("./handlers/TileInfo");
srv.on("getTileInfo", async (req) => {
let tileInfo = new TileInfo(req.data.appName);
return await tileInfo.collect();
});
srv/handlers/TileInfo.js
./**
* Collecting Dynamic App Launcher Information
*/
class TileInfo {
APP_NAMES = Object.freeze({
purchaseOrder: "XO"
});
#appName;
/**
* Instance setup
* @param {*} appName Application Name
*/
constructor(appName) {
this.#appName = appName ? appName : "UNKNOWN";
}
/**
* Collect Tile Properties
* @returns
*/
async collect() {
try {
switch (this.#appName) {
case this.APP_NAMES.purchaseOrder:
return {
subtitle: "This is the: subtitle",
title: "This is the: title",
icon: "sap-icon://developer-settings",
info: "This is the: info",
infoState: "Critical",
number: "44.44",
numberDigits: 1,
numberFactor: "k",
numberState: "Negative",
numberUnit: "EUR",
stateArrow: "Down"
};
// break;
default:
return {};
}
}
catch (error) {
return {};
}
}
}
module.exports = { TileInfo };
(appName)
is passed to the constructor, the one we placed in the manifest.json as function parameter in the path, and sent by Build Work Zone within the request. Here we only return a sample object for demonstration purposes. Replace it to populate the response with useful information according to Your needs. You can notice the UNKNOWN
application we default when nothing is passed. The purpose of this is not to break the runtime for unknown or misconfigured applications names, but rather display only the static content of the tile configured in the manifest.json
like the title and icon. You can spot out and fix such situations seeing the 3 dots instead of the KPI number.You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
8 | |
8 | |
5 | |
4 | |
4 | |
4 | |
4 | |
4 | |
3 | |
3 |