Andy in the Cloud

From BBC Basic to and beyond…

1 Comment

User Notifications with the Utility Bar API

utilityprogressIn this blog, I want to highlight a couple of great UI features provided by the Utility Bar in Lightning Experience. These are relatively new and accessed only via the Utility Bar API, so are not immediately accessible. This blog is based on code and material I prepared for Dreamforce 2017. However, I did not have time to dig into the code during that session so this blog provides that opportunity. My session also covered other cool features in Lightning Experience, such as the amazing App Console mode!

Enabling and Understanding the Utility Bar API
The utility bar API is enabled at a component level though it does have access to the whole utility bar. You can specify the lightning:utilityBarAPI component in any component, regardless if its in the utility bar or not. This component will not display anything but it does have a very useful selection of methods!

<lightning:utilityBarAPI aura:id="utilitybar"/>

In your component code you simple access it like any other component.

var utilityAPI = cmp.find("utilitybar");

Once you have access to an instance of the component you can call any of its methods. All methods take a utilityId parameter. Although if you call it within the context of a component running in the utility bar you can omit this parameter and the API will discover it for you. All the methods take a single JavaScript object with properties representing the parameters to the method.

utilityAPI.setPanelHeaderLabel({ label: "My Label" });

One interesting design aspect of these methods is they do not respond immediately, all responses are returned via a callback. To do this the API uses the JavaScript Promises pattern. Fortunately, its a pretty easy convention to pick up and use. It is worth taking the time to understand, it has fast become defacto callback approach.

Providing Notifications


There are many occasions that you want to notify the user of something that’s happened since they last logged in or during login as a result of some background process. The setUtilityHighlighted method is a good way to drive such notifications.

You can, of course, evaluate on initialize of your component, but it’s worth considering using Platform Events, it’s really easy to send them from your Apex code or Process Builder and you can easily integrate my Streaming API component to respond to the event. The code below is a very simple isolated example using browser timers, but it helps illustrate the API and give you a basis to build one.

   label="{! v.readNotification ? 'Mark as Read' : 'Wait' }" 
<aura:if isTrue="{!v.readNotification}">
   <ui:message title="Confirmation"severity="info">
      This is a confirmation message.</ui:message>
    demoNotifications: function (cmp, event) {
		var utilityAPI = cmp.find("utilitybar"); 
        var readNotification = cmp.get('v.readNotification');
        if(readNotification == true) {
			utilityAPI.setUtilityHighlighted({ highlighted : false });                        
            cmp.set('v.readNotification', false);
        } else {
            setTimeout($A.getCallback(function () {
                utilityAPI.setUtilityHighlighted({ highlighted : true });            
				cmp.set('v.readNotification', true);
            }), 3000);                    

Providing Progress Updates


By using a combination of setUtilityLabel and setUtilityIcon you can create an eye-catching progress updating effect. This sample is a pretty simple browser timer based example. However, you could again use Platform Events to send events as part of a Batch Apex execution to update on progress or just poll the AsyncApexJob object.

    label="{! v.isProgressing ? 'Stop' : 'Start' }" 
    value="{! v.progress }" size="large" />
demoProgressIndicator: function (cmp, event) {
    var utilityAPI = cmp.find("utilitybar"); 
    if (cmp.get('v.isProgressing')) {
        // stop
        cmp.set('v.isProgressing', false);
        cmp.set('v.progress', 0);
        cmp.set('v.progressToggleIcon', false);
        utilityAPI.setUtilityLabel({ label : 'Utility Bar API Demo' });                    
        utilityAPI.setUtilityIcon({ icon : 'thunder' } );                                    
    } else {
        // start
        cmp.set('v.isProgressing', true);
        cmp._interval = setInterval($A.getCallback(function () {
            var progresToggleIcon = 
               cmp.get('v.progressToggleIcon') == true ? false : true;
            var progress = cmp.get('v.progress');
            cmp.set('v.progress', progress === 100 ? 0 : progress + 1);
            cmp.set('v.progressToggleIcon', progresToggleIcon);
                { label : 'Utility Bar API Demo (' + progress + '%)' });        
                { icon : progresToggleIcon == true ? 'thunder' : 'spinner' });
        }), 400);


There is still plenty to dig into in the code samples from the session. You can also deploy the sample code into an org and try out some of the other interactive API demos. Enjoy!



Understanding how your App Experience fits into Lightning Experience

Lightning Experience is not just a shiny new looking version of Salesforce Classic. Nor is it just some new cool technology for building device agnostic responsive rich clients. Its a single place where users access your application and of course others from Salesforce and those from AppExchange. Its essentially an application container a home for apps!

Like any home, its important to know how it works and how to maximise your experience in it. How do you make the occupants (your users) feel like its one place and not just bolted together. I decided to create the following graphics to summarise Lightning Experience container features. I have removed all the default actions, components you get from Salesforce, so we can easily see what it offers in a raw state.

Imagine the Widget App has several UIs to it…

  • Home page, customisable by the user using your components and others
  • Widgets tab that allows user to manage the widget records
  • Widget Manager organise your widgets, easy to access any time
  • Widget Utilities common information, contextual, easy to access any time
  • Widget Builder is a completly custom UI for constructing bigger widgets

Home Page, Utility Bar and Global Actions

The Home page is actually shared  between all applications in Lightning Experience. You can choose to include it in your tabs or not. If you do, users can customise it with Lightning App Builder by dragging Lightning Components on it that you or others provide. New to Global Actions for Spring’17 is the ability to add Lightning Actions.


widget.pngWhen you see the cog image with the Lightning logo in it, it means that that space can be anything you imagine! Because that space is driven by a Lightning Component!

Global Action Popup Management

When the user selects a Global Action, Lightning Experience automatically provides some useful features. The popup allows the user to close it, minimise or maximise it.

lexcontainer3Record Page and Record Actions

Record page content is determined by a number of things, object Actions, object Record Layout and Lightning pages (created by Lighting App Builder) associated with the object. Lightning pages are scoped based on the active application, profile or record type.


Lightning Tabs

Provide the biggest real-estate for your entirely custom UI needs. The utility bar and global actions are however still available for your users to call on at any time!


Increasingly in each Salesforce release we are seeing more and more extensibility emerging. The above graphics are designed to get you thinking about how best to leverage Lightning Experience when designing your application. Read my other blogs relating to Utility Bar and Lightning Actions.