Tree grid Hierarchy for records can improve user experience and gives more insight on parent child hierarchy at one place. Salesforce does give Account Hierarchy feature out of the box, but what if you want the similar functionality for Role Hierarchy or Case Hierarchy or any custom object hierarchy? Well, Now you can use this generic Lightning Web Component which allows you to have hierarchy view on single sObject records.
Code – LWC Generic Tree Grid Hierarchy Component
Lets create an apex method with name HierarchyController and a Lightning Web Component with name RoleHirarchyExplorer. We are going to demo how to display Role Hierarchy in LWC. You can modify this to have any kind of hierarchy with few change.
Apex Class – HierarchyController
There are two methods in this class. getAllHirarchy is a generic method which you can call to get the wrapper of parent and child map of any sObject which will be used by LWC to display the hierarchy.
getAllRoleHirarchy is a method to get the parent child map for UserRole sObject, similalry you can have methods to get other sObject hierarchy.
public class HierarchyController {
//This method is for getting role hierarchy
//you can create similar method for any other hierarchy
@AuraEnabled
public static hierarchyWrapper getAllRoleHirarchy(){
List<UserRole> userRoleList = new List<UserRole>();
userRoleList = [Select Id, Name, ParentRoleId from UserRole];
return getAllHirarchy(userRoleList,'ParentRoleId');
}
//This is a generic method which returns a wrapper which holds map of parent and its child list
@auraEnabled
public static hierarchyWrapper getAllHirarchy(List<Sobject> recordList, String parentFieldApiName){
Map<String,List<SObject>> mapofparentwithlistOfchild = new map<String, List<SObject>>();
List<SObject> parentList = new List<SObject>();
for(SObject record: recordList){
if(record.get(parentFieldApiName) != null){
if(mapofparentwithlistOfchild.containskey((String)record.get(parentFieldApiName))){
mapofparentwithlistOfchild.get((String)record.get(parentFieldApiName)).add(record);
}else{
mapofparentwithlistOfchild.put((String)record.get(parentFieldApiName), new list<SObject>{record});
}
}else{
parentList.add(record);
}
}
hierarchyWrapper wrapper = new hierarchyWrapper();
wrapper.superParentList = parentList;
wrapper.parentMap = mapofparentwithlistOfchild;
return wrapper;
}
public class hierarchyWrapper{
@AuraEnabled public List<SObject> superParentList{get;set;}
@AuraEnabled public Map<String,List<SObject>> parentMap{get;set;}
}
}
RoleHirarchyExplorer – LWC for Tree Grid Hierarchy
The lightning web component will have three files. They are html, js and meta xml file. You can create the component and copy the below code in respective file.
roleHirarchyExplorer.html
lightning-tree-grid component expects you to pass the columns and data to display. We have added lwc:if to make sure it renders only when data is available.
<template>
<lightning-tree-grid lwc:if={hierarchyMap} columns={gridColumns} data={hierarchyMap}
key-field="Id"></lightning-tree-grid>
</template>
roleHirarchyExplorer.js
As we are demonstrating Role Hierarchy, I have called the getAllRoleHirarchy apex method from HierarchyController class.
You can call your own method to fit your requirement. For example, if you are looking to get Case Hierarchy, You can create a method in HierarchyController class and pass the case list and parent field api name for case object to getAllHirarchy method by calling it. See below code
@AuraEnabled
public static hierarchyWrapper getAllAccountHirarchy(){
List<Account> accountList = new List<Account>();
accountList = [Select Id, Name, ParentId from Account];
return getAllHirarchy(accountList,'ParentId');
}
Add above method in HierarchyController and call it in JS file.
Full JS Code
import { LightningElement, api } from 'lwc';
import getAllRoleHirarchy from '@salesforce/apex/HierarchyController.getAllRoleHirarchy';
const COLUMNS_DEFINITION_BASIC = [
{
type: 'text',
fieldName: 'Name',
label: 'Role Name',
},
{
type: 'text',
fieldName: 'Id',
label: 'Role Id',
},
];
export default class RoleHirarchyExplorer extends LightningElement {
hierarchyMap;
//pass your columns definition as per your requirement
@api gridColumns = COLUMNS_DEFINITION_BASIC;
//This is the field api name of field whose value will be put in parent field of child
//for example UserRole, Id of the parent role will be the ParentRoleId field value of child role
@api primaryKey = 'Id';
connectedCallback() {
//We ae making call of apex method which pass the sobjectlist and parent field api name
//in getAllHirarchy generic method in HierarchyController
//you can change the method as per your requirement
getAllRoleHirarchy().then(result => {
this.parseResult(result);
}).catch(error => {
console.log('error', error, JSON.stringify(error));
});
}
parseResult(result) {
this.hierarchyMap = [];
result.superParentList.forEach(element => {
this.hierarchyMap.push(this.findChildrenNode(element, result));
});
this.hierarchyMap = JSON.parse(JSON.stringify(this.hierarchyMap));
}
findChildrenNode(element, result) {
for (var key in result.parentMap) {
if (key == element[this.primaryKey]) {
element["_children"] = result.parentMap[key];
element["_children"].forEach(child => {
this.findChildrenNode(child, result);
});
}
}
return element;
}
}
roleHirarchyExplorer.js-meta.xml
This file enables the component to be used with home, record and app page in lightning experience.
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>57.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Demo – Tree Grid LWC Hierarchy on Same sObject
Do you need help?
Stuck while working on this requirement? Do you want to get review of your solution? Now, you can book dedicated 1:1 with me on Lightning Web Component completely free.
GET IN TOUCH
Schedule a 1:1 Meeting with me
Also check out https://salesforcediaries.com/category/lightning-web-com