Thursday, 11 August 2022

Support special characters when opening document from Salesforce to SharePoint using Rest API

SCENARIO

While working on one of the requirements for a Manufacture sector project for a client based out of Atlanta, GA, there was a requirement to allow special characters like % & # _ ( ) * - . in the document name while uploading from salesforce to SharePoint and open the document from salesforce custom LWC component.

Let's brief on the scenario: To store\manage files client is using SharePoint through integration. While users upload documents in the salesforce, files are uploaded to SharePoint and shown to salesforce custom component. Now the client has requested new enhancement to allow special characters as well like % & # _ ( ) * - in document name.

Document upload with special characters works fine as we were using salesforce content document to upload files. After that our custom API is responsible to upload same file and give response back to open uploaded files on success dialog box.

However, file was being uploaded in SharePoint and few changes were done in Custom API to provide response back for the document name containing special character.

CHALLENGE

Custom API changes were not enough to make solution fully work as we were able to open such documents from success dialog box but not from salesforce Custom Component. We were using SharePoint OOTB REST API to build link for SharePoint document link.

APPROACH

We have used salesforce APEX ENCODINGUTIL class to encode file name in URL. This solved the issue for most of the documents having special characters but not for which contains space in Document name.

After few analysis, we found ENCODINGUTIL replace space with '+' sign. With the tricky solution we resolved the issue by replacing '+'  with '%20' in encoded Document name. Let's understand with the example.

EXAMPLE:

  • Find below few specific parameter being used in solution.
    • Document Name : Test % & # _ ( ) * - .docx
    • OOTB\Standard SharePoint document Encoded URL : 
      SiteURL/Shared%20Documents/General/Test%20%25%20&%20%23%20_%20(%20)%20%20-%20.docx
  • To get document details, we make SharePoint  REST API callout.
  • In the response, we get FileRef As 
    SiteURL/Shared Documents/Genetal/Test % & # _ ( ) * - .docx
  • As we can see from both the URL SharePoint document URL is Encoded and in the response FileRef is not Encoded in format.
  • So we need to Encode FileRef  and replace '+' with '%20' in the apex as below.
String DocumentencodedUrl = EncodingUtil.urlEncode(FileRef, 'UTF-8');
//By using EncodingUtil class and its methods we can encode and decode URL strings.

System.Debug('Encoded Document URL--> '+DocumentencodedUrl);
// Encoded Document URL--> SiteURL%2FShared+Documents%2FGenetal%2FTest+%25+%26+%23+_+%28+%29+*+-+.docx

String DocumentUrl = DocumentencodedUrl.replace('+','%20');
//By replace string function we are replacing '+' with '%20'

System.Debug('Document URL--> '+DocumentUrl);
//Document URL--> SiteURL%2FShared%20Documents%2FGenetal%2FTest%20%25%20%26%20%23%20_%20%28%20%29%20*%20-%20.docx

In the above code, we have used EncodeUtil class and its urlEncode Method to encode the URL string and replace the method to replace '+' with '%20'.

  • Now our DocumentencodedUrl will work and document can be opened from salesforce custom component.


CONCLUSION

By encoding URL and replacing '+' with '%20' we can resolve the document URL issue having special character and space.

 
If you have any questions you can reach out our
Salesforce Consulting team here.

Thursday, 4 August 2022

Create Notifications with LightningAlert, LightningConfirm, and LightningPrompt Modules


The Web Hypertext Application Technology Working Group (WHATWG) updated the HTML specification in early 2021 to remove support for the alert(), confirm(), and prompt() native APIs when used in a third-party context. So, Browsers like Chrome and Safari are now planning to end support for cross-origin use of the window.alert(), window.confirm(), and window.prompt() native APIs.

To address this issue in any LWC or Aura component, Salesforce has introduced LightningAlert, LightningConfirm, and LightningPrompt in the Summer'22 release. See Summer'22 release notes Click here.

So now to generate notifications from your Lightning web components, use the new modules LightningAlert, LightningConfirm, and LightningPrompt instead of native APIs.

