Workspace API: How to get Record Id of Enclosing/Parent Tab




Hi Folks, 
I am back with another blog wherein I will discuss how to use Workspace API to get the Record Id of the Enclosing tab. (Basically the parent tab for the current subtab).


Specifically in Salesforce Service Console apps when we click on any lookup value then that record's detail page opens in Subtab mode. For example when we click on Account Name from the Account Lookup field in the Case Record Page then we see that the Account Record Page is opened as a subtab under the current Case Record Page



Situations can come where we want the Record Id for both the Account Id and the Case Id.

We can easily get the AccountId via the recordId attribute.
<aura:attribute name="recordId" type="Id" />

But how to get the CaseId, this value is present in the parent tab. This blog will give you the answer.

Salesforce has provided Workspace API using which we can get this information out.
We will discuss 3 different Workspace API methods that will help us retrieve this information.

1. Using the getEnclosingTabId method
This method would require 2 steps to get the information.
i) Getting the enclosing Tab's Id
ii) Using this tabId to call getTabInfo method to get the information about the enclosing tab
    In the 2nd step, we get a lot of information about the enclosing tab along with which we also get the         URL. From the URL we can trim the RecordId.

workspaceAPI.getEnclosingTabId()
.then(varTabId => {
// Step - 2: Get the enclosing tab's information using the tab Id received from the Step - 1.
workspaceAPI.getTabInfo({tabId: varTabId})
.then(response => {
// The response will contain the entire information about the enclosing tab.
// Below line of code will fetch us the URL for enclosing tab.
let enclosingTabURL = response.pageReference.state.ws;
let enclosingTabURLArray = enclosingTabURL.split('/');
let enclosingTabObjectId = (enclosingTabURLArray && enclosingTabURLArray.length > 1)
? enclosingTabURLArray[enclosingTabURLArray.length-2]
: null;
console.log('Enclosing RecordId --> ' + enclosingTabObjectId);
        // Extra step to call getTabInfo method in case we don't want to rely on splitting.
workspaceAPI.getTabInfo({tabId: response.parentTabId})
.then(response => {
console.log('response => ' + response.recordId);
component.set("v.enclosingTabObjectId", response.recordId);
component.set("v.subTabObjectId", component.get("v.recordId"));
});
});
})
.catch(function(error) {
console.log(error);
});

2. Using the getAllTabInfo method
This method will give us all the information regarding all the tabs that are open in the service console in an array format. Hence, we need to be smart and write appropriate logic in Javascript to get only the information that we want.

The below code is written based on an assumption that only one parent and subtab are present on the screen.

workspaceAPI.getAllTabInfo().then(function(response) {
console.log(JSON.stringify(response));
component.set("v.enclosingTabObjectId",response[0].recordId);
component.set("v.subTabObjectId", component.get("v.recordId"));
})
.catch(function(error) {
console.log(error);
});

Sample JSON response that comes from this method.

[
{
"tabId": "ctab0",
"url": "https://energy-enterprise-905.lightning.force.com/lightning/r/Case/5000p000004pE5EAAU/view",
"pinned": false,
"closeable": true,
"title": "00001015",
"icon": "standard:case",
"iconAlt": "Case",
"highlighted": false,
"pageReference": {
"type": "standard__recordPage",
"attributes": {
"objectApiName": "Case",
"recordId": "5000p000004pE5EAAU",
"actionName": "view"
},
"state": {}
},
"isSubtab": false,
"parentTabId": null,
"subtabs": [
{
"tabId": "ctab0_1",
"url": "https://energy-enterprise-905.lightning.force.com/lightning/r/Account/0010p00000uTE4XAAW/view?ws=%2Flightning%2Fr%2FCase%2F5000p000004pE5EAAU%2Fview",
"pinned": false,
"closeable": true,
"title": "asdf",
"icon": "standard:account",
"iconAlt": "Account",
"highlighted": false,
"pageReference": {
"type": "standard__recordPage",
"attributes": {
"objectApiName": "Account",
"recordId": "0010p00000uTE4XAAW",
"actionName": "view"
},
"state": {
"ws": "/lightning/r/Case/5000p000004pE5EAAU/view"
}
},
"isSubtab": true,
"parentTabId": "ctab0",
"focused": true,
"recordId": "0010p00000uTE4XAAW"
}
],
"focused": true,
"recordId": "5000p000004pE5EAAU"
}
]

3. Using the getFocusedTabInfo method

This is kind of similar to the 1st method.

workspaceAPI.getFocusedTabInfo().then(function(response) {
workspaceAPI.getTabInfo({tabId: response.parentTabId})
.then(response => {
component.set("v.enclosingTabObjectId",response.recordId);
component.set("v.subTabObjectId", component.get("v.recordId"));
});
});

For ease of understanding the functionality of the methods, I have created a simple Aura Component.
This component has a table that will display the information about the current tab record id as well as the enclosing tab record id. There are 3 buttons with names the same as the Workspace API method names. And a button to clear the information already there on the screen.

