Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
kammaje_cis
Active Contributor
As we know Fiori gets its user image from JAM. It is common that not every customer have JAM integration, so most of the customers end up having a user icon there instead of having user's image.

If you are not yet on Fiori 2.0, here is a blog on how to get the user image. But if you are on Fiori 2.0, hack mentioned in the blog will no longer work as as SAP has changed the architecture of fetching the image. Also there is a 'Me' area which has another placeholder for a user image.

At ConvergentIS, we are early adopters of Fiori 2.0 and wanted to get this feature. This blog outlines how you can achieve getting user image for Fiori 2.0.

Here is the end result.



Step 1. Decide where you are going to get the image from and get the URL ready. You might get it from your ECC, or from any other external site. We got it from Office365 profile.

Step 2. Create a UI plugin for Fiori launchpad and assign this to all the users in your Org. Use this link as your guide.

That is it. You are all good.

Note: If you are sourcing the image from an external site, you might need user's info to calculate the right URL. Use the ushell API to get user info like user name, email etc.
We used the image from our sharepoint user profile and needed user's email to fetch the profile photo.

Here is the complete code of the UI plugin.
(function() {
"use strict";

/*global jQuery, sap */
jQuery.sap.declare("cis.FLPugin.Component");
jQuery.sap.require("sap.ui.core.Component");

var sComponentName = "cis.FLPugin";

// new Component
sap.ui.core.Component.extend("cis.FLPugin.Component", {

metadata: {
version: "@version@",
library: "sap.ushell.demo.UIPluginSampleAddHeaderItems"
},

_getRenderer: function() {
var that = this,
oDeferred = new jQuery.Deferred(),
oShellContainer,
oRenderer;

that._oShellContainer = jQuery.sap.getObject("sap.ushell.Container");
if (!that._oShellContainer) {
oDeferred.reject(
"Illegal state: shell container not available; this component must be executed in a unified shell runtime context.");
} else {
oRenderer = that._oShellContainer.getRenderer();
if (oRenderer) {
oDeferred.resolve(oRenderer);
} else {
// renderer not initialized yet, listen to rendererCreated event
that._onRendererCreated = function(oEvent) {
oRenderer = oEvent.getParameter("renderer");
if (oRenderer) {
oDeferred.resolve(oRenderer);
} else {
oDeferred.reject("Illegal state: shell renderer not available after recieving 'rendererLoaded' event.");
}
};
that._oShellContainer.attachRendererCreatedEvent(that._onRendererCreated);
}
}
return oDeferred.promise();
},

init: function() {
var that = this,
fgetService = sap.ushell && sap.ushell.Container && sap.ushell.Container.getService;
this.oCrossAppNavigator = fgetService && fgetService("CrossApplicationNavigation");

this._getRenderer().fail(function(sErrorMessage) {
jQuery.sap.log.error(sErrorMessage, undefined, sComponentName);
})
.done(function(oRenderer) {
var imageSource = "https://outlook.office365.com/owa/service.svc/s/GetPersonaPhoto?email=" + sap.ushell.Container.getService("UserInfo").getUser().getEmail();
//Below is for the small icon on top left
$("#meAreaHeaderButton").html( "<img style='max-width: 100%; height:auto;' src=" + imageSource + ">" );

//Below is for the Me area
var biggerImage = imageSource + "&UA=0&size=HR96x96";
sap.ushell.Container.getService("UserInfo").getUser().setImage(biggerImage);
});
},

exit: function() {
if (this._oShellContainer && this._onRendererCreated) {
this._oShellContainer.detachRendererCreatedEvent(this._onRendererCreated);
}
}
});
})();

 

Disclaimer: This is a hack and there is no guarantee that this hack would work seamlessly in further versions of Fiori Launchpad. SAP would not support such hacks.

However, the insane hacker in me would suggest another unsupported hack 😉 . Copy the Fiori Launchpad itself (copy the BSP /UI2/USHELL) to have your own Launhcpad and perform your changes there or keep it as a backup.
33 Comments
former_member200665
Participant
0 Kudos
Very nicely explained Krishna . . .  Keep it up !
HenrikBruentrup
Explorer
0 Kudos

Hi Krishna,

thank you for this nice tutorial!

However, I cannot get the big profile icon in the MeArea to show the designated image. All other placeholders (one in header & two in settings) are being replaced correctly. Any idea why just the big one is not working?

I did not change any of your code other than posted below.

.done(function(oRenderer) {

var imageSource = "http://XXX:ZZZ/sap/bc/ui5_ui5/sap/zuserimage/profileImage.jpg";

//Below is for the small icon on top left
$("#meAreaHeaderButton").html( "<img style='max-width: 100%; height:auto;' src=" + imageSource + ">" );

//Below is for the Me area
sap.ushell.Container.getService("UserInfo").getUser().setImage(imageSource);

});

