Expected Output:
Source Code:
LWC Component:
---------------------
accountHierarchyTreeGrid.html
<template>
<lightning-card title="Account, Contact, and Case Hierarchy">
<div class="slds-p-around_medium">
<template if:true={gridData}>
<lightning-tree-grid
columns={gridColumns}
data={gridData}
key-field={keyField}>
</lightning-tree-grid>
</template>
<template if:false={gridData}>
<p class="slds-align_absolute-center">Loading or No Accounts found to display.</p>
</template>
</div>
</lightning-card>
</template>
accountHierarchyTreeGrid.js
import { LightningElement, wire } from 'lwc';
import getAccountHierarchy from '@salesforce/apex/HierarchyController.getAccountHierarchy';
export default class AccountHierarchyTreeGrid extends LightningElement {
// Key-field for unique identification
keyField = 'id';
// Data property to hold the hierarchical records
gridData = [];
// Column definitions for lightning-tree-grid
gridColumns = [
{
// This column holds the expandable node and the main name/number
type: 'text',
fieldName: 'name',
label: 'Name / Number',
initialWidth: 300
},
// --- Account Field ---
{
type: 'text',
fieldName: 'industry',
label: 'Account Industry',
initialWidth: 150
},
// --- Contact Field ---
{
type: 'email',
fieldName: 'email',
label: 'Contact Email',
initialWidth: 200
},
// --- Case Fields ---
{
type: 'text',
fieldName: 'subject',
label: 'Case Subject'
},
{
type: 'text',
fieldName: 'status',
label: 'Case Status',
initialWidth: 150
}
];
// Wire service calls the simplified Apex method
@wire(getAccountHierarchy)
wiredAccounts({ error, data }) {
if (data) {
// The data is a List<Object> (Maps) and is directly usable by the tree grid
this.gridData = data;
} else if (error) {
console.error('Error fetching hierarchy data:', error);
// Optional: Add logic to display an error toast message here
}
}
}
accountHierarchyTreeGrid.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>60.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Apexclass:
/**
* @description Controller to fetch Account, Contact, and Case data for the LWC Tree Grid.
* This builds the hierarchy directly using Maps instead of using the Javascript
manipulation of data.
*/
public with sharing class HierarchyController {
/**
* @description Fetches Accounts, Contacts, and Cases, and formats them directly into maps.
* @return List<Object> The root list of Accounts as Map<String, Object> structures.
*/
@AuraEnabled(cacheable=true)
public static List<Object> getAccountHierarchy() {
// Use SOQL to fetch Accounts, Contacts, and Cases
List<Account> accountResults = [
SELECT
Id, Name, Industry,
(SELECT Id, FirstName, LastName, Email, (SELECT Id, CaseNumber, Subject, Status FROM Cases) FROM Contacts)
FROM Account
ORDER BY Name
LIMIT 10
];
List<Object> rootList = new List<Object>();
// 1. Process Accounts (Level 1)
for (Account acc : accountResults) {
// Create the Account map node
Map<String, Object> accNode = new Map<String, Object>();
accNode.put('id', acc.Id);
accNode.put('name', acc.Name);
accNode.put('industry', acc.Industry);
List<Object> contactChildren = new List<Object>();
if (acc.Contacts != null && !acc.Contacts.isEmpty()) {
// 2. Process Contacts (Level 2)
for (Contact con : acc.Contacts) {
// Create the Contact map node
Map<String, Object> conNode = new Map<String, Object>();
conNode.put('id', con.Id);
conNode.put('name', con.FirstName + ' ' + con.LastName);
conNode.put('firstName', con.FirstName);
conNode.put('lastName', con.LastName);
conNode.put('email', con.Email);
List<Object> caseChildren = new List<Object>();
if (con.Cases != null && !con.Cases.isEmpty()) {
// 3. Process Cases (Level 3)
for (Case c : con.Cases) {
Map<String, Object> caseNode = new Map<String, Object>();
caseNode.put('id', c.Id);
caseNode.put('name', c.CaseNumber);
caseNode.put('caseNumber', c.CaseNumber);
caseNode.put('subject', c.Subject);
caseNode.put('status', c.Status);
caseChildren.add(caseNode);
}
// Add Cases to the Contact node using the required '_children' key
conNode.put('_children', caseChildren);
}
contactChildren.add(conNode);
}
// Add Contacts to the Account node using the required '_children' key
accNode.put('_children', contactChildren);
}
rootList.add(accNode);
}
return rootList;
}
}
Reference:
No comments:
Post a Comment