The below examples show how to use LightningAlert, LightningConfirm, and LightningPrompt in Lightning web components.



Example

Let's look at the example, There are 3 buttons in LWC to display the notification Alert, Confirm and Prompt. 

Below is a code and output for LightningAlert, LightningConfirm, and LightningPrompt notifications.


In this example, a modal with a header, message, and two buttons are created. If the user enters text and clicks "OK" in the prompt, the .open() function returns a promise that resolves to the input value; however, if the user clicks “Cancel,” the promise resolves to null. 


Output





If you have any questions you can reach out to our Salesforce Consulting team here.

Thursday, 28 July 2022

Fill the form and display data into data table without storing it into sObject/database using LWC

SCENARIO


While working on one of the requirements for an Automobile sector project for a client based out of Dallas, Texas, there was a requirement to add data using a form in LWC and display it into the dataTable without storing it into sObject/database.

CHALLENGE


Although the requirement seems easy, we faced challenges while displaying records into the dataTable and reRendering it when a new record is added.
 

APPROACH


To display records without storing them into sObject/database, We used a JSON object that will be responsible to store all the data to be displayed in the dataTable.
Also, we declared that JSON object as a reactive property using the @track decorator. So the table can be reRendered automatically when the value of that variable is changed/updated.

Data.html

<template>
    <lightning-card title="Add data into Datatable">
        <lightning-layout>
            <lightning-input class="slds-p-around_medium" label="Make"  type="string" name="Make"  onchange={makeChangedHandler} required="true"> </lightning-input>
            <lightning-input class="slds-p-around_medium" label="Model" type="string" name="Model" onchange={modelChangedHandler} required="true"> </lightning-input>
            <lightning-input class="slds-p-around_medium" label="Year" type="date" name="Year" onchange={yearChangedHandler} required="true"> </lightning-input>
        </lightning-layout>
        <lightning-button class="slds-m-left_x-small" label="Display" variant="brand" onclick={handleClick}>
        </lightning-button>
        <lightning-datatable key-field="id" id="datatable" data={fields} columns={columns}>
        </lightning-datatable>                 
    </lightning-card>  
</template>

Data.js

import { LightningElement,track } from 'lwc';

export default class Data extends LightningElement {
     columns = [{
        label: 'Make',
        fieldName: 'Make',
        type: 'text',
        sortable: true
    },
    {
        label: 'Model',
        fieldName: 'Model',
        type: 'text',
        sortable: true
    },
    {
        label: 'Year',
        fieldName: 'Year',
        type: 'Date',
        sortable: true
    },
];

    strMake;
    strModel;
    strYear;
    @track fields =[];
    
    makeChangedHandler(event){
        this.strMake = event.target.value;  
    }
    modelChangedHandler(event){
        this.strModel = event.target.value;
    }
    yearChangedHandler(event){
        this.strYear = event.target.value;
    }

    handleClick(){
        if(this.strMake  &&  this.strModel  && this.strYear)
        {
            this.fields = [...this.fields,{'Make' : this.strMake, 'Model' : this.strModel, 'Year' : this.strYear}];   
        }
        this.strMake ='';
        this.strModel ='';
        this.strYear ='';
        //code to clear field once values are entered
        this.template.querySelectorAll('lightning-input').forEach(element => {
        element.value = null;     
        });
    }
}

There are 3 input fields in the form. Whenever the values will be entered in these fields, it will get stored in their respective variables (strMake, strModel, strYear).

On click of Display button, these 3 inputs will be validated and pushed into an array, which is then used to display data in the data table. Also, it will clear these 3 input fields and allow users to enter another record.

As the array is declared as a reactive property, it will reRender the table automatically to display the newly created record.



OUTPUT




CONCLUSION


By using the above-mentioned approach & code, We will be able to add data into the data table without using sObject or saving data into a database in LWC.

If you have any questions you can reach out to our Salesforce Consulting team here.

Thursday, 21 July 2022