Best regards,

Henrik

kammaje_cis
Active Contributor
0 Kudos
Try providing a relative URL instead of full URL. May be the call is failing due to SOP.
former_member228315
Discoverer
Hi Krishna,

i only don't understand where you have to create this plugin? is it also in launchpad (designer) or is it in the hana cloud platform? or eclipse and upload it?

thanks.
 
former_member197071
Participant
0 Kudos
Hi Krishna,

 

Thanks for your contribution. It is really useful. How to integrate JAM with Fiori? I have a requirement.
Former Member
0 Kudos
Hi,

is there a standard way to use an image? For example upload it in Transaction SU01 ?
former_member197071
Participant
0 Kudos
Krishna,

The link that you provided in Step 2 says we need to create target mapping, but in which catalog to create it? Do I need to create a Z catalog for it?
0 Kudos
Hi Krishna,

 

I am using full URL (same for both Me area and small icon) , that too , an absolute URL from Google. I am experiencing same issue as that of Henrik. I have seen no call is getting failed in my case.

@Henrik : By any chance, are you able to resolve the error?

Best Regards

Parth Budhiraja
0 Kudos
Hi Henrik,

Are you able to resolve the  issue?

 

Regards

Parth
former_member25364
Participant
0 Kudos
Hello

I have created a Z catalog in which I have set the target mapping as explained in the link of the step 2.

I have created the role with the catalog and I have assigned my user. But the Globe does not appear in the launchpad.

Could you help ?

Could you be more explicit about the creation of the plugin ? which IDE ? how and where do you deploy the plugins ?

Regards

Emmanuel

 

 

 

 
kammaje_cis
Active Contributor
0 Kudos
Yeah, it has to be a Z catalog and this catalog should be assigned to all employees (by roles).
Former Member
0 Kudos
Hello Kishore,

 

First of all thanks for this brilliant post. However like few others I am struggling to make sense about UI plugin file. I was able to add globe as per standard documentation and was able to make it work but for that I assume file UIPluginSampleAddHeaderItems in following location already exists /sap/bc/ui5_demokit/test-resources/sap/ushell/demoapps/UIPluginSampleAddHeaderItems/Component.js

 

And following code is inside this file:

 
(function () {
"use strict";

/*global jQuery, sap */
jQuery.sap.declare("sap.ushell.demo.UIPluginSampleAddHeaderItems.Component");
jQuery.sap.require("sap.ui.core.Component");

var sComponentName = "sap.ushell.demo.UIPluginSampleAddHeaderItems";

// new Component
sap.ui.core.Component.extend("sap.ushell.demo.UIPluginSampleAddHeaderItems.Component", {

metadata : {
version: "@version@",
library: "sap.ushell.demo.UIPluginSampleAddHeaderItems"
},

/**
* Returns the shell renderer instance in a reliable way,
* i.e. independent from the initialization time of the plug-in.
* This means that the current renderer is returned immediately, if it
* is already created (plug-in is loaded after renderer creation) or it
* listens to the &quot;rendererCreated&quot; event (plug-in is loaded
* before the renderer is created).
*
* @returns {object}
* a jQuery promise, resolved with the renderer instance, or
* rejected with an error message.
*/
_getRenderer: function () {
var that = this,
oDeferred = new jQuery.Deferred(),
oShellContainer,
oRenderer;

that._oShellContainer = jQuery.sap.getObject("sap.ushell.Container");
if (!that._oShellContainer) {
oDeferred.reject("Illegal state: shell container not available; this component must be executed in a unified shell runtime context.");
} else {
oRenderer = that._oShellContainer.getRenderer();
if (oRenderer) {
oDeferred.resolve(oRenderer);
} else {
// renderer not initialized yet, listen to rendererCreated event
that._onRendererCreated = function (oEvent) {
oRenderer = oEvent.getParameter("renderer");
if (oRenderer) {
oDeferred.resolve(oRenderer);
} else {
oDeferred.reject("Illegal state: shell renderer not available after recieving 'rendererLoaded' event.");
}
};
that._oShellContainer.attachRendererCreatedEvent(that._onRendererCreated);
}
}
return oDeferred.promise();
},

init: function () {
var that = this,
fgetService = sap.ushell && sap.ushell.Container && sap.ushell.Container.getService;
this.oCrossAppNavigator = fgetService && fgetService("CrossApplicationNavigation");

this._getRenderer().fail(function (sErrorMessage) {
jQuery.sap.log.error(sErrorMessage, undefined, sComponentName);
})
.done(function (oRenderer) {

var oPluginParameters = that.getComponentData().config, // obtain plugin parameters
sRendererExtMethod;

if (oPluginParameters.position === "end") {
sRendererExtMethod = "addHeaderEndItem";
} else if (oPluginParameters.position === "begin") {
sRendererExtMethod = "addHeaderItem";
} else {
jQuery.sap.log.error("Invalid 'position' parameter, must be one of <begin, end>", undefined, sComponentName);
return;
}

if (typeof oRenderer[sRendererExtMethod] === "function") {
oRenderer[sRendererExtMethod](
"sap.ushell.ui.shell.ShellHeadItem", {
tooltip: oPluginParameters.tooltip || "",
icon: sap.ui.core.IconPool.getIconURI(oPluginParameters.icon || "question-mark"),
press: function () {
sap.m.MessageToast.show(oPluginParameters.message || "Default Toast Message");
}
},
true,
false);
} else {
jQuery.sap.log.error("Extension method '" + sRendererExtMethod + "' not supported by shell renderer", undefined, sComponentName);
return;
}
});
},

exit: function () {
if (this._oShellContainer && this._onRendererCreated) {
this._oShellContainer.detachRendererCreatedEvent(this._onRendererCreated);
}
}
});
})();