Please try it and let me know if this helps.

Adding here the entire code:

> Component File

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
<aura:attribute name="recordId" type="Id" />
<aura:attribute name="subTabObjectId" type="String" default="unknown"/>
<aura:attribute name="enclosingTabObjectId" type="String" default="unknown"/>
<lightning:workspaceAPI aura:id="workspace" />

<div class="slds-tabs_card slds-tabs_default">
<lightning:buttonGroup class="slds-float_left">
<lightning:button
variant="destructive-text"
label="Clear"
title="Destructive action"
onclick="{! c.clearData }"/>
</lightning:buttonGroup>
<lightning:buttonGroup class="slds-float_right">
<lightning:button
variant="neutral"
label="getEnclosingTabId"
title="Get"
onclick="{! c.getDetailsViaEnclosingTab }"/>
<lightning:button
variant="brand"
label="getAllTabInfo"
title="Destructive action"
onclick="{! c.getDetailsViaGetAllTabs }"/>
<lightning:button
variant="brand-outline"
label="getFocusedTabInfo"
title="Destructive action"
onclick="{! c.getDetailsViaFocussedTab }"/>
</lightning:buttonGroup>
<table class="slds-table slds-table_cell-buffer slds-table_bordered"
aria-labelledby="element-with-table-label other-element-with-table-label">
<thead>
<tr class="slds-line-height_reset">
<th class="" scope="col">
<div class="slds-truncate" title="Subtab Id">Key</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Subtab Id">Value</div>
</th>
</tr>
</thead>
<tbody>
<tr class="slds-hint-parent">
<th data-label="Opportunity Name" scope="row">
<div class="slds-truncate" title="Cloudhub">
<a href="#" tabindex="-1">Subtab Object Id</a>
</div>
</th>
<td data-label="Account Name">
<div class="slds-truncate" title="Cloudhub">{!v.subTabObjectId}</div>
</td>
</tr>
<tr class="slds-hint-parent">
<th data-label="Opportunity Name" scope="row">
<div class="slds-truncate" title="Cloudhub + Anypoint Connectors">
<a href="#" tabindex="-1">Enclosing Tab Object Id</a>
</div>
</th>
<td data-label="Account Name">
<div class="slds-truncate" title="Cloudhub">{!v.enclosingTabObjectId}</div>
</td>
</tr>
</tbody>
</table>
</div>
</aura:component>

> Javascript File

({
clearData : function (component) {
component.set("v.subTabObjectId","");
component.set("v.enclosingTabObjectId", "");
},
getDetailsViaEnclosingTab: function (component) {
var workspaceAPI = component.find("workspace");
// Step - 1: Get the enclosing tab's Id.
workspaceAPI.getEnclosingTabId()
.then(varTabId => {
// Step - 2: Get the enclosing tab's information using the tab Id received from the Step - 1.
workspaceAPI.getTabInfo({tabId: varTabId})
.then(response => {
// The response will contain the entire information about the enclosing tab.
// Below line of code will fetch us the URL for enclosing tab.
let enclosingTabURL = response.pageReference.state.ws;
let enclosingTabURLArray = enclosingTabURL.split('/');
let enclosingTabObjectId = (enclosingTabURLArray && enclosingTabURLArray.length > 1)
? enclosingTabURLArray[enclosingTabURLArray.length-2]
: null;
console.log('Enclosing RecordId --> ' + enclosingTabObjectId);
// Extra step to call getTabInfo method in case we don't want to rely on splitting.
workspaceAPI.getTabInfo({tabId: response.parentTabId})
.then(response => {
console.log('response => ' + response.recordId);
component.set("v.enclosingTabObjectId", response.recordId);
component.set("v.subTabObjectId", component.get("v.recordId"));
});
});
})
.catch(function(error) {
console.log(error);
});
},
    getDetailsViaGetAllTabs: function (component) {
var workspaceAPI = component.find("workspace");
workspaceAPI.getAllTabInfo().then(function(response) {
console.log(JSON.stringify(response));
component.set("v.enclosingTabObjectId",response[0].recordId);
component.set("v.subTabObjectId", component.get("v.recordId"));
})
.catch(function(error) {
console.log(error);
});
},
    getDetailsViaFocussedTab: function(component) {
var workspaceAPI = component.find("workspace");
workspaceAPI.getFocusedTabInfo().then(function(response) {
workspaceAPI.getTabInfo({tabId: response.parentTabId})
.then(response => {
component.set("v.enclosingTabObjectId",response.recordId);
component.set("v.subTabObjectId", component.get("v.recordId"));
});
});
}
})

Note: Workspace API is only available for AURA and NOT for LWC.

Comments

  1. Thank you for describing the Workspace API use case. It will really help.

    ReplyDelete
  2. Its really helpful to get the parent tab details such as record id. Implementation is also very handy.
    This function is returning all the details of the tab "getDetailsViaGetAllTabs".

    Thanks Ayan

    ReplyDelete

Post a Comment

Popular posts from this blog

Adding NPM module into LWC