Using Background Utility Items on Lightning Console

In this blog, I am going to how to use the background utility items that the runs from the background of utility bar of a console. Utilities harness the power of Lightning components. When you set up a utility bar, you select which Lightning components to use as utilities. However, not all Lightning components can be utilities. To be added to a utility bar, a Lightning component must implement the flexipage:availableForAllPageTypes interface. To run the utility bar from the background we need to implement the lightning:backgroundUtilityItem interface. lightning: backgroundUtilityItem is used to create a component that fires and responds to events without rendering in the utility bar. Background utility items are added to an app the same way normal utility items are, but they don’t appear in the utility bar. In this example, the component implements lightning:backgroundUtilityItem and listens for lightning:tabCreated events when the app loads. The component prevents users not to open more than 3 cases tab. If the user is trying to open the more than 3 tabs then it will close the first open tab automatically.

Step 1: Create a component

Here is the simple component that will run background. this component will run at the background and close the tab automatically when user trying to open the fourth tab.

<aura:component implements="lightning:backgroundUtilityItem,force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="limit" default="3" type="Integer" />
    <aura:handler event="lightning:tabCreated" action="{!c.onTabCreated}" />
    <lightning:workspaceAPI aura:id="workspace" />
</aura:component>
({
    onTabCreated: function(cmp) {
        var workspace = cmp.find("workspace");
        var limit = cmp.get("v.limit");
        workspace.getAllTabInfo().then(function (tabInfo) {
            console.log(tabInfo);
            if (tabInfo.length > limit) {
                workspace.closeTab({
                    tabId: tabInfo[1].tabId
                });
            }
        });
    }
})

Step 2: Add a Utility Bar to Lightning Apps

  • From Setup, enter App in the Quick Find box, then select App Manager.
  • To edit the existing app, click Edit in the drop-down menu next to your Lightning App.
  • Click the Utility Items tab and add the above created component to utility bar

Select the component and save it

Testing

go to the console and try to open the more than three cases now it will close the first tab automatically.

Key Consideration  

When creating a utility bar for your app, keep these things in mind:

  • Utility bars created using the Lightning App Wizard or in the Lightning App Builder can be assigned to only one Lightning app. However, utility bars created using the API can be assigned to multiple Lightning apps.
  • The utility bar doesn’t support Visualforce pages or components.
  • The utility bar doesn’t fully support the Chatter Publisher and Feed components.
  • The History utility works in Lightning console apps only.
  • The Omni-Channel utility works in the Lightning Service Console app only.

 

Salesforce Lightning Console change Case Tab Icon dynamically

In this blog, I am going to show how to change the console case tab icon dynamically. standard salesforce case icon is Briefcase.In this post, i am going show how to change the case icon dynamilly based on the case Origin. If case origin is the phone we will show the case tab icon as phone .if the case origin is email then we will show the tab icon as email. here are the simple apex class and component

Apex Class

public class CaseIconChange {
    @AuraEnabled
    public  static string getIcon(Id caseId)
    {
        string source =caseId;    
        Case caseRec = [select Id, CaseNumber, Origin from Case where Id =: caseId];
        if(caseRec.Origin!=null && caseRec.Origin!='')
        {
            if(caseRec.Origin=='Phone'){
                source='call-'+caseRec.Origin;
            }
            if(caseRec.Origin=='Web'){
                source='live_chat-'+caseRec.Origin;
            }
            if(caseRec.Origin=='Email'){
                source='email-'+caseRec.Origin;
            }
        }   
        return source;
    }
}

The above apex class will return the case icon string to component based on the case origin.

Lightning Component 

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId"
                controller="CaseIconChange" >
    <lightning:workspaceAPI aura:id="workspace" />
    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>   
    <aura:handler event="force:refreshView" action="{!c.doInit}" />  
</aura:component>
({
    doInit : function(cmp, event, helper) {
        var workspaceAPI = cmp.find("workspace");
        workspaceAPI.getFocusedTabInfo().then(function(response) {
            var focusedTabId = response.tabId; 
            var action = cmp.get("c.getIcon");
            action.setParams({ caseId: response.recordId});
            action.setCallback(this,
                               $A.getCallback(function(response1)
                                              {
                                                  var state = response1.getState();    
                                                  console.log('state'+state);
                                                  if (state == "SUCCESS")  
                                                  {
                                                      var result= response1.getReturnValue();
                                                      var finalString=result.split("-");
                                                      workspaceAPI.setTabIcon({tabId: focusedTabId, icon: "standard:"+ finalString[0], iconAlt: finalString[1]});   
                                                  }
                                              }
                                             ));
            $A.enqueueAction(action);       
            
        })
        
    }
})

Adding a component to Record Page 

Now add the above component into the lightning record page as shown below.T o change the case icon indicator you need to invoke the above create component. So I add this component to the record page.

Testing 

Now go to the case and change the origin. based on the origin it will change the icon . in the example I am changing the origin phone which changes the case tab icon to the phone

if we change the origin to the web then it will change the case icon to chat as shown below.

 

Using Page Context in the Utility Bar API

In this blog, I am going to show how to use the utility bar API in page context which means we will be communicating the page records id to utility bar.In both Lightning console apps and standard navigation apps, utilities can respond to the context of the current page. Set implements=”force:hasRecordId” on a Lightning component used in the utility bar to access the recordId of the record a user is viewing.This simple component implements force:hasRecordId and listens for changes to the record being viewed. The following example we will be showing the key field on the case from the utility bay when the user opens the case from the console.

<aura:component implements="force:hasRecordId,flexipage:availableForAllPageTypes"
                access="global">
    
    <aura:attribute name="cases" type="Case"/>
    <aura:attribute name="caseFields" type="String[]" default="Comments,Status,Subject,Priority,"/>
    <force:recordData aura:id="cases"
                      recordId="{!v.recordId}"
                      targetFields="{!v.caseFields}"
                      layoutType="FULL"/>
    <div class="slds-clearfix">
        <lightning:card iconName="standard:Case" title="{! 'Case Details for ' + v.recordId}">
            
            <lightning:recordForm aura:id="caseForm"
                                  recordId="{!v.recordId}"
                                  objectApiName="Case"
                                  fields="{!v.caseFields}"
                                  columns="1"
                                  mode="View"/>
            
        </lightning:card>
        
    </div>
</aura:component>

Now go to the App manager and all this utility bar to the console

  • From Setup, enter App in the Quick Find box, then select App Manager.
  • To edit the existing app, click Edit in the drop-down menu next to your Lightning App.
  • Click the Utility Items tab and add the above  created component to utility bar

After adding the utility bar to console you can see the utility bar will open case details when the user is open the case as shown below

 

Lightning Console disabling tab closing

In this blog, I will show one of the coolest features of the console to disable the close record action on Lightning experience. In this example, if any high priority cases are created, case description is required to close the tab otherwise we will be disabling the close icon on the tab. we can use a console API to prevent agents from closing tabs until they’ve completed all required work on a case. The console API  can disable a tab from closing using the disableTabClose method. You can prevent tabs from being closed in two ways:
  1. Disable a primary tab. Its subtabs remain unlocked unless disableTabClose is invoked on them individually.
  2. Disable a subtab. This also disables its enclosing primary tab.

disableTabClose is fully supported when you click the close-tab icon or when invoked via API. Other ways of invoking it aren’t fully supported and may not behave as you want them to. Macros aren’t fully supported. If disableTabClose is invoked via a macro, the error message might not appear, but the agent still won’t be able to close the tab in most cases. And of course, we can only lead a horse to water. An agent can still close the browser window. But hey, can’t say we didn’t try!

Tab behavior when records are deleted

When a primary tab is disabled and its record is deleted, that whole set of tabs (primary + subtabs) automagically closes.

When a subtab is disabled and its record is deleted, the subtab remains open but refreshes as a blank tab (although any sidebar components will render).

Code

Here is the simple code.

public class DisableCloseTab {
    
    public static DisableCloseTabService service = new DisableCloseTabService();
    @AuraEnabled 
    public static boolean disableCase(String caseId){
        return service.getDisbaleStatus(caseId);
    }
    
}
public class DisableCloseTabService {
    public boolean getDisbaleStatus(String caseId){
        Case c = [Select id ,Priority , Description from Case where Id = :caseId];
        if(c.Priority=='High' && c.Description==null){
            return true ; 
        }else{
            return false ;
        }
    }
}

DisableTabClose.cmp

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="DisableCloseTab">
    <aura:handler name="init" value="this" action="{!c.doInit}"/>
    <aura:handler event="force:refreshView" action="{!c.doInit}" />  
    <lightning:workspaceAPI aura:id="workspace" />
</aura:component>
({
	doInit : function(component, event, helper) {
		helper.init(component, event, helper);
	}
})
({
    init : function(component, event, helper) {
        var action = component.get("c.disableCase");
        action.setParams({ caseId: component.get("v.recordId")});
        action.setCallback(this,$A.getCallback(function(response1)
         {
         console.log('state'+response1);
         var state = response1.getState();             
         if (state === "SUCCESS")  
         {
             var result= response1.getReturnValue();
             var workspaceAPI = component.find("workspace");
             if(result===true){
                 workspaceAPI.getFocusedTabInfo().then(function(response) {
                     var focusedTabId = response.tabId;
                     workspaceAPI.disableTabClose({
                         tabId: focusedTabId,
                         disabled: true,
                         closeable:false
                         
                     })
                     .then(function(tabInfo) {
                         console.log(tabInfo);
                     })
                     .catch(function(error) {
                         console.log(error);
                     });
                 })
                 .catch(function(error) {
                     console.log(error);
                 });
             }else{
                 workspaceAPI.getFocusedTabInfo().then(function(response) {
                     var focusedTabId = response.tabId;
                     workspaceAPI.disableTabClose({
                         tabId: focusedTabId,
                         disabled: false,
                         closeable:true
                     })
                     .then(function(tabInfo) {
                         console.log(tabInfo);
                     })
                     .catch(function(error) {
                         console.log(error);
                     });
                 })
                 .catch(function(error) {
                     console.log(error);
                 });
                 
             }
             
         }
             else if (state === "ERROR") 
             {
                 var errors = response1.getError();
                 console.log(errors);
             }
         }
                                              ));
        $A.enqueueAction(action);       
        
        
    }
})

Include this component on Lightning Record Page 

Now add the DisableTabClose.cmp to the record page anywhere as shown below 

Testing

Now open any high priority record without description .the close tab button is disabled as shown below.

Now open any high priority record with description .the close tab button is enabled as shown below.