A new way to enforce user level security with Apex code

By the release of Summer 22, Major expansion in the Apex security model. Now we can declare Apex database operations run on user or system modes. In this blog, we will see how to write Secure Apex Code with User Mode Database Operations (Summer '22 release) in a remarkably simplified manner. This feature is currently under Beta.

The new Database methods support an AccessLevel parameter that lets you run database operations in user mode instead of in the default system mode. By default Apex code runs in system mode,  Which means that it runs with substantially elevated permissions over the user running the code. To enhance the security context of Apex, you can specify user mode access for database operations. Field-level security (FLS) and object permissions of the running user are respected in user mode, unlike in system mode. User mode always applies sharing rules. in system mode they’re controlled by the class sharing keywords.

USER_MODE AND SYSTEM_MODE

In SOQL queries we can indicate the mode of the operation by using USER_MODE or SYSTEM_MODE. Below is an example that specifies the user mode.

List<Account> accts = [SELECT Id, Name, Phone, BillingCity FROM Account WITH USER_MODE];

List<Contact> cons = [SELECT Id, FirstName, LastName, Account.Name FROM Contact WITH USER_MODE]; 

Database operation with USER or SYSTEM MODE

Database operations can specify user or system mode. Below is an example to insert a new account with user mode.

Account acct = new Account(
    Name='Binary Republik',
    Phone='9909950592');

insert as USER acct;

Account acc = [SELECT Id, Name, Phone FROM Account WHERE Name ='Binary Republik'];

acc.Email = 'info@binaryrepublik.com';
update as SYSTEM acc; 
 

Dynamic at runtime syntax

The new AccessLevel class represents the two modes in which Apex runs database operations. Use this new class to define the execution mode as user mode or system mode. Use these new overloaded methods to perform DML and query operations.
  • Database.query methods
  • Search.query methods
  • Database DML methods (insert, update, upsert, merge, delete, undelete, and convertLead)
Below are some examples.
//Database.query example

Account acc = Database.query('SELECT Id, Name FROM Account WHERE Name = 'Binary Republic'', AccessLevel.USER_MODE);

//Database.insert example

Database.insert(new Account(Name = 'Binary Republik'),AccessLevel.USER_MODE);

Click here see release notes on secure apex Code with user mode database operations. 


If you have any questions you can reach out our Salesforce Consulting team here.

Thursday, 14 July 2022

Display a notification banner using the lightning web component


SCENARIO

While working on one of the requirements for a Health sector project for a client based out of Atlanta, GA, there was a requirement to display a notification banner or greeting message based on a time frame using the lightning web component.

CHALLENGE

The requirement is to display a greeting message or a notification banner for a specific duration. after the duration, the message will be changed or not display any banner. So they conditionally render notification messages or greeting messages based on a time frame without user interaction.

APPROACH

Notification banners communicate a state that affects the entire system, not just a feature or page. It appears automatically and lasts for the duration of the session.

Bellow is our approach to achieve the requirement by using Lightning Web Component and Custom Metadata Type.

  1. Create a custom metadata type to store the banner details.
    1. Start Date
    2. End Date
    3. Message
  2. Create an Apex class to retrieve custom metadata type records.
  3. Create a lightning web component to conditionally render a notification banner.

Step 1:- Create a Custom Metadata Type to store the banner details.

Below are the steps to create a custom metadata type.
  • Click on Setup, In the Quick Find box type Custom Metadata Type.
  • Select New Custom Metadata Type and enter Label and Plural Label.
  • Click on Save.
  • Create 3 custom fields to store the start date, end date, and message. below is an image of Custom Metadata Type.

Custom Metadata Type
  • The next step is to create a record into a custom metadata type. Click on Manage Notification Banners and fill in the details and click on Save. Below is an image of the record.

Custom Metadata Type Record

Step 2:- Create an Apex Class to retrieve custom metadata type records.

Step 3:- Create a Lightning Web Component to conditionally render a notification banner.




Output:-

Output


If you have any questions you can reach out our Salesforce Consulting team here.

Thursday, 7 July 2022

Actions Missing in Activity Composer on Objects

SCENARIO

While working on one of the requirements for the client based in Atlanta, a few users were unable to see some actions under Activity composer on the Lead object.

CHALLENGE

As an administrator, we were able to see all the actions like 'Log a call', 'New task', 'Email', 'New Event'  but some of the users were unable to see a few actions like 'New Task' and 'Log a call'. It was challenging to identify the problem that certain users were experiencing. We had some trouble going through all the settings and checking user and object setups because we were unsure of which configuration was acting inconsistently.

SOLUTION

To resolve this issue, we tried a lot of solutions and found a bunch of configurations we should check to control user access over Activity composers.

Below are 5 configurations that are useful to resolve this kind of issue.

  1. Make sure the user has permission to the Task object
  2. Check page layout assignment for the record type
  3. Check object page layout
  4. Check the default record type of the Global action and record type permission to the user
  5. Ensure that users have permission to view the record type

Follow the below steps to verify all permissions and configurations.

1. Make sure the user has permission to the Task object.
  • Open respective Profiles for the user who is facing the issue.
  • Click on 'System Permission and verify user permission to the Task object.

2. Check page layout assignment for the record type.
  • Go to Object Manager, find the 'Lead' object.
  • Click on Record Types, Click on the 'Page layout Assignment' button and verify the page layout assigned to the user.

3. Check object page layout.
  • Go to Object Manager, find the Lead object.
  • Click on Page Layouts, Open the respective page layout where you want to add the missing action.
  • Click 'Override the Predefined Actions' under Salesforce Mobile and Lightning Actions.
  • Drag and Drop 'Log a Call' and 'Create Task' from Mobile & Lightning Actions and Save the page.
If the actions are added to the page layout even though users are not able to see the actions you can check another step.

4. Check the default record type of the Global action and record type permission to the user.
  • Make sure the user has permission to the record type selected under the Global actions.

5. Ensure that users have permission to view the record type.
  • Open respective Profiles for the user who is facing the issue.
  • Click on 'Object Settings' and open the Task object.
  • Make sure the user has permission to the record type for a particular action.

OUTPUT


Before modifying permissions



After modifying permissions



CONCLUSION

By following the above steps, we can verify the user permission & object configurations and modify them to make the actions visible to the user.


If you have any questions you can reach out our Salesforce Consulting team here.



Thursday, 30 June 2022

Salesforce Dynamic Related List in the lightning app builder

With the Salesforce Summer'22 release, Related lists can now be customized straight from the Lightning App Builder rather than the page layout editor with Salesforce's new Dynamic Related List.

What does salesforce's Dynamic Related List mean?
Dynamic Related Lists is the newest feature in the Summer’22 release, With the use of Dynamic Related List you can customize the related list directly in Lightning App Builder. By customizing a related list you can set how many records to display, which fields and actions to appear, and set filters on the related list.

Dynamic Related List – Single Component
The following characteristics set the dynamic related list - single component apart from the static related list component.

  • Define Related List Label and type of list
  • Configure Number of Records to Display 
  • Show/hide List View Action Bar
  • Define Related List Filters
  • Configure Actions 
  • Set Component Visibility

    Let's see how to add Dynamic Related List into page.

    Add Dynamic Related Lists in Lightning Page using Lightning App Builder 
    Follow the below steps to add Dynamic Related List - Single component one a Lightning Record Page, Here we are adding Dynamic Related List on a Account record page.

    • Click on Setup.
    • Click on Object Manager, Select Account.
    • Select Lightning Record Page, Click on Account Record Page.
    • Click On Edit.
    • Drag and drop Dynamic Related List – Single on the canvas.
    • After adding Dynamic Related List – Single, Configure all the properties which is shown in the below image.

    Dynamic Related List - Single
    • Clock on Save and Activate.

    Click Here to see release notes on Dynamic Related List.

    If you have any questions you can reach out our Salesforce Consulting team here.