And according the UI plugin code you provided, does this need to create a new UI plugin file or do I have to modify above code to align as per your code?

Really appreciate if you could provide some input?

Best Regards,
Arpit
former_member193947
Participant
0 Kudos
Hello Krishna,

We are trying to show the User's full name next to the image icon on the top left. Is there an option to do that ? What you showed in your blog next to the user image is again a picture ?

Thanks.
herbstt
Explorer
0 Kudos
Hi Henrik,

the problem is located in the following coding line:

var biggerImage = imageSource + "&UA=0&size=HR96x96";

Don't use the parameters "&UA=0&size=HR96x96" and it works fine.

Fiori Launchpad matches automatically the correct size for the image.

Best regards,

Tobias
former_member193947
Participant
0 Kudos
Hello Krishna,

We followed your code but still the icon image is not getting displayed. We are trying to source from an external url, whereas relative URL is working fine. Any other ways to source icon image ?

Thanks.
0 Kudos
Hello Krishna

Thanks for the tutorial!

I followed your code, also with the image from Office365, but I get an "401 unauthorized" error. Do you know how to solve this?

Thanks.
FrankKrause
Participant
0 Kudos
Hi  Krishna,

nice tutorial but I'm asking myself why do I have to spent so much efforts on that. The Image URL should be part of the basic services...
0 Kudos
Hi Krishna,

I've followed your guide and now am able to see the user image for the small icon on the top left corner.  But i don't see the image in the "Me area".





After doing some inspecting with chrome devtools I tried to modify some jquery code in the after function so as you may see in the second image i can change the icon but not always works. Below the code i modified:
			this._getRenderer().fail(function(sErrorMessage) {
jQuery.sap.log.error(sErrorMessage, undefined, sComponentName);
})
.done(function(oRenderer) {
//var imageSource = "https://outlook.office365.com/owa/service.svc/s/GetPersonaPhoto?email=" + sap.ushell.Container.getService("UserInfo").getUser().getEmail();

var imageSource = "/sap/public/bc/ui2/logon/custom_images/Mario_Nintendo.png"
var imageSourceBIG = "/sap/public/bc/ui2/logon/custom_images/mbig.png"

//Below is for the small icon on top left
$("#meAreaHeaderButton").html( "<img style='max-width: 100%; height:auto;' src=" + imageSource + ">" );

//Below is for the Me area
//var biggerImage = imageSource; //+ "&UA=0&size=HR96x96";
sap.ushell.Container.getService("UserInfo").getUser().setImage(imageSourceBIG);
});
},

exit: function() {
if (this._oShellContainer && this._onRendererCreated) {
this._oShellContainer.detachRendererCreatedEvent(this._onRendererCreated);
}
},

after: function(){
var imageSourceBIG = "/sap/public/bc/ui2/logon/custom_images/mbig.png"
$(".sapUshellMeAreaUserImage").html( "<img style='max-width: 100%; height:auto;' src=" + imageSourceBIG + ">" );
}

Do you have any suggestion?

Thanks in advance.
former_member186852
Contributor
0 Kudos
Hi Experts ,

I have developed the same functionality. Image is not appearing after navigation(i.e. once i click on any tile , Image is not appearing . I have to refresh the page then its showing. )

 

Regards ,

Meghal Shah
SimoneCattozzi
Participant
0 Kudos
I've moved youre code in ".done" event and it worked!

A simple adjustement in style of "img" has been necessary to fix image position
var smallImage = imageBaseUrl + "?size=SMALL";
//Below is for the small icon on top left
$("#meAreaHeaderButton").html( "<img style='max-width: 100%; height:auto;' src=" + smallImage + ">" );

//Below is for the Me area
var biggerImage = imageBaseUrl + "?size=BIG";
$(".sapUshellMeAreaUserImage").html( "<img style='max-width: 100%; height:auto; position:absolute; left: -0px; top: -0px;' src=" + biggerImage + ">" );

 



 
VijayCR
Active Contributor
0 Kudos
Very Informative blog what i am missing here is How can i create component.js file with out modifying the standard component.js which is given for the launch pad.I understand i can over ride the rendering using target mapping but what will be the path of my component.js file ??
kammaje_cis
Active Contributor
0 Kudos
Hi Vijay,

This is the concept of Launchpad plugins.  These are separate apps which get executed upon launch of Fiori Launchpad. You can read about it here. https://help.sap.com/viewer/cc1c7615ee2f4a699a9272453379006c/7.5.9/en-US/d58602924af34fc3816d44ddb6a9e911.html
VijayCR
Active Contributor
0 Kudos
Hello Krishna,

Thanks Now I understand I need to create Custom Z * BSP app and then assign that path and component name in the target mapping in URL and ID give the app name and component name.

But just one more small thing why have you not used the new Webide architecture using the manifest.josn ?

Thanks,

Vijay
VijayCR
Active Contributor
0 Kudos
Hi getting the below error in launch pad

jquery.sap.global-dbg.js Exception occurred while creating new sap.ui.core.ws.SapPcpWebSocket. Message: Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed. -
VijayCR
Active Contributor
0 Kudos
Hello Krishna,

Please let me know how to solve the error 'Could not load user image from: https://outlook.office365.com/owa/service.svc/s/GetPersonaPhoto?email= - sap.ushell.renderers.fiori2.Shell.view'

GetPersonaPhoto:1 GET https://outlook.office365.com/owa/service.svc/s/GetPersonaPhoto?email=@1.5 401 (Unauthorized)

Thanks,

Vijay
0 Kudos
Hi Krishna,

 

Can you please suggest the code to sync user image of outlook with FLP in SAP Portal.

As I tried your suggested code but it is not working in SAP Portal FLP.

 

Thanks in advance

Purushottam
benlim
Contributor
0 Kudos
The original code is not reflected expected results whereby the image appear a few seconds then disappear after all the request is finished loaded. I've open another post for this discussion under Custom User Image in SCP Portal Fiori 2.0.

Appreciate if you could shed some lights on this.

Thanks.

Regards,

Ben

 
MichalUhlir
Explorer
0 Kudos
Hello,

you are almost done. Instead of using direct change of html code with this statement:

$("#meAreaHeaderButton").html( "<img style='max-width: 100%; height:auto;' src=" + imageSource + ">" );

You need to change icon model:

sap.ui.getCore().byId("meAreaHeaderButton").setIcon(imageSource);

Then, you image will not disappear when you navigate to app or other page.

Best Regards,

Michal
former_member327199
Participant
0 Kudos
Thanks Krishna for Wonderful blog. Minor tweaks as mentioned by Tobias and Michal and All Good.
0 Kudos
I am also getting same issue. please share if you have any solution.

 

Thanks
Amita
hschaefer123
Participant
0 Kudos
Thanks Krishna for the blog.

Just some thaughts from my side.

With cFLP and Horizon Theme, the shell avatar image seems to be set by userInfo.
// User Image
var oUser = sap.ushell.Container.getService("UserInfo").getUser();
var sAvatarSource = sap.ui.require.toUrl("your/name/space")
+ "/graph/v1.0/users/" + oUser.getEmail() + "/photos/96x96/$value";

// Shell header me avatar (auto set by refering to oUser.getImage())
/*
var oAvatar = sap.ui.getCore().byId("meAreaHeaderButton");
oAvatar.setSrc(sAvatarSource);
*/

// Me area
oUser.setImage(sAvatarSource);

Anyhow, if you need to manipulate existing meAreaHeaderButton, than i would prefer getting the underlying sapui5 avatar control (see my code in comments) with getCore().byId(..) and just setting the avatar source.

Anyhow for me, both avatar icons are workling out-of-the-box setting just the oUser image, but i am using the btp cloud launchpad (not on premise).

Also to get the Azure user icons, i needed a destination using a technical user to be allowed to read users avatar. It would also be possible with a on-behalf-of destination flow, but than, you would need a service endpoint like SAP Bridge or something similar.

Thanks for sharing.

Also, the is an ongoing efford to have a collection of shell plugins, so maybe also blog is relevant!

Best regards
Holger

 

 
0 Kudos
HI krishnakishor.kammaje2

What is the license for the code above?

Thanks in advance!
Andrei
Labels in this area