Monday, June 22, 2020

How to get Salesforce Base URL in Lightning Web Component

To get Salesforce base URL use the window.location object can be used to get the current page address (URL).
The window.location.origin property returns the origin URL of the current page.

baseURL.html:

<template>
    <lightning-card title="Salesforce Base URL in Lighting Web Component">
        <div class="slds-text-heading_medium slds-text-align-center">
            SFDC Base URL : <p></p><lightning-formatted-url value={sfdcBaseURL} ></lightning-formatted-url></p>
        </div>
    </lightning-card>

</template>

baseURL.js:

import { LightningElement } from 'lwc';
export default class BaseURL extends LightningElement {
    sfdcBaseURL;
    renderedCallback() {
        this.sfdcBaseURL = window.location.origin;
    }

}
baseURL.js-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>

</LightningComponentBundle>

Output:


Getting Current Logged in User information in Lightning Web Component(lwc)

userDetails.html:

<template>
    <lightning-card title="Current Logged User Information">
        <template if:true={objUser}>
            <dl class="slds-list_horizontal slds-wrap" style="margin-left: 3%;">
                <dt class="slds-item_label slds-truncate" title="First Name">First Name:</dt>
                <dd class="slds-item_detail slds-truncate"><b>{objUser.FirstName}</b></dd>
                <dt class="slds-item_label slds-truncate" title="Last Name">Last Name:</dt>
                <dd class="slds-item_detail slds-truncate"><b>{objUser.LastName}</b></dd>
                <dt class="slds-item_label slds-truncate" title="Full Name">Name:</dt>
                <dd class="slds-item_detail slds-truncate"><b>{objUser.Name}</b></dd>
                <dt class="slds-item_label slds-truncate" title="Alias">Alias:</dt>
                <dd class="slds-item_detail slds-truncate"><b>{objUser.Alias}</b></dd>
                <dt class="slds-item_label slds-truncate" title="Active">Is Active:</dt>
                <dd class="slds-item_detail slds-truncate"><b>{objUser.IsActive}</b></dd>
            </dl>
        </template>
    </lightning-card>

</template>

userDetails.js:

import { LightningElement, track, wire} from 'lwc';

// To get the record details based on record id
import { getRecord } from 'lightning/uiRecordApi';

// impoting USER id
import USER_ID from '@salesforce/user/Id'; 

export default class CurrentUserDetailsInLWC extends LightningElement {

    @track objUser = {};
    
    // using wire service getting current user data
    @wire(getRecord, { recordId: USER_ID, fields: ['User.FirstName', 'User.LastName', 'User.Name', 'User.Alias', 'User.IsActive'] })
    userData({error, data}) {
        if(data) {
            window.console.log('data ====> '+JSON.stringify(data));

            let objCurrentData = data.fields;

            this.objUser = {
                FirstName : objCurrentData.FirstName.value,
                LastName : objCurrentData.LastName.value,
                Name : objCurrentData.Name.value,
                Alias : objCurrentData.Alias.value,
                IsActive : objCurrentData.IsActive.value,
            }
        } 
        else if(error) {
            window.console.log('error Occured====> '+JSON.stringify(error))
        } 
    }


}
userDetails.js-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>

</LightningComponentBundle>

Sunday, February 23, 2020

Lightning Web Component Modal

lWCModal.html:

<template>
   <div class ="slds-theme_default">
       <div class="slds-p-around_medium">
        <lightning-button label="Show LWC Modal" variant= "brand" onclick={handleOpenModal}>
        </lightning-button>
       </div>
<template if:true={isOpenModal}>
    <div style="height: 500px;">
        <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open"></section>
        <div class="slds-modal__container">
            <header class="slds-modal__header">
                <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close" onclick={handleCloseModal}>
                    <lightning-icon icon-name="utility:close" variant="inverse" alternative-text="Close" size="medium">
                    </lightning-icon>
                    <span class="slds-assistive-text">Close</span>
                </button>
                <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">LWC Modal</h2>
            </header>
            <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                <div class="slds-text-heading_small slds-text-align_center">
                    Welcome to LWC
                </div>
            </div>
            <footer class="slds-modal__footer">
                <lightning-button label="Cancel" variant="neutral" onclick={handleCloseModal}></lightning-button>
            </footer>
        </div>
    </section>
    <div class="slds-backdrop slds-backdrop_open"></div>
</div>
</template>
</div>

</template>

lWCModal.js:

import { LightningElement, track } from 'lwc';

export default class LWCModal extends LightningElement {
    @track isOpenModal = false;

    handleOpenModal(){
        this.isOpenModal =true;
    }
    handleCloseModal(){
        this.isOpenModal = false;
    }

}

lWCModal.js-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>47.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>

</LightningComponentBundle>

Lightning Web Component OnLoad

lWCOnLoad.html:

<template>
    <div class="slds-text-heading_large slds-text-align_center">
        {greeting}
</div>
</template>

lWCOnLoad.js:

import { LightningElement, track } from 'lwc';

export default class LWCOnLoad extends LightningElement {

    @track greeting;

    connectedCallback(){
        this.greeting ='Welcome to LWC';
    }

}


Get Current User Id in Lightning Web Component



UserDetails.html: 

<template>
<div class="slds-text-heading_large slds-text-align_center">
   User Id : {currentUserId}
    </div>
</template>

UserDetails.js: 

import { LightningElement } from 'lwc'; 
import strUserId from '@salesforce/user/Id'

export default class UserDetails extends LightningElement { 
 userId = strUserId 

}

Lightning CPQ button for Recall Approval

Lightning Component:

<aura:component controller="CpqRecallQuoteApprovalController" implements="flexipage:availableForAllPageTypes,force:appHostable,force:lightningQuickActionWithoutHeader,force:hasRecordId">
    <aura:attribute name="isSpinner" type="boolean" default="false"/>
    <aura:handler event="aura:waiting" action="{!c.handleShowSpinner}"/>
    <aura:handler event="aura:doneWaiting" action="{!c.handleHideSpinner}"/>
    <aura:html tag="style">
        .cuf-content {
        padding: 0 0rem !important;
        }
        .slds-p-around--medium {
        padding: 0rem !important;
        }       
        .slds-modal__content{
        overflow-y:hidden !important;
        height:unset !important;
        max-height:unset !important;
        }
    </aura:html>
    <div class="modal-header slds-modal__header slds-size_1-of-1">
        <h4 class="title slds-text-heading--medium" >Recall Approval</h4>
    </div>
    <!-- MODAL BODY / INPUT FORM -->    
    <div class="slds-modal__content slds-p-around--x-small slds-align_absolute-center slds-size_1-of-1 slds-is-relative" aura:id="modalbody" id="modalbody">
        <center>
            <b>This will allow you to edit the quote but will require the quote to be approved again.<br/> 
                Do you wish to continue?
            </b>
        </center>
    </div>
    <div class="modal-footer slds-modal__footer slds-size_1-of-1">
        <div class="forceChangeRecordTypeFooter">
            <ui:button class="slds-button slds-button_neutral" disabled="{!v.isSpinner}" label="Cancel" press="{!c.cancel}" /> 
            <ui:button class="slds-button slds-button--brand" disabled="{!v.isSpinner}" label="{!v.isSpinner == true ? 'Ok...' : 'Ok'}" press="{!c.proceedToRecall}"/>
        </div>
    </div>

</aura:component>

Lightning JS Controller:

({
    cancel: function(component, event, helper) {
        $A.get("e.force:closeQuickAction").fire();
    },
    proceedToRecall: function(component, event, helper) {
        var action = component.get("c.onRecall");
        action.setParams({"quoteId" : component.get("v.recordId")});
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                console.log(response.getReturnValue());
                $A.get('e.force:refreshView').fire();
                $A.get("e.force:closeQuickAction").fire();
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " +
                                    errors[0].message);
                    }
                }
            }
                else {
                    console.log("Unknown error");
                }
        });
        $A.enqueueAction(action);
    },
    //Call by aura:waiting event  
    handleShowSpinner: function(component, event, helper) {
        component.set("v.isSpinner", true); 
    },
     
    //Call by aura:doneWaiting event 
    handleHideSpinner : function(component,event,helper){
        component.set("v.isSpinner", false);
    }

})

Apex Controller:

public class CpqRecallQuoteApprovalController {
    
/*
* This method will call get triggered on Recall approval button in Lightning Component
*/ 
    @AuraEnabled
    public static void onRecall(String quoteId) {
        if (quoteId != null) {
            SBAA.ApprovalAPI.recall(quoteId, SBAA__Approval__c.Quote__c);
        }
    }

}

Lightning CPQ button for Submit For Approval

Lightning Component:


