<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<script src="https://sapui5.hana.ondemand.com/1.38.10/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.ui.commons,sap.ui.core, sap.suite.ui.commons"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-resourceroots='{
"demo": "./"
}'>
</script>
<style>
.sapSuiteGTHdrContent{
height:1.5rem !important;
}
#oTileContent-content{
min-height: 8rem;
}
</style>
<!-- add sap.ui.table,sap.ui.ux3 and/or other libraries to 'data-sap-ui-libs' if required -->
<script>
var view = sap.ui.view({id:"idview1", viewName:"demo.CustomTile", type:sap.ui.core.mvc.ViewType.XML});
view.placeAt("content");
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<core:View
xmlns="sap.suite.ui.commons"
xmlns:mc="sap.suite.ui.microchart"
xmlns:core="sap.ui.core"
controllerName="demo.CustomTile">
<GenericTile
header="{/data/display_title_text}"
subheader="{/data/display_subtitle_text}"
size="Auto"
frameType="OneByOne"
press="onPress">
<tileContent>
<TileContent footer="{/data/display_info_text}" frameType="OneByOne">
<content>
<mc:ComparisonMicroChart
size="M"
id="compMicroChart">
<mc:data>
<mc:ComparisonMicroChartData
title="{/data/comparisonModel/1/title}"
value="{/data/comparisonModel/1/value}"
color="{/data/comparisonModel/1/color}"/>
<mc:ComparisonMicroChartData
title="{/data/comparisonModel/2/title}"
value="{/data/comparisonModel/2/value}"
color="{/data/comparisonModel/2/color}"/>
<mc:ComparisonMicroChartData
title="{/data/comparisonModel/3/title}"
value="{/data/comparisonModel/3/value}"
color="{/data/comparisonModel/3/color}"/>
</mc:data>
</mc:ComparisonMicroChart>
</content>
</TileContent>
</tileContent>
</GenericTile>
</core:View>
(function() {
"use strict";
/*global jQuery, OData, sap, setTimeout, hasher */
jQuery.sap.require("sap.ui.core.IconPool");
jQuery.sap.require("sap.ushell.components.tiles.utils");
sap.ui.controller("demo.CustomTile", {
// handle to control/cancel browser's setTimeout()
timer: null,
// handle to control/cancel data.js OData.read()
oDataRequest1: null,
oDataRequest2: null,
oDataRequest3: null,
_setComparisonData: function(oModel, config) {
var aData;
//For testing purposes (data will be present when utilited within the Launchpad):
var oDataProp = oModel.getProperty("/data");
if (!oDataProp) {
var aPropData = {
"display_title_text": "Test Title",
"display_subtitle_text": "Test Subtitle",
"display_info_text": "Information"
};
oModel.setProperty("/data", aPropData);
}
if (config) {
//For display when configuring the tile:
aData = {
1: {
"title": "Example 1",
"value": 25,
"color": "Neutral"
},
2: {
"title": "Example 2",
"value": 15,
"color": "Good"
},
3: {
"title": "Example 3",
"value": 35,
"color": "Critical"
}
};
} else {
aData = {
1: {
"title": "...",
"value": 0,
"color": "Neutral"
},
2: {
"title": "...",
"value": 0,
"color": "Neutral"
},
3: {
"title": "...",
"value": 0,
"color": "Neutral"
}
};
}
oModel.setProperty("/data/comparisonModel", aData);
},
onInit: function() {
var oView = this.getView();
var oModel;
var oViewData = oView.getViewData();
//Adding to allow for running script outside of Launchpad:
if (oViewData) {
var oTileApi = oViewData.chip;
var oConfig = sap.ushell.components.tiles.utils.getConfiguration(oTileApi, oTileApi.configurationUi.isEnabled(), false);
var sKeywords;
var aKeywords;
var that = this;
var sNavigationTargetUrl = oConfig.navigation_target_url;
var sSystem;
this.bIsDataRequested = false;
sSystem = oTileApi.url.getApplicationSystem();
if (sSystem) { // propagate system to target application
sNavigationTargetUrl += ((sNavigationTargetUrl.indexOf("?") < 0) ? "?" : "&") + "sap-system=" + sSystem;
}
this.navigationTargetUrl = sNavigationTargetUrl;
/*
* Model of the applauncher tile consisting of
* config (tile configuration),
* data (dyanmic data read from a data source)
* nav (target URL set to '' in case of Admin UI), and
* search (highlight terms)
*/
oModel = new sap.ui.model.json.JSONModel({
config: oConfig,
data: sap.ushell.components.tiles.utils.getDataToDisplay(oConfig, {
number: (oTileApi.configurationUi.isEnabled() ? 1234 : "...")
}),
nav: {
navigation_target_url: (oTileApi.configurationUi && oTileApi.configurationUi.isEnabled() ? "" : sNavigationTargetUrl)
},
search: {
display_highlight_terms: []
}
});
this._setComparisonData(oModel, oTileApi.configurationUi.isEnabled());
oView.setModel(oModel);
// implement search contract
if (oTileApi.search) {
// split and clean keyword string (may be comma + space delimited)
sKeywords = oView.getModel().getProperty("/config/display_search_keywords");
aKeywords = jQuery.grep(sKeywords.split(/[, ]+/), function(n, i) {
return n && n !== "";
});
// add title and subtitle (if present) to keywords for better FLP searching
if (oConfig.display_title_text && oConfig.display_title_text !== "" &&
aKeywords.indexOf(oConfig.display_title_text) === -1) {
aKeywords.push(oConfig.display_title_text);
}
if (oConfig.display_subtitle_text && oConfig.display_subtitle_text !== "" &&
aKeywords.indexOf(oConfig.display_subtitle_text) === -1) {
aKeywords.push(oConfig.display_subtitle_text);
}
if (oConfig.display_info_text && oConfig.display_info_text !== "" &&
aKeywords.indexOf(oConfig.display_info_text) === -1) {
aKeywords.push(oConfig.display_info_text);
}
// defined in search contract:
oTileApi.search.setKeywords(aKeywords);
oTileApi.search.attachHighlight(
function(aHighlightWords) {
// update model for highlighted search term
oView.getModel().setProperty("/search/display_highlight_terms", aHighlightWords);
}
);
}
// implement bag update handler
if (oTileApi.bag && oTileApi.bag.attachBagsUpdated) {
// is only called by the FLP for bookmark tiles which have been updated via bookmark service
oTileApi.bag.attachBagsUpdated(function(aUpdatedBagIds) {
if (aUpdatedBagIds.indexOf("tileProperties") > -1) {
sap.ushell.components.tiles.utils._updateTilePropertiesTexts(oView, oTileApi.bag.getBag('tileProperties'));
}
});
}
// implement preview contract
if (oTileApi.preview) {
oTileApi.preview.setTargetUrl(sNavigationTargetUrl);
oTileApi.preview.setPreviewIcon(oConfig.display_icon_url);
oTileApi.preview.setPreviewTitle(oConfig.display_title_text);
}
// implement refresh contract
if (oTileApi.refresh) {
oTileApi.refresh.attachRefresh(this.refreshHandler.bind(null, this));
}
// attach the refresh handler also for the visible contract, as we would like
// on setting visible to true, to directly go and call the oData call
if (oTileApi.visible) {
oTileApi.visible.attachVisible(this.visibleHandler.bind(this));
}
// implement configurationUi contract: setup configuration UI
if (oTileApi.configurationUi.isEnabled()) {
oTileApi.configurationUi.setUiProvider(function() {
// attach configuration UI provider, which is essentially a components.tiles.dynamicapplauncher.Configuration
var oConfigurationUi = sap.ushell.components.tiles.utils.getConfigurationUi(oView, "view.Configuration");
oTileApi.configurationUi.attachCancel(that.onCancelConfiguration.bind(null, oConfigurationUi));
oTileApi.configurationUi.attachSave(that.onSaveConfiguration.bind(null, oConfigurationUi));
return oConfigurationUi;
});
this.getView().getContent()[0].setTooltip(
sap.ushell.components.tiles.utils.getResourceBundleModel().getResourceBundle()
.getText("edit_configuration.tooltip")
);
} else {
if (!oTileApi.preview || !oTileApi.preview.isEnabled()) {
if (!sSystem) {
sap.ushell.Container.addRemoteSystemForServiceUrl(oConfig.service_url1);
} // else registration is skipped because registration has been done already
// outside this controller (e.g. remote catalog registration)
// start fetching data from backend service if not in preview or admin mode
this.onUpdateDynamicData();
}
}
// attach the tile actions provider for the actions contract
if (oTileApi.actions) {
//TODO check new property name with designer dudes
var aActions = oConfig.actions,
aExtendedActions;
if (aActions) {
aExtendedActions = aActions.slice();
} else {
aExtendedActions = [];
}
var tileSettingsAction = sap.ushell.components.tiles.utils.getTileSettingsAction(oModel, this.onSaveRuntimeSettings.bind(this));
aExtendedActions.push(tileSettingsAction);
oTileApi.actions.setActionsProvider(function() {
return aExtendedActions;
});
}
} else {
//Design/Testing mode:
oModel = new sap.ui.model.json.JSONModel();
this._setComparisonData(oModel, true);
oView.setModel(oModel);
}
},
// convenience function to stop browser's timeout and OData calls
stopRequests: function() {
if (this.timer) {
clearTimeout(this.timer);
}
if (this.oDataRequest) {
try {
this.oDataRequest.abort();
} catch (e) {
jQuery.sap.log.warning(e.name, e.message);
}
}
},
// destroy handler stops requests
onExit: function() {
this.stopRequests();
},
// trigger to show the configuration UI if the tile is pressed in Admin mode
onPress: function() {
var oView = this.getView(),
oViewData = oView.getViewData(),
oModel = oView.getModel(),
sTargetUrl = oModel.getProperty("/nav/navigation_target_url"),
oTileApi = oViewData.chip;
if (oTileApi.configurationUi.isEnabled()) {
oTileApi.configurationUi.display();
} else if (sTargetUrl) {
if (sTargetUrl[0] === '#') {
hasher.setHash(sTargetUrl);
} else {
window.open(sTargetUrl, '_blank');
}
}
},
// dynamic data updater
onUpdateDynamicData: function() {
var oView = this.getView(),
oConfig = oView.getModel().getProperty("/config"),
nservice_refresh_interval = oConfig.service_refresh_interval;
if (!nservice_refresh_interval) {
nservice_refresh_interval = 0;
} else if (nservice_refresh_interval < 10) {
// log in English only
jQuery.sap.log.warning(
"Refresh Interval " + nservice_refresh_interval + " seconds for service URL " + oConfig.service_url1 + " is less than 10 seconds, which is not supported. " + "Increased to 10 seconds automatically.",
null,
"view.CustomTile.controller"
);
nservice_refresh_interval = 10;
}
if (oConfig.service_url1) {
this.loadData(nservice_refresh_interval);
}
},
extractData: function(oData) {
var name,
aKeys = ["results", "icon", "title", "number", "numberUnit", "info", "infoState", "infoStatus", "targetParams", "subtitle", "stateArrow", "numberState", "numberDigits", "numberFactor"];
if (typeof oData === "object" && Object.keys(oData).length === 1) {
name = Object.keys(oData)[0];
if (jQuery.inArray(name, aKeys) === -1) {
return oData[name];
}
}
return oData;
},
// tile settings action UI save handler
onSaveRuntimeSettings: function(oSettingsView) {
var
oViewModel = oSettingsView.getModel(),
oTileApi = this.getView().getViewData().chip,
oConfigToSave = this.getView().getModel().getProperty("/config");
oConfigToSave.display_title_text = oViewModel.getProperty('/title');
oConfigToSave.display_subtitle_text = oViewModel.getProperty('/subtitle');
oConfigToSave.display_info_text = oViewModel.getProperty('/info');
oConfigToSave.display_search_keywords = oViewModel.getProperty('/keywords');
// use bag contract in order to store translatable properties
var tilePropertiesBag = oTileApi.bag.getBag('tileProperties');
tilePropertiesBag.setText('display_title_text', oConfigToSave.display_title_text);
tilePropertiesBag.setText('display_subtitle_text', oConfigToSave.display_subtitle_text);
tilePropertiesBag.setText('display_info_text', oConfigToSave.display_info_text);
tilePropertiesBag.setText('display_search_keywords', oConfigToSave.display_search_keywords);
function logErrorAndReject(oError) {
jQuery.sap.log.error(oError, null, "view.CustomTile.controller");
}
// saving the relevant properteis
tilePropertiesBag.save(
// success handler
function() {
jQuery.sap.log.debug("property bag 'tileProperties' saved successfully");
// update the local tile's config - saving changes on the Model
this.getView().getModel().setProperty("/config", oConfigToSave);
// update tile's model for changes to appear immediately
// (and not wait for the refresh handler which happens every 10 seconds)
this.getView().getModel().setProperty('/data/display_title_text', oConfigToSave.display_title_text);
this.getView().getModel().setProperty('/data/display_subtitle_text', oConfigToSave.display_subtitle_text);
this.getView().getModel().setProperty('/data/display_info_text', oConfigToSave.display_info_text);
// call to refresh model which (due to the binding) will refresh the tile
this.getView().getModel().refresh();
}.bind(this),
logErrorAndReject // error handler
);
},
// configuration save handler
onSaveConfiguration: function(oConfigurationView) {
var
// the deferred object required from the configurationUi contract
oDeferred = jQuery.Deferred(),
oModel = oConfigurationView.getModel(),
// tile model placed into configuration model by getConfigurationUi
oTileModel = oModel.getProperty("/tileModel"),
oTileApi = oConfigurationView.getViewData().chip,
aTileNavigationActions = sap.ushell.components.tiles.utils.tileActionsRows2TileActionsArray(oModel.getProperty("/config/tile_actions_rows")),
// get the configuration to save from the model
configToSave = {
//display_icon_url: oModel.getProperty("/config/display_icon_url"),
display_number_unit: oModel.getProperty("/config/display_number_unit"),
service_first_label: oModel.getProperty("/config/service_first_label"),
service_second_label: oModel.getProperty("/config/service_second_label"),
service_third_label: oModel.getProperty("/config/service_third_label"),
service_url1: oModel.getProperty("/config/service_url1"),
service_url2: oModel.getProperty("/config/service_url2"),
service_url3: oModel.getProperty("/config/service_url3"),
service_lower_threshold: oModel.getProperty("/config/service_lower_threshold"),
service_upper_threshold: oModel.getProperty("/config/service_upper_threshold"),
service_refresh_interval: oModel.getProperty("/config/service_refresh_interval"),
navigation_use_semantic_object: oModel.getProperty("/config/navigation_use_semantic_object"),
navigation_target_url: oModel.getProperty("/config/navigation_target_url"),
navigation_semantic_object: jQuery.trim(oModel.getProperty("/config/navigation_semantic_object")) || "",
navigation_semantic_action: jQuery.trim(oModel.getProperty("/config/navigation_semantic_action")) || "",
navigation_semantic_parameters: jQuery.trim(oModel.getProperty("/config/navigation_semantic_parameters")),
display_search_keywords: oModel.getProperty("/config/display_search_keywords")
};
//If the input fields icon, semantic object and action are failing the input validations, then through an error message requesting the user to enter/correct those fields
var bReject = sap.ushell.components.tiles.utils.checkInputOnSaveConfig(oConfigurationView);
if (!bReject) {
bReject = sap.ushell.components.tiles.utils.checkTileActions(oConfigurationView);
}
if (bReject) {
oDeferred.reject("mandatory_fields_missing");
return oDeferred.promise();
}
// overwrite target URL in case of semantic object navigation
if (configToSave.navigation_use_semantic_object) {
configToSave.navigation_target_url = sap.ushell.components.tiles.utils.getSemanticNavigationUrl(configToSave);
oModel.setProperty("/config/navigation_target_url", configToSave.navigation_target_url);
}
// use bag contract in order to store translatable properties
var tilePropertiesBag = oTileApi.bag.getBag('tileProperties');
tilePropertiesBag.setText('display_title_text', oModel.getProperty("/config/display_title_text"));
tilePropertiesBag.setText('display_subtitle_text', oModel.getProperty("/config/display_subtitle_text"));
tilePropertiesBag.setText('display_info_text', oModel.getProperty("/config/display_info_text"));
tilePropertiesBag.setText('display_search_keywords', configToSave.display_search_keywords);
var tileNavigationActionsBag = oTileApi.bag.getBag('tileNavigationActions');
//forward populating of tile navigation actions array into the bag, to Utils
sap.ushell.components.tiles.utils.populateTileNavigationActionsBag(tileNavigationActionsBag, aTileNavigationActions);
function logErrorAndReject(oError, oErrorInfo) {
jQuery.sap.log.error(oError, null, "CustomTile.controller");
oDeferred.reject(oError, oErrorInfo);
}
// use configuration contract to write parameter values
oTileApi.writeConfiguration.setParameterValues({
tileConfiguration: JSON.stringify(configToSave)
},
// success handler
function() {
var oConfigurationConfig = sap.ushell.components.tiles.utils.getConfiguration(oTileApi, false, false),
// get tile config data in admin mode
oTileConfig = sap.ushell.components.tiles.utils.getConfiguration(oTileApi, true, false),
// switching the model under the tile -> keep the tile model
oModel = new sap.ui.model.json.JSONModel({
config: oConfigurationConfig,
// keep tile model
tileModel: oTileModel
});
oConfigurationView.setModel(oModel);
// update tile model
oTileModel.setData({
data: oTileConfig,
nav: {
navigation_target_url: ""
}
}, false);
if (oTileApi.preview) {
oTileApi.preview.setTargetUrl(oConfigurationConfig.navigation_target_url);
oTileApi.preview.setPreviewIcon(oConfigurationConfig.display_icon_url);
oTileApi.preview.setPreviewTitle(oConfigurationConfig.display_title_text);
}
tilePropertiesBag.save(
// success handler
function() {
jQuery.sap.log.debug("property bag 'tileProperties' saved successfully");
// update possibly changed values via contracts
if (oTileApi.title) {
oTileApi.title.setTitle(
configToSave.display_title_text,
// success handler
function() {
oDeferred.resolve();
},
logErrorAndReject // error handler
);
} else {
oDeferred.resolve();
}
},
logErrorAndReject // error handler
);
tileNavigationActionsBag.save(
// success handler
function() {
jQuery.sap.log.debug("property bag 'navigationProperties' saved successfully");
},
logErrorAndReject // error handler
);
},
logErrorAndReject // error handler
);
return oDeferred.promise();
},
successHandleFn: function(index, oResult) {
var oConfig = this.getView().getModel().getProperty("/config");
this.oDataRequest = undefined;
var oData = oResult;
if (typeof oResult === "object") {
var uriParamInlinecount = jQuery.sap.getUriParameters(oConfig.service_url1).get("$inlinecount");
if (uriParamInlinecount && uriParamInlinecount === "allpages") {
oData = {
number: oResult.__count
};
} else {
oData = this.extractData(oData);
}
} else if (typeof oResult === "string") {
oData = {
number: oResult
};
}
var oDataComp = {
title: "",
value: "",
color: ""
};
switch (index) {
case 1:
oDataComp.title = oConfig.service_first_label;
break;
case 2:
oDataComp.title = oConfig.service_second_label;
break;
case 3:
oDataComp.title = oConfig.service_third_label;
break;
}
oDataComp.value = Number(oData.number);
if (oDataComp.value > Number(oConfig.service_upper_threshold)) {
oDataComp.color = "Critical";
} else if (oDataComp.value < Number(oConfig.service_lower_threshold)) {
oDataComp.color = "Good";
} else {
oDataComp.color = "Neutral";
}
// set data to display
//var oDataToDisplay = sap.ushell.components.tiles.utils.getDataToDisplay(oConfig, oDataComp);
var oModel = this.getView().getModel();
var sCompModelProp = oModel.getProperty("/data/comparisonModel");
if (!sCompModelProp) {
var oComparisonProp = {
1: {
"title": "",
"value": 0,
"color": "Neutral"
},
2: {
"title": "",
"value": 0,
"color": "Neutral"
},
3: {
"title": "",
"value": 0,
"color": "Neutral"
}
};
oModel.setProperty("/data/comparisonModel", oComparisonProp);
}
oModel.setProperty("/data/comparisonModel/" + index + "/", oDataComp);
// rewrite target URL
this.getView().getModel().setProperty("/nav/navigation_target_url",
sap.ushell.components.tiles.utils.addParamsToUrl(
this.navigationTargetUrl,
oDataToDisplay
));
},
// error handler
errorHandlerFn: function(oMessage) {
var oConfig = this.getView().getModel().getProperty("/config");
this.oDataRequest1 = undefined;
this.oDataRequest2 = undefined;
this.oDataRequest3 = undefined;
var sMessage = oMessage && oMessage.message ? oMessage.message : oMessage,
oResourceBundle = sap.ushell.components.tiles.utils.getResourceBundleModel()
.getResourceBundle();
if (oMessage.response) {
sMessage += " - " + oMessage.response.statusCode + " " + oMessage.response.statusText;
}
// log in English only
jQuery.sap.log.error(
"Failed to update data via service " + oConfig.service_url1 + ": " + sMessage,
null,
"view.CustomTile"
);
this.getView().getModel().setProperty("/data",
sap.ushell.components.tiles.utils.getDataToDisplay(oConfig, {
number: "???",
info: oResourceBundle.getText("dynamic_data.error"),
infoState: "Critical"
})
);
},
// configuration cancel handler
onCancelConfiguration: function(oConfigurationView, successHandler, errorHandle) {
// re-load old configuration and display
var oViewData = oConfigurationView.getViewData(),
oModel = oConfigurationView.getModel(),
// tile model placed into configuration model by getConfigurationUi
oTileModel = oModel.getProperty("/tileModel"),
oTileApi = oViewData.chip,
oCurrentConfig = sap.ushell.components.tiles.utils.getConfiguration(oTileApi, false, false);
oConfigurationView.getModel().setData({
config: oCurrentConfig,
tileModel: oTileModel
}, false);
},
// loads data from backend service
loadData: function(nservice_refresh_interval) {
var oDynamicTileView = this.getView(),
oConfig = oDynamicTileView.getModel().getProperty("/config"),
sUrl1 = oConfig.service_url1,
sUrl2 = oConfig.service_url2,
sUrl3 = oConfig.service_url3,
that = this;
var oTileApi = this.getView().getViewData().chip;
if (!sUrl1 && !sUrl2 && !sUrl3) {
return;
}
if (/;o=([;\/?]|$)/.test(sUrl1)) { // URL has placeholder segment parameter ;o=
sUrl1 = oTileApi.url.addSystemToServiceUrl(sUrl1);
}
if (/;o=([;\/?]|$)/.test(sUrl2)) { // URL has placeholder segment parameter ;o=
sUrl2 = oTileApi.url.addSystemToServiceUrl(sUrl2);
}
if (/;o=([;\/?]|$)/.test(sUrl3)) { // URL has placeholder segment parameter ;o=
sUrl3 = oTileApi.url.addSystemToServiceUrl(sUrl3);
}
//set the timer if required
if (nservice_refresh_interval > 0) {
// log in English only
jQuery.sap.log.info(
"Wait " + nservice_refresh_interval + " seconds before calling " + oConfig.service_url1 + " again",
null,
"view.CustomTile.controller"
);
// call again later
this.timer = setTimeout(that.loadData.bind(that, nservice_refresh_interval, false), (nservice_refresh_interval * 1000));
}
// Verify the the Tile visibility is "true" in order to issue an oData request
if (oTileApi.visible.isVisible() && !that.oDataRequest1) {
this.bIsDataRequested = true;
that.oDataRequest1 = OData.read({
requestUri: sUrl1,
headers: {
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
}
},
// sucess handler
this.successHandleFn.bind(this, 1),
this.errorHandlerFn.bind(this)
); // End of oData.read
that.oDataRequest2 = OData.read({
requestUri: sUrl2,
headers: {
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
}
},
// sucess handler
this.successHandleFn.bind(this, 2),
this.errorHandlerFn.bind(this)
); // End of oData.read
that.oDataRequest3 = OData.read({
requestUri: sUrl3,
headers: {
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
}
},
// sucess handler
this.successHandleFn.bind(this, 3),
this.errorHandlerFn.bind(this)
); // End of oData.read
}
},
// loads data once if not in configuration mode
refreshHandler: function(oDynamicTileController) {
var oTileApi = oDynamicTileController.getView().getViewData().chip;
if (!oTileApi.configurationUi.isEnabled()) {
oDynamicTileController.loadData(0);
} else {
oDynamicTileController.stopRequests();
}
},
// load data in place in case setting visibility from false to true
// with no additional timer registered
visibleHandler: function(isVisible) {
var oView = this.getView(),
oConfig = oView.getModel().getProperty("/config"),
nservice_refresh_interval = oConfig.service_refresh_interval;
if (isVisible) {
if (!this.bIsDataRequested) {
//tile is visible and data wasn't requested yet
this.refreshHandler(this);
}
if (nservice_refresh_interval) {
//tile is visible and the refresh interval isn't set to 0
this.refreshHandler(this);
}
} else {
this.stopRequests();
}
}
});
}());
(function () {
"use strict";
/*global jQuery, sap */
jQuery.sap.require("sap.ushell.components.tiles.utils");
sap.ui.controller("view.Configuration", {
// checks given inputs
onConfigurationInputChange: function (oControlEvent) {
sap.ushell.components.tiles.utils.checkInput(this.getView(), oControlEvent);
},
// default semantic objects for dynamic applauncher: blank
aDefaultObjects : [{obj: "", name: ""}],
onInit: function () {
var oView = this.getView(),
oSemanticObjectSelector = oView.byId("navigation_semantic_objectInput"),
oActionSelector = oView.byId("navigation_semantic_actionInput"),
oResourceModel = sap.ushell.components.tiles.utils.getResourceBundleModel();
oView.setModel(oResourceModel, "i18n");
var oBundle = oResourceModel.getResourceBundle();
// set view name for identification in utils
oView.setViewName("view.Configuration");
sap.ushell.components.tiles.utils.createSemanticObjectModel(this, oSemanticObjectSelector, this.aDefaultObjects);
sap.ushell.components.tiles.utils.createActionModel(this, oActionSelector, this.aDefaultObjects);
// make sure that the chose object is written back to the configuration
oSemanticObjectSelector.attachChange(function (oControlEvent) {
var sValue = oControlEvent.getSource().getValue();
oView.getModel().setProperty("/config/navigation_semantic_object", sValue);
});
oActionSelector.attachChange(function (oControlEvent) {
var sValue = oControlEvent.getSource().getValue();
oView.getModel().setProperty("/config/navigation_semantic_action", sValue);
});
// toggle editable property of targetURL input field depending on navigation_use_semantic_object
oView.byId("targetUrl").bindProperty("enabled", {
formatter: function (bUseLaunchpad) {
return !bUseLaunchpad;
},
path: "/config/navigation_use_semantic_object"
});
//Adding list items URL and Intent to the Target Type in Tile Actions section
var oItem = new sap.ui.core.ListItem({key: "URL", text:oBundle.getText("configuration.tile_actions.table.target_type.url")});
oView.byId("targetTypeCB").addItem(oItem);
oItem = new sap.ui.core.ListItem({key: "INT", text:oBundle.getText("configuration.tile_actions.table.target_type.intent")});
oView.byId("targetTypeCB").addItem(oItem);
},
onAfterRendering: function(){
// sap.ushell.components.tiles.utils.updateTooltipForDisabledProperties(this.getView());
sap.ushell.components.tiles.utils.updateMessageStripForOriginalLanguage(this.getView());
},
// forward semantic object value helper request to utils
onValueHelpRequest : function (oEvent) {
//Third parameter is to differentiate whether it's Tile Actions icon field or general icon field. If it's true, then it's tile actions icon field, else general icon field.
sap.ushell.components.tiles.utils.objectSelectOnValueHelpRequest(this, oEvent, false);
},
// forward semantic action value helper request to utils
onActionValueHelpRequest : function (oEvent) {
//Third parameter is to differentiate whether it's Tile Actions icon field or general icon field. If it's true, then it's tile actions icon field, else general icon field.
sap.ushell.components.tiles.utils.actionSelectOnValueHelpRequest(this, oEvent, false);
},
// change handler for check box
onCheckBoxChange : function (oEvent) {
var oView = this.getView(),
oSemanticObjectSelector = oView.byId("navigation_semantic_objectInput"),
oModel = oSemanticObjectSelector.getModel(),
value = oEvent.getSource().getSelected();
oModel.setProperty("/enabled", value);
sap.ushell.components.tiles.utils.checkInput(this.getView(), oEvent);
},
// forward icon value help request to utils
onIconValueHelpRequest : function (oEvent) {
//Third parameter is to differentiate whether it's Tile Actions icon field or general icon field. If it's true, then it's tile actions icon field, else general icon field.
sap.ushell.components.tiles.utils.iconSelectOnValueHelpRequest(this, oEvent, false);
},
// forward icon close request to utils
onSelectIconClose: function () {
sap.ushell.components.tiles.utils.onSelectIconClose(this.getView());
},
// forward icon ok to utils
onSelectIconOk: function () {
sap.ushell.components.tiles.utils.onSelectIconOk(this.getView());
},
//This function applies table logic for the Action according to the Target Type:
//if Taregt Type is URL, then Action field should be disabled else if it's Intent, then the Action field should be enabled.
handleTargetTypeChange : function(oTargetTypeComboBox){
sap.ushell.components.tiles.utils.onTargetTypeChange(oTargetTypeComboBox);
},
//forward tile actions semantic object value helper request to utils
onTileActionValueHelp : function (oEvent) {
//Third parameter is to differentiate whether it's Tile Actions icon field or general icon field. If it's true, then it's tile actions icon field, else general icon field.
sap.ushell.components.tiles.utils.objectSelectOnValueHelpRequest(this, oEvent, true);
},
//forward icon value help request to utils
onTileActionIconValueHelp : function (oEvent) {
//Third parameter is to differentiate whether it's Tile Actions icon field or general icon field. If it's true, then it's tile actions icon field, else general icon field.
sap.ushell.components.tiles.utils.iconSelectOnValueHelpRequest(this, oEvent, true);
},
//adds new row in the tile actions table
addRow : function(){
sap.ushell.components.tiles.utils.addTileActionsRow(this.getView());
},
//delets row in the tile actions table
deleteRow : function(){
sap.ushell.components.tiles.utils.deleteTileActionsRow(this.getView());
}
});
}());
<core:View
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:form="sap.ui.layout.form"
xmlns:layout="sap.ui.layout"
xmlns:table="sap.ui.table"
xmlns:clayout="sap.ui.commons.layout"
xmlns:common="sap.ui.commons"
controllerName="view.Configuration">
<MessageStrip
id="messageStrip"
showIcon="true"
showCloseButton="false"
visible="false"/>
<form:SimpleForm
id="configuration"
maxContainerCols="8"
minWidth="1024"
editable="true">
<form:content>
<core:Title id="categoryCommon" text="{i18n>configuration.category.general}"/>
<Label text="{i18n>configuration.display_title_text}"/>
<Input id="titleInput" value="{/config/display_title_text}" width="100%" tooltip="{i18n>configuration.display_title_text.tooltip}" enabled="{/config/editable}" editable="{/config/isLocaleSuitable}"/>
<Label text="{i18n>configuration.display_subtitle_text}"/>
<Input id="subtitleInput" value="{/config/display_subtitle_text}" enabled="{/config/editable}" tooltip="{i18n>configuration.display_subtitle_text.tooltip}" editable="{/config/isLocaleSuitable}"/>
<Label text="{i18n>configuration.keywords}"/>
<Input id="keywordsInput" value="{/config/display_search_keywords}" enabled="{/config/editable}" width="100%" tooltip="{i18n>configuration.keywords.tooltip}" editable="{/config/isLocaleSuitable}"/>
<!--<Label text="{i18n>configuration.display_icon_url}"/>
<Input id="iconInput" value="{/config/display_icon_url}" enabled="{/config/editable}" placeholder="sap-icon://inbox" tooltip="{i18n>configuration.display_icon_url.tooltip}" liveChange="onConfigurationInputChange"
valueHelpRequest="onIconValueHelpRequest" showValueHelp="true"/>-->
<Label text="{i18n>configuration.display_info_text}"/>
<Input id="infoInput" value="{/config/display_info_text}" width="100%" enabled="{/config/editable}" tooltip="{i18n>configuration.display_info_text.tooltip}" editable="{/config/isLocaleSuitable}"/>
<core:Title id="categoryDynamicData" text="{i18n>configuration.category.dynamic_data}"/>
<Label text="Service Label(1)"/>
<Input id="serviceLabel1Input" value="{/config/service_first_label}" width="100%" enabled="{/config/editable}" tooltip="Service Label(1)"/>
<Label text="Service URL(1)"/>
<Input id="serviceUrl1Input" value="{/config/service_url1}" width="100%" enabled="{/config/editable}" tooltip="Service URL(1)"/>
<Label text="Service Label(2)"/>
<Input id="serviceLabel2Input" value="{/config/service_second_label}" width="100%" enabled="{/config/editable}" tooltip="Service Label(2)"/>
<Label text="Service URL(2)"/>
<Input id="serviceUrl2Input" value="{/config/service_url2}" width="100%" enabled="{/config/editable}" tooltip="Service URL(2)"/>
<Label text="Service Label(3)"/>
<Input id="serviceLabel3Input" value="{/config/service_third_label}" width="100%" enabled="{/config/editable}" tooltip="Service Label(3)"/>
<Label text="Service URL(3)"/>
<Input id="serviceUrl3Input" value="{/config/service_url3}" width="100%" enabled="{/config/editable}" tooltip="Service URL(3)"/>
<Label text="Lower Threshold"/>
<Input id="lowerThresholdInput" value="{/config/service_lower_threshold}" type="Number" enabled="{/config/editable}" width="6em" placeholder="{i18n>configuration.lower_threshold}" tooltip="{i18n>configuration.lower_threshold.tooltip}"/>
<Label text="Upper Threshold"/>
<Input id="upperThresholdInput" value="{/config/service_upper_threshold}" type="Number" enabled="{/config/editable}" width="6em" placeholder="{i18n>configuration.upper_threshold}" tooltip="{i18n>configuration.upper_threshold.tooltip}"/>
<Label text="{i18n>configuration.service_refresh_interval}"/>
<Input id="refreshInput" value="{/config/service_refresh_interval}" type="Number" enabled="{/config/editable}" width="6em" placeholder="{i18n>configuration.seconds}" tooltip="{i18n>configuration.seconds.tooltip}"/>
<core:Title id="categoryNavigation" text="{i18n>configuration.category.navigation}"/>
<Label text="{i18n>configuration.navigation_use_semantic_object}"/>
<CheckBox id="useLpdCheckbox" selected="{/config/navigation_use_semantic_object}" select="onCheckBoxChange" tooltip="{i18n>configuration.navigation_use_semantic_object.tooltip}" enabled="{/config/editable}"/>
<Label text="{i18n>configuration.semantic_object}"/>
<Input id="navigation_semantic_objectInput" width="100%" tooltip="{i18n>configuration.semantic_object.tooltip}" maxLength="30" liveChange="onConfigurationInputChange" valueHelpRequest="onValueHelpRequest" showValueHelp="true" showSuggestion="true"
enabled="{= ${/enabled} && ${/config/editable}}" value="{/value}"/>
<Label text="{i18n>configuration.navigation_semantic_action}"/>
<Input id="navigation_semantic_actionInput" value="{/config/navigation_semantic_action}" width="100%" maxLength="50" enabled="{= ${/config/navigation_use_semantic_object} && ${/config/editable}}"
tooltip="{i18n>configuration.navigation_semantic_action.tooltip}" liveChange="onConfigurationInputChange" valueHelpRequest="onActionValueHelpRequest" showValueHelp="true" showSuggestion="true"/>
<Label text="{i18n>configuration.navigation_semantic_parameters}"/>
<Input id="navigation_semantic_parametersInput" value="{/config/navigation_semantic_parameters}" width="100%" enabled="{= ${/config/navigation_use_semantic_object} && ${/config/editable}}"
tooltip="{i18n>configuration.navigation_semantic_parameters.tooltip}"/>
<Label text="{i18n>configuration.navigation_target_url}"/>
<Input id="targetUrl" value="{/config/navigation_target_url}" type="Url" width="100%" tooltip="{i18n>configuration.navigation_target_url.tooltip}"/>
<core:Title id="categoryTileActions" text="{i18n>configuration.category.tile_actions}"/>
<table:Table id="tileActions" rows="{/config/tile_actions_rows}" selectionBehavior="Row" selectionMode="Multi" visibleRowCount="3" enableColumnReordering="false" rowHeight="30px">
<table:Column id="menuItem" width="80px" tooltip="{i18n>configuration.tile_actions.table.menu_item_tooltip}">
<Label text="{i18n>configuration.tile_actions.table.menu_item}"/>
<table:template>
<common:TextField value="{menu_title}" enabled="{editable}" valueState="{valueState}"/>
</table:template>
</table:Column>
<table:Column id="targetType" width="85px" tooltip="{i18n>configuration.tile_actions.table.target_type_tooltip}">
<Label text="{i18n>configuration.tile_actions.table.target_type}"/>
<table:template>
<common:ComboBox id="targetTypeCB" value="{target_type}" enabled="{editable}" change="handleTargetTypeChange"/>
</table:template>
</table:Column>
<table:Column id="navigationTarget" width="162px" tooltip="{i18n>configuration.tile_actions.table.navigation_target_tooltip}">
<Label text="{i18n>configuration.tile_actions.table.navigation_target}"/>
<table:template>
<Input liveChange="onConfigurationInputChange" valueHelpRequest="onTileActionValueHelp" showValueHelp="{isTargetTypeIntent}" showSuggestion="{isTargetTypeIntent}" value="{navigation_target}" enabled="{editable}"/>
</table:template>
</table:Column>
<table:Column id="action" width="85px" tooltip="{i18n>configuration.tile_actions.table.action_tooltip}">
<Label text="{i18n>configuration.tile_actions.table.action}"/>
<table:template>
<common:TextField value="{action}" enabled="{isTargetTypeIntent}"/>
</table:template>
</table:Column>
<table:Column id="icon" width="110px" tooltip="{i18n>configuration.tile_actions.table.icon_tooltip}">
<Label text="{i18n>configuration.tile_actions.table.icon}"/>
<table:template>
<Input value="{icon}" placeholder="sap-icon://inbox" enabled="{/config/editable}" valueState="{iconValueState}" valueStateText="{iconValueStateText}" liveChange="onConfigurationInputChange" valueHelpRequest="onTileActionIconValueHelp"
showValueHelp="true"/>
</table:template>
</table:Column>
</table:Table>
<Label/>
<clayout:MatrixLayout>
<clayout:MatrixLayoutRow>
<clayout:MatrixLayoutCell hAlign="End">
<common:Button id="addRow" text="{i18n>configuration.tile_actions.table.add}" enabled="{/config/editable}" tooltip="{i18n>configuration.tile_actions.table.add_tooltip}" press="addRow" width="100px"/>
<common:Button id="deleteRow" text="{i18n>configuration.tile_actions.table.remove}" enabled="{/config/editable}" tooltip="{i18n>configuration.tile_actions.table.remove_tooltip}" press="deleteRow" width="100px"/>
</clayout:MatrixLayoutCell>
</clayout:MatrixLayoutRow>
</clayout:MatrixLayout>
</form:content>
</form:SimpleForm>
<HBox visible="false">
<Dialog id="selectIconDialog" leftButton="ok" rightButton="cancel" title="{i18n>configuration.select_icon}">
<content>
<layout:ResponsiveFlowLayout id="icons"/>
<HBox visible="true">
<Button id="ok" enabled="{/config/ok.enabled}" text="{i18n>configuration.ok}"/>
<Button id="cancel" text="{i18n>configuration.cancel}" press="onSelectIconClose"/>
</HBox>
</content>
</Dialog>
</HBox>
</core:View>
<?xml version="1.0" encoding="UTF-8"?>
<chip xmlns="http://schemas.sap.com/sapui2/services/Chip/1">
<implementation>
<sapui5>
<viewName>view/CustomTile.view.xml</viewName>
</sapui5>
</implementation>
<appearance>
<title>Custom Dynamic Applauncher</title>
<description>Custom Dynamic Applauncher Chip</description>
</appearance>
<contracts>
<consume id="bag" />
<consume id="configuration">
<parameters>
<parameter name="tileConfiguration"></parameter>
</parameters>
</consume>
<consume id="writeConfiguration" />
<consume id="configurationUi" />
<consume id="preview" />
<consume id="refresh" />
<consume id="search" />
<consume id="url" />
<consume id="visible" />
<consume id="actions" />
<consume id="types">
<parameters>
<parameter name="supportedTypes">tile,link</parameter>
</parameters>
</consume>
</contracts>
<parameters>
<parameter name="/UI2/ChipType">applauncher</parameter>
</parameters>
</chip>
(function() {
"use strict";
/*global jQuery, OData, sap, setTimeout, hasher */
jQuery.sap.require("sap.ui.core.IconPool");
jQuery.sap.require("sap.ushell.components.tiles.utils");
sap.ui.controller("demo.CustomTile", {
// handle to control/cancel browser's setTimeout()
timer: null,
// handle to control/cancel data.js OData.read()
oDataRequest: null,
_setComparisonData: function(oModel) {
var aData = {
1: {
"title": "Example 1",
"value": 25,
"color": "Neutral"
},
2: {
"title": "Example 2",
"value": 15,
"color": "Good"
},
3: {
"title": "Example 3",
"value": 35,
"color": "Critical"
}
};
oModel.setProperty("/comparisonModel", aData);
},
onInit: function() {
var oView = this.getView();
var oViewData = oView.getViewData();
var that = this;
var oModel = new sap.ui.model.json.JSONModel();
oModel.setProperty("/display_title_text", "Test Title");
oModel.setProperty("/display_subtitle_text", "Test Subtitle");
oModel.setProperty("/display_icon_url", "icon");
oModel.setProperty("/display_info_text", "wide view");
this._setComparisonData(oModel);
oView.setModel(oModel);
},
// convenience function to stop browser's timeout and OData calls
stopRequests: function() {
if (this.timer) {
clearTimeout(this.timer);
}
if (this.oDataRequest) {
try {
this.oDataRequest.abort();
} catch (e) {
jQuery.sap.log.warning(e.name, e.message);
}
}
},
// destroy handler stops requests
onExit: function() {
this.stopRequests();
},
// trigger to show the configuration UI if the tile is pressed in Admin mode
onPress: function() {
var oView = this.getView(),
oViewData = oView.getViewData(),
oModel = oView.getModel(),
sTargetUrl = oModel.getProperty("/nav/navigation_target_url"),
oTileApi = oViewData.chip;
if (oTileApi.configurationUi.isEnabled()) {
oTileApi.configurationUi.display();
} else if (sTargetUrl) {
if (sTargetUrl[0] === '#') {
hasher.setHash(sTargetUrl);
} else {
window.open(sTargetUrl, '_blank');
}
}
},
// dynamic data updater
onUpdateDynamicData: function() {
var oView = this.getView(),
oConfig = oView.getModel().getProperty("/config"),
nservice_refresh_interval = oConfig.service_refresh_interval;
if (!nservice_refresh_interval) {
nservice_refresh_interval = 0;
} else if (nservice_refresh_interval < 10) {
// log in English only
jQuery.sap.log.warning(
"Refresh Interval " + nservice_refresh_interval + " seconds for service URL " + oConfig.service_url1 + " is less than 10 seconds, which is not supported. " + "Increased to 10 seconds automatically.",
null,
"view.CustomTile.controller"
);
nservice_refresh_interval = 10;
}
if (oConfig.service_url1) {
this.loadData(nservice_refresh_interval);
}
},
extractData: function(oData) {
var name,
aKeys = ["results", "icon", "title", "number", "numberUnit", "info", "infoState", "infoStatus", "targetParams", "subtitle", "stateArrow", "numberState", "numberDigits", "numberFactor"];
if (typeof oData === "object" && Object.keys(oData).length === 1) {
name = Object.keys(oData)[0];
if (jQuery.inArray(name, aKeys) === -1) {
return oData[name];
}
}
return oData;
},
// tile settings action UI save handler
onSaveRuntimeSettings: function(oSettingsView) {
var
oViewModel = oSettingsView.getModel(),
oTileApi = this.getView().getViewData().chip,
oConfigToSave = this.getView().getModel().getProperty("/config");
oConfigToSave.display_title_text = oViewModel.getProperty('/title');
oConfigToSave.display_subtitle_text = oViewModel.getProperty('/subtitle');
oConfigToSave.display_info_text = oViewModel.getProperty('/info');
oConfigToSave.display_search_keywords = oViewModel.getProperty('/keywords');
// use bag contract in order to store translatable properties
var tilePropertiesBag = oTileApi.bag.getBag('tileProperties');
tilePropertiesBag.setText('display_title_text', oConfigToSave.display_title_text);
tilePropertiesBag.setText('display_subtitle_text', oConfigToSave.display_subtitle_text);
tilePropertiesBag.setText('display_info_text', oConfigToSave.display_info_text);
tilePropertiesBag.setText('display_search_keywords', oConfigToSave.display_search_keywords);
function logErrorAndReject(oError) {
jQuery.sap.log.error(oError, null, "view.CustomTile.controller");
}
// saving the relevant properteis
tilePropertiesBag.save(
// success handler
function() {
jQuery.sap.log.debug("property bag 'tileProperties' saved successfully");
// update the local tile's config - saving changes on the Model
this.getView().getModel().setProperty("/config", oConfigToSave);
// update tile's model for changes to appear immediately
// (and not wait for the refresh handler which happens every 10 seconds)
this.getView().getModel().setProperty('/data/display_title_text', oConfigToSave.display_title_text);
this.getView().getModel().setProperty('/data/display_subtitle_text', oConfigToSave.display_subtitle_text);
this.getView().getModel().setProperty('/data/display_info_text', oConfigToSave.display_info_text);
// call to refresh model which (due to the binding) will refresh the tile
this.getView().getModel().refresh();
}.bind(this),
logErrorAndReject // error handler
);
},
// configuration save handler
onSaveConfiguration: function(oConfigurationView) {
var
// the deferred object required from the configurationUi contract
oDeferred = jQuery.Deferred(),
oModel = oConfigurationView.getModel(),
// tile model placed into configuration model by getConfigurationUi
oTileModel = oModel.getProperty("/tileModel"),
oTileApi = oConfigurationView.getViewData().chip,
aTileNavigationActions = sap.ushell.components.tiles.utils.tileActionsRows2TileActionsArray(oModel.getProperty("/config/tile_actions_rows")),
// get the configuration to save from the model
configToSave = {
display_icon_url: oModel.getProperty("/config/display_icon_url"),
service_first_label: oModel.getProperty("/config/service_first_label"),
service_second_label: oModel.getProperty("/config/service_second_label"),
service_third_label: oModel.getProperty("/config/service_third_label"),
service_url1: oModel.getProperty("/config/service_url1"),
service_url2: oModel.getProperty("/config/service_url2"),
service_url3: oModel.getProperty("/config/service_url3"),
service_lower_threshold: oModel.getProperty("/config/service_lower_threshold"),
service_upper_threshold: oModel.getProperty("/config/service_upper_threshold"),
service_refresh_interval: oModel.getProperty("/config/service_refresh_interval"),
navigation_use_semantic_object: oModel.getProperty("/config/navigation_use_semantic_object"),
navigation_target_url: oModel.getProperty("/config/navigation_target_url"),
navigation_semantic_object: jQuery.trim(oModel.getProperty("/config/navigation_semantic_object")) || "",
navigation_semantic_action: jQuery.trim(oModel.getProperty("/config/navigation_semantic_action")) || "",
navigation_semantic_parameters: jQuery.trim(oModel.getProperty("/config/navigation_semantic_parameters")),
display_search_keywords: oModel.getProperty("/config/display_search_keywords")
};
//If the input fields icon, semantic object and action are failing the input validations, then through an error message requesting the user to enter/correct those fields
var bReject = sap.ushell.components.tiles.utils.checkInputOnSaveConfig(oConfigurationView);
if (!bReject) {
bReject = sap.ushell.components.tiles.utils.checkTileActions(oConfigurationView);
}
if (bReject) {
oDeferred.reject("mandatory_fields_missing");
return oDeferred.promise();
}
// overwrite target URL in case of semantic object navigation
if (configToSave.navigation_use_semantic_object) {
configToSave.navigation_target_url = sap.ushell.components.tiles.utils.getSemanticNavigationUrl(configToSave);
oModel.setProperty("/config/navigation_target_url", configToSave.navigation_target_url);
}
// use bag contract in order to store translatable properties
var tilePropertiesBag = oTileApi.bag.getBag('tileProperties');
tilePropertiesBag.setText('display_title_text', oModel.getProperty("/config/display_title_text"));
tilePropertiesBag.setText('display_subtitle_text', oModel.getProperty("/config/display_subtitle_text"));
tilePropertiesBag.setText('display_info_text', oModel.getProperty("/config/display_info_text"));
tilePropertiesBag.setText('display_search_keywords', configToSave.display_search_keywords);
var tileNavigationActionsBag = oTileApi.bag.getBag('tileNavigationActions');
//forward populating of tile navigation actions array into the bag, to Utils
sap.ushell.components.tiles.utils.populateTileNavigationActionsBag(tileNavigationActionsBag, aTileNavigationActions);
function logErrorAndReject(oError, oErrorInfo) {
jQuery.sap.log.error(oError, null, "CustomTile.controller");
oDeferred.reject(oError, oErrorInfo);
}
// use configuration contract to write parameter values
oTileApi.writeConfiguration.setParameterValues({
tileConfiguration: JSON.stringify(configToSave)
},
// success handler
function() {
var oConfigurationConfig = sap.ushell.components.tiles.utils.getConfiguration(oTileApi, false, false),
// get tile config data in admin mode
oTileConfig = sap.ushell.components.tiles.utils.getConfiguration(oTileApi, true, false),
// switching the model under the tile -> keep the tile model
oModel = new sap.ui.model.json.JSONModel({
config: oConfigurationConfig,
// keep tile model
tileModel: oTileModel
});
oConfigurationView.setModel(oModel);
// update tile model
oTileModel.setData({
data: oTileConfig,
nav: {
navigation_target_url: ""
}
}, false);
if (oTileApi.preview) {
oTileApi.preview.setTargetUrl(oConfigurationConfig.navigation_target_url);
oTileApi.preview.setPreviewIcon(oConfigurationConfig.display_icon_url);
oTileApi.preview.setPreviewTitle(oConfigurationConfig.display_title_text);
}
tilePropertiesBag.save(
// success handler
function() {
jQuery.sap.log.debug("property bag 'tileProperties' saved successfully");
// update possibly changed values via contracts
if (oTileApi.title) {
oTileApi.title.setTitle(
configToSave.display_title_text,
// success handler
function() {
oDeferred.resolve();
},
logErrorAndReject // error handler
);
} else {
oDeferred.resolve();
}
},
logErrorAndReject // error handler
);
tileNavigationActionsBag.save(
// success handler
function() {
jQuery.sap.log.debug("property bag 'navigationProperties' saved successfully");
},
logErrorAndReject // error handler
);
},
logErrorAndReject // error handler
);
return oDeferred.promise();
},
successHandleFn: function(index, oResult) {
var oConfig = this.getView().getModel().getProperty("/config");
this.oDataRequest = undefined;
var oData = oResult;
if (typeof oResult === "object") {
var uriParamInlinecount = jQuery.sap.getUriParameters(oConfig.service_url1).get("$inlinecount");
if (uriParamInlinecount && uriParamInlinecount === "allpages") {
oData = {
number: oResult.__count
};
} else {
oData = this.extractData(oData);
}
} else if (typeof oResult === "string") {
oData = {
number: oResult
};
}
var oConfig = this.getView().getModel().getProperty("/config");
var oDataComp = {
title: "",
value: "",
color: ""
};
switch (index) {
case 1:
oDataComp.title = oConfig.service_first_label;
break;
case 2:
oDataComp.title = oConfig.service_second_label;
break;
case 3:
oDataComp.title = oConfig.service_third_label;
break;
}
oDataComp.value = Number(oData.number);
if (oDataComp.value > Number(oConfig.service_upper_threshold)) {
oDataComp.color = "Critical";
} else if (oDataComp.value < Number(oConfig.service_lower_threshold)) {
oDataComp.color = "Good";
} else {
oDataComp.color = "Neutral";
}
// set data to display
//var oDataToDisplay = sap.ushell.components.tiles.utils.getDataToDisplay(oConfig, oDataComp);
var oModel = this.getView().getModel();
var sCompModelProp = oModel.getProperty("/data/comparisonModel");
if (!sCompModelProp) {
var oComparisonProp = {
1: {
"title": "",
"value": 0,
"color": "Neutral"
},
2: {
"title": "",
"value": 0,
"color": "Neutral"
},
3: {
"title": "",
"value": 0,
"color": "Neutral"
}
};
oModel.setProperty("/data/comparisonModel", oComparisonProp);
};
oModel.setProperty("/data/comparisonModel/" + index + "/", oDataComp);
// rewrite target URL
this.getView().getModel().setProperty("/nav/navigation_target_url",
sap.ushell.components.tiles.utils.addParamsToUrl(
this.navigationTargetUrl,
oDataToDisplay
));
},
// error handler
errorHandlerFn: function(oMessage) {
var oConfig = this.getView().getModel().getProperty("/config");
this.oDataRequest1 = undefined;
this.oDataRequest2 = undefined;
this.oDataRequest3 = undefined;
var sMessage = oMessage && oMessage.message ? oMessage.message : oMessage,
oResourceBundle = sap.ushell.components.tiles.utils.getResourceBundleModel()
.getResourceBundle();
if (oMessage.response) {
sMessage += " - " + oMessage.response.statusCode + " " + oMessage.response.statusText;
}
// log in English only
jQuery.sap.log.error(
"Failed to update data via service " + oConfig.service_url1 + ": " + sMessage,
null,
"view.CustomTile"
);
this.getView().getModel().setProperty("/data",
sap.ushell.components.tiles.utils.getDataToDisplay(oConfig, {
number: "???",
info: oResourceBundle.getText("dynamic_data.error"),
infoState: "Critical"
})
);
},
// configuration cancel handler
onCancelConfiguration: function(oConfigurationView, successHandler, errorHandle) {
// re-load old configuration and display
var oViewData = oConfigurationView.getViewData(),
oModel = oConfigurationView.getModel(),
// tile model placed into configuration model by getConfigurationUi
oTileModel = oModel.getProperty("/tileModel"),
oTileApi = oViewData.chip,
oCurrentConfig = sap.ushell.components.tiles.utils.getConfiguration(oTileApi, false, false);
oConfigurationView.getModel().setData({
config: oCurrentConfig,
tileModel: oTileModel
}, false);
},
// loads data from backend service
loadData: function(nservice_refresh_interval) {
var oDynamicTileView = this.getView(),
oConfig = oDynamicTileView.getModel().getProperty("/config"),
sUrl1 = oConfig.service_url1,
sUrl2 = oConfig.service_url2,
sUrl3 = oConfig.service_url3,
that = this;
var oTileApi = this.getView().getViewData().chip;
if (!sUrl1 && !sUrl2 && !sUrl3) {
return;
}
if (/;o=([;\/?]|$)/.test(sUrl1)) { // URL has placeholder segment parameter ;o=
sUrl1 = oTileApi.url.addSystemToServiceUrl(sUrl1);
}
if (/;o=([;\/?]|$)/.test(sUrl2)) { // URL has placeholder segment parameter ;o=
sUrl2 = oTileApi.url.addSystemToServiceUrl(sUrl2);
}
if (/;o=([;\/?]|$)/.test(sUrl3)) { // URL has placeholder segment parameter ;o=
sUrl3 = oTileApi.url.addSystemToServiceUrl(sUrl3);
}
//set the timer if required
if (nservice_refresh_interval > 0) {
// log in English only
jQuery.sap.log.info(
"Wait " + nservice_refresh_interval + " seconds before calling " + oConfig.service_url1 + " again",
null,
"view.CustomTile.controller"
);
// call again later
this.timer = setTimeout(that.loadData.bind(that, nservice_refresh_interval, false), (nservice_refresh_interval * 1000));
}
// Verify the the Tile visibility is "true" in order to issue an oData request
if (oTileApi.visible.isVisible() && !that.oDataRequest1) {
this.bIsDataRequested = true;
that.oDataRequest1 = OData.read({
requestUri: sUrl1,
headers: {
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
}
},
// sucess handler
this.successHandleFn.bind(this, 1),
this.errorHandlerFn.bind(this)
); // End of oData.read
that.oDataRequest2 = OData.read({
requestUri: sUrl2,
headers: {
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
}
},
// sucess handler
this.successHandleFn.bind(this, 2),
this.errorHandlerFn.bind(this)
); // End of oData.read
that.oDataRequest3 = OData.read({
requestUri: sUrl3,
headers: {
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
}
},
// sucess handler
this.successHandleFn.bind(this, 3),
this.errorHandlerFn.bind(this)
); // End of oData.read
}
},
// loads data once if not in configuration mode
refreshHandler: function(oDynamicTileController) {
var oTileApi = oDynamicTileController.getView().getViewData().chip;
if (!oTileApi.configurationUi.isEnabled()) {
oDynamicTileController.loadData(0);
} else {
oDynamicTileController.stopRequests();
}
},
// load data in place in case setting visibility from false to true
// with no additional timer registered
visibleHandler: function(isVisible) {
var oView = this.getView(),
oConfig = oView.getModel().getProperty("/config"),
nservice_refresh_interval = oConfig.service_refresh_interval;
if (isVisible) {
if (!this.bIsDataRequested) {
//tile is visible and data wasn't requested yet
this.refreshHandler(this);
}
if (nservice_refresh_interval) {
//tile is visible and the refresh interval isn't set to 0
this.refreshHandler(this);
}
} else {
this.stopRequests();
}
}
});
}());