Whenever a record meets certain criteria and enters the approval process, we send an email notification to the approver which mainly includes two links, namely
1. Record link, on click of which navigates to the record details page in the Salesforce instance
2. Approval request page
link,
on click of which navigates to Salesforce approval request page with
Approve/Reject/Reassign buttons
Why do we customize the standard
approval request page?
When we create a new approval process in Salesforce, it allows us to select the specific fields to be displayed on the approval request page and those fields will be displayed in the Details tab of the approval request page as mentioned below.
What if the requirement is to show
different fields in different sections as mentioned below?
In this case, we must go for customization
to display data in the different sections.
Step 1: Create a Lightning web
component
nSP_Approvals_Custom_Layout.html
<template>
<div class="slds-card">
<lightning-record-view-form
record-id={oppRecId}
object-api-name="Opportunity"
density="comfy">
<div class="slds-card slds-m-top_medium slds-m-bottom_medium">
<div class="slds-card__header slds-grid">
<header class="slds-media slds-media_center slds-has-flexi-truncate">
<div class="slds-media__figure">
<span class="slds-icon_container slds-icon-standard-account" title="account">
<lightning-icon icon-name="standard:opportunity"
alternative-text="Opportunity"
title="Opportunity"
size="small">
</lightning-icon>
<span class="slds-assistive-text">Section 1</span>
</span>
</div>
<div class="slds-media__body">
<h2 class="slds-card__header-title">
<span>Section 1</span>
</h2>
</div>
</header>
</div>
<div class="slds-card__body slds-card__body_inner">
<lightning-output-field field-name="Name" class="slds-form-element slds-form-element_readonly ">
</lightning-output-field>
<lightning-output-field field-name="Id" class="slds-form-element slds-form-element_readonly ">
</lightning-output-field>
<lightning-output-field field-name="AccountId" class="slds-form-element slds-form-element_readonly ">
</lightning-output-field>
</div>
</div>
<div class="slds-card">
<div class="slds-card__header slds-grid">
<header class="slds-media slds-media_center slds-has-flexi-truncate">
<div class="slds-media__figure">
<span class="slds-icon_container slds-icon-standard-account" title="account">
<lightning-icon icon-name="standard:opportunity"
alternative-text="Opportunity"
title="Opportunity"
size="small">
</lightning-icon>
<span class="slds-assistive-text">Section 2</span>
</span>
</div>
<div class="slds-media__body">
<h2 class="slds-card__header-title">
<span>Section 2</span>
</h2>
</div>
</header>
</div>
<div class="slds-card__body slds-card__body_inner">
<div class="slds-grid">
<div class="slds-col slds-size_1-of-2">
<lightning-output-field field-name="Name" class="slds-form-element slds-form-element_readonly ">
</lightning-output-field>
</div>
<div class="slds-col slds-size_1-of-2">
<lightning-output-field field-name="AccountId" class="slds-form-element slds-form-element_readonly ">
</lightning-output-field>
</div>
</div>
</div>
</div>
</lightning-record-view-form>
</div>
</template>
nSP_Approvals_Custom_Layout.js
import { LightningElement, api, wire, track } from 'lwc';
import getOpportunityRecord from '@salesforce/apex/NSP_Approvals.getOpportunityRecord';
export default class NSP_Approvals_Custom_Layout extends LightningElement {
@api recordId;
@api oppRecId;
@api pageType;
@wire(getOpportunityRecord, {
pIWorkItemId: '$recordId',
pageType: '$pageType'
})
getOpportunityRecord({data, error}) {
if (data) {
this.oppRecId = data.Id;
}
}
}
nSP_Approvals_Custom_Layout.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<!-- <target>lightning__AppPage</target> -->
<target>lightning__RecordPage</target>
<!-- <target>lightning__HomePage</target> -->
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordPage">
<property name="pageType" label="Page Type" type="string" datasource="Request,Response"/>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
Step 2: Create Apex class
//codekiat.com
public class NSP_Approvals {
@AuraEnabled(cacheable=true)
public static opportunity getOpportunityRecord(Id pIWorkItemId, string pageType){
Opportunity oppRecord;
Id oppId;
system.debug('pIWorkItemId >> ' + pIWorkItemId);
if (pageType == 'Request') {
oppId = [SELECT Id, ProcessInstance.TargetObjectId from ProcessInstanceWorkitem WHERE Id =: pIWorkItemId].ProcessInstance.TargetObjectId;
} else {
oppId = [SELECT Id, ProcessInstance.TargetObjectId from ProcessInstanceStep WHERE Id =: pIWorkItemId].ProcessInstance.TargetObjectId;
}
oppRecord = [SELECT Id from Opportunity where Id=: oppId];
return oppRecord;
}
}
Step 3: Remove
the existing page layout standard component in the Details tab of the record page and add the newly created lightning web component to the record page from the app builder
Result
Bonus Tip: How to get the
approval request record page/name for customization?
Step 1: Log in to the Salesforce
instance as an administrator, submit your record to approvals, which triggers
an approval process and an email notification with the approval request link, on click of which navigates to the approval request record page in the Salesforce.
Step 2: In the approval request
record page, click the gear icon at the top right corner, and choose Edit Page
Step 3: Once the app builder page
is loaded, click the Save button at the top right corner. In case an activation
popup opens, we can close it.
Step 4: Navigate to setup > Lightning
app builder and check if the new approval request page record is available.
Refer to the below screenshot.
Well, you got the record page to
edit and make changes as required.
Hope this helps! Post your queries or feedback in the comments section below.
10 Comments
Hi Naveen,
ReplyDeleteI have a similar requirement where I need to use the visualforce page instead, only difference is that I need a add few custom fields which should populate only if there's a value in that field. How can i achieve it.
Thanks!
You can implement the hide/show logic within visualforce page and embed it inside lighting component.
DeleteGreat Blog, really helpful Thank you so much!!!
ReplyDeleteHi Naranjan, Thanks for the feedback.
DeleteHi Naveen,
ReplyDeleteI need to add a custom Lighting component into the Approval Request Page along with the standard detail page.
Is it poossible?
Yes, that is possible. You just need to add the custom component below the standard details component.
DeleteHi, great post, exactly what I needed.
ReplyDeleteI have a question tho. Does Approval process logic continue to work? I mean does it get locked what Approval process is in Pending or Approved?
thanks.
Thanks for the feedback. Yes, approval process logic continue to work as it is and locking works as per the standard behavior.
Deletenice post!
ReplyDeleteHi Naveen, can we call approve or reject record in datatable using approval process apex class
ReplyDelete