<aura:component controller="CpqQuoteApprovalController" implements="flexipage:availableForAllPageTypes,force:appHostable,force:lightningQuickActionWithoutHeader,force:hasRecordId">
    <aura:attribute name="requiredValuesNotAvailable" type="boolean" default="true"/>
    <aura:attribute name="displaySecondConfirmation" type="boolean" default="false"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="isSpinner" type="boolean" default="false"/>
    <aura:handler event="aura:waiting" action="{!c.handleShowSpinner}"/>
    <aura:handler event="aura:doneWaiting" action="{!c.handleHideSpinner}"/>
     
    <aura:html tag="style">
        .cuf-content {
        padding: 0 0rem !important;
        }
        .slds-p-around--medium {
        padding: 0rem !important;
        }       
        .slds-modal__content{
        overflow-y:hidden !important;
        height:unset !important;
        max-height:unset !important;
        }
    </aura:html>
    <div class="modal-header slds-modal__header slds-size_1-of-1">
        <h4 class="title slds-text-heading--medium" >Submit For Approval</h4>
    </div>
    
    <!-- MODAL BODY / INPUT FORM -->    
    <div class="slds-modal__content slds-p-around--x-small slds-align_absolute-center slds-size_1-of-1 slds-is-relative" aura:id="modalbody" id="modalbody">
        <aura:if isTrue="{!!v.displaySecondConfirmation}">
            <center>
                <b>Do you want to submit quote for approval?<br/>
                    Once submitted for approval Quote will be locked.</b>
            </center>
        </aura:if>
        <aura:if isTrue="{!v.displaySecondConfirmation}">
            <center>
                <b>Please provide Quote Name and Discount Justification before Submitting for Approval</b>
            </center>
        </aura:if>
    </div>
    <!-- End of Modal Content -->  
    <!-- MODAL FOOTER -->
    <div class="modal-footer slds-modal__footer slds-size_1-of-1">
        <aura:if isTrue="{!!v.displaySecondConfirmation}">
            <div class="forceChangeRecordTypeFooter">
                <ui:button class="slds-button slds-button_neutral" disabled="{!v.isSpinner}" label="Cancel" press="{!c.cancel}" /> 
                <ui:button class="slds-button slds-button--brand" disabled="{!v.isSpinner}" label="{!v.isSpinner == true ? 'Ok...' : 'Ok'}" press="{!c.proceedToSubmit}"/>
            </div>

        </aura:if>
        <aura:if isTrue="{!v.displaySecondConfirmation}">
            <ui:button class="slds-button slds-button--brand" label="Ok" press="{!c.cancel}" />
        </aura:if>
    </div>

</aura:component>


Lightning JS Controller:

({
    doInit: function(component, event, helper) {
        var action = component.get("c.checkForRequiredFields");
        action.setParams({"recordId" : component.get("v.recordId")});
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                console.log(response.getReturnValue());
                component.set("v.requiredValuesNotAvailable", response.getReturnValue());
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " +
                                    errors[0].message);
                    }
                }
            }
                else {
                    console.log("Unknown error");
                }
        });
        $A.enqueueAction(action);
    },
    cancel: function(component, event, helper) {
        $A.get("e.force:closeQuickAction").fire();
    },
    proceedToSubmit: function(component, event, helper) {
        var requiredValuesNotAvailable = component.get("v.requiredValuesNotAvailable");
   
        if(requiredValuesNotAvailable){
            component.set('v.displaySecondConfirmation', true);
        }
        else{
            var action = component.get("c.onSubmit");
            action.setParams({"quoteId" : component.get("v.recordId")});
            action.setCallback(this, function(response) {
                var state = response.getState();
                if (state === "SUCCESS") {
                    console.log(response.getReturnValue());
                    $A.get('e.force:refreshView').fire();
                    $A.get("e.force:closeQuickAction").fire();
                }
                else if (state === "ERROR") {
                    var errors = response.getError();
                    if (errors) {
                        if (errors[0] && errors[0].message) {
                            console.log("Error message: " +
                                        errors[0].message);
                        }
                    }
                }
                    else {
                        console.log("Unknown error");
                    }
            });
            $A.enqueueAction(action);
         
        }
    },

     //Call by aura:waiting event
    handleShowSpinner: function(component, event, helper) {
        component.set("v.isSpinner", true);
    },
   
    //Call by aura:doneWaiting event
    handleHideSpinner : function(component,event,helper){
        component.set("v.isSpinner", false);
    }
})

Apex Controller:

public class CpqQuoteApprovalController {
    @AuraEnabled
    public static boolean checkForRequiredFields(String recordId) {
        Boolean requiredFieldsNotAvailable = false;
        List<SBQQ__Quote__c> qt = [SELECT Id, SBQQ__Type__c, Quote_Name__c, Discount_Justification__c FROM SBQQ__Quote__c Where Id =: recordId];
        if((qt[0].SBQQ__Type__c == 'Amendment') && ((qt[0].Quote_Name__c == null) || (qt[0].Discount_Justification__c == null))){
            requiredFieldsNotAvailable = true;
        }
        return requiredFieldsNotAvailable;
    }
/*
* This method will call submit approval method
*/
    @AuraEnabled
    public static void onSubmit(String quoteId) {
        if (quoteId != null) {
            SBAA.ApprovalAPI.submit(quoteId, SBAA__Approval__c.Quote__c);
        }
    }
}