Thursday 9 September 2021

LWC: Share JavaScript code within a module & across your modules

 Introduction

One of the best practices while designing efficient lightning web component is to use utility javascript files to define the helper methods. This keeps the primary JavaScript file in your LWC module cleaner to read and debug. Most importantly to achieve reusability. In this blog, I would discuss & demonstrate the exporting-importing javascript functions.

Export within a module

Let's discuss this an example. Say I am developing a LWC module(homeComponent) in LWC to calculate certain maths equations. I need some functions to calculate difference between 2 numbers, products of 2 numbers etc. I received a JavaScript file(utility.js) from my fellow developer with these 2 methods defined. I just need to call those 2 methods in from my LWC.

Step 1 - would be to include the utility.js into my module homeComponent.


Step 2 should be exporting the functions in utility.js in order for homeComponent.js to consume it.

Step 3 would be to import the functions in homeComponent.js and use them.

When the connectedCallback is called, following would be printed in the browser console.


So, we have successfully imported two functions from our utility.js to our homeComponent.js file and used them.

This approach is called named export where we are specifying multiple functions to be exported.

Let me go one step further introduce another method in the utilty.js and make that as our exported method and keep the calculateDifference and calculateProduct methods as private methods. This way this I will only have to export one method and keep everything else in the utility.js as private.

Now importing the calculate function in similar way as previous one.

The browser log would look something like this now.


This approach is known as Export default, where we export only one function from a file. This is useful when there is only a single method to expose from a utility file. In case of multiple functions to export, named export is the way to go.

Export across modules

With this concept, I will briefly touch the approach of sharing JavaScript code across modules. This is widely used & more useful, however the concepts are same.

A good use case is displaying toast messages. In my projects, I refrain from invoking ShowToastEvent from each & every components, rather I keep a utility service component where I keep such reusable methods and call them whenever I require those functions.

My GlobalUtility.js would look like this

Notice that I imported my required modules(lightning/platformShowToastEvent) in my utility, so I wont have to import them in my homeComponent, the actual consumer module.

The named export & export default approaches are also applicable in this global utility too.

Hope it helps! Thanks, have a good day.

Tuesday 5 January 2021

A package.xml generator and editor

Introduction

Package.xml is a manifest file between your orgs during deployments. Developers/Admins who have worked on huge projects without proper DevOps implemented and tried to deploy the changes using package.xml know the pain of maintaining it.

Change Set being so easy in terms of accessibility and user friendly, it will take sometime for the salesforce world to move from changeset to package based deployment tools(e.g sfdx).

Recently I was forking with Metadata API using JavaScript and found this JsForce JS library with inbuilt functions to call salesforce APIs. So thought of utilizing it to built something useful. A package.xml generator!

Click here for GitHub Repo - Package XML Creator

Overview


The tool will:
  1. let the user select all kinds of components.
  2. let the user upload a xml file to resume working on that
  3. store the xml for a day
  4. be fast in rendering UI
  5. have easy accessibility
Little preview:



Implementation

We first need to store the component types with some configurable parameters in static resource. I preferred keeping a json file, as the VF page could very easily and efficiently read the file using Vanilla Javascript. And VF was an obvious choice as this tool needs to work in classic as well as Lightning Experience, skipping all the limitations of ltng:outApp.

The json file would look like this with parameters like ObjectAPIName, fieldToFetch, Method, IncludePckg etc. 

For the "let the user select all kinds of components" part, this tool uses static resource to store the mapping of metadata types with Metadata API reference. Instead of Metadata API, some component types need SOQL to fetch the list, like Dashboard, Report. Metadata API's listMetdata call requires a folder name to be specified for such component types, not very helpful for our use case.

Now that the configuration part is done, we would also need a VF page to display all the components and let user select them.

Few highlights from the VF page code:

The filter panel with component dropdown and upload package.xml option 


Reading the static resource and populating the dropdown on load:

 


Next was to "let the user upload a xml file to resume working on that" - a simple xml file upload and read in Vanilla JavaScript. After the file read, preparing the UI to show the selected components from the uploaded package.xml.


Next, we had to "store the xml for a day". Custom Objects are expensive in terms of read and write, we needed something faster & temporary. Platform Cache - it allows you to specify TTL - time to live. So we don't have to clear them explicitly. We are using the current user id and save timestamp to create a unique key for each package.xml. Users can use the generated URL to fetch the package.xml anytime within first 24 hours.

In terms of making the tool "be fast in rendering UI" - we have tried to use Vanilla JavaScript and plain CSS everywhere. All the server calls are using RemoteAction, since this tool might need to show a large number of components time to time, avoiding view state was an obvious choice. And to be honest, I wanted to play around with my new found love - Vanilla JavaScript. :)

In order to - "have easy accessibility", we thought of letting the users click anywhere on the row to select/unselect it. The usual checkbox selection gets very tiresome to click sometimes. So we just thought of letting the users give a bit of relief here. Don't worry, we still have the good old checkboxes too. Each row in the result section is a list item and it contains a inputCheckBox. 

Here is a rendered row:


Its nothing but a input checkbox inside a list item.

Following code in JavaScript in function toggleSelection,lets me find the list item that clicked.


Installation

Create a Platform Cache partition with the name - PackageXMLStorage with some Organization storage capacity. No need to make it default. If you are installing it in a dev org, trial capacity can be used.

The github repo comes with a lightning enabled tab - Package Creator. After the installation, access to this tab needs to be given to the targeted users using a profile or permission set.

Click here for GitHub Repo - Package XML Creator


Thank you for your time. Please feel free to post any questions, suggestions.

Tuesday 29 September 2020

Data Security within Salesforce Org - Profiles, Roles & OWD: A beginners guide

Salesforce is a transactional system which means the data that resides within Salesforce is supposed to be accessed by users regularly in form of some sort of transaction. Like any transactional system, Salesforce also has few features to hide or selectively hide few piece of information from selected users or if you look at it from the other side, show or selectively show few piece of information to selected group of users. Getting confused already? Hang on!

Lets cover this complex topic with an example. Think about a Time Tracker Application of a company. Contractors enter their daily worked hours into the system and their manager approves them. Towards the end of the month, the finance team accesses these approved hours and process the payments. Simple stuff.

The core object of such a system would be Daily Hours Entry[DHE]. Key fields would be Date worked(Date), Total Hours(Integer), Owner(User). The users(i.e. Contractors) will have their manager also assigned to them using Role Hierarchy.

Now before we design the sharing security of our Time Tracker Application, lets see what all tools we have and what wonders they can do for us.

The Salesforce sharing model is a matrix. One side of the matrix is Object Level Access[OLA] - the settings which defines what all objects a user will have access to and the type of access[Create, Read, Edit or Delete]. The other side of the matrix is Record Level Access[RLA] - the settings which defines, if you have access to an object from OLA**, which all records of that object would you be able to access. Like if that object has 100 records, you might not want a user to see all 100 of them but only his own 10 of them.

** The bold line is important, if a user do not have any access on an object using OLA, RLA is irrelevant to that user.

Sharing Setting Tools


The OLA tools:

1. Profile - Profile is the basic OLA tool we have. Every user will have one Profile assigned to them. We will define the access for objects, fields of those objects, Record Types, Page Layouts and some more advanced stuff which we can park for the time being. First 2 are important for now. Objects and Field of those objects.

2. Permission Set - This is another OLA tool and this works on top of what you define in Profile for a user. Permission Set will also have same options like what we have in profiles - Object access, field access. Then whats the need of Permission Set when we have Profile, right? Permission Set is used for expanding the access level we have set in profiles for a set of users. Example - say 2 users has same profile with read access on Account. One of them temporarily needs Edit access on Account for some reason. We would not create a separate profile for this short purpose, instead we will provide the user a permission set with Edit access on Account. So in combination of the existing profile[read] and this permission set[edit], the user will have read and Edit access on Account. And when the purpose is fullfilled, we will remove the permission set from the user, so he is back at read access on Account. You see how permission set was expanding the original access of the user?


Note: Permission Set can only expand the existing access, it can not shrink the original access given to a user by profile.


The RLA tools:

1. Org-Wide Defaults[OWD]: From the RLA perspective, OWD is the basic access defined for an org[Note: for an org, not for a user]. Anything that you define at OWD, like the name suggests, its applied Org-Wide. So here we define how records should be visible to users in our org. For each object, we have 4 options here

a. private: if this option is selected, the records of this object would be private in nature and the owner[usually the creator] of any record is the only person who can access the record. Nobody else can see the record.*

b. public read only: this option tells the org that records of this object can be seen by all users of the org but they cannot edit/delete it. Only the owner can edit/delete it.

c. public read/write: this is the most permissive access level. If this is selected, any user of the org can see, edit, delete it. But wait, it doesnt mean its a open field for grazing, users would still need OLA on that object, without that RLA is useless for them, remember?

d. controlled by parent: This is the fourth option and it's only available for those objects which are the detail[child] in one master-detail relationship. So the child object inherits the OWD setting of its parent object. If a user has access on a record of the parent object, it has access to the child records of that parent records. More on this sometime later.

2. Sharing Rules: This is the last RLA tool for us. Sharing rules works on top of OWD. Same like Profile-Permission Set, it can only expand the access, can not shirnk the original access. Here we can share selective records of an object to a group of users with Read Only or Read/Write access.


Okay, now that we have known our tools, lets use them to design our sharing model for Time Tracker Application.


TT Application will have below group of users:

1. Contractor - They are the people who will log their hours in Daily Hours Entry object. So they get Create, Read, Edit, Delete access on DHE object using Profile.

2. Contractor Manager - They are the people who will approve the DHE records created by their subordinates - they need Read & Edit access only on DHE using Profile.

3. Executive Leadership - They are basicaly Contractor Managers but since they also hold Executive level positions, they need visibility over the full system. As they play a Contractor Manager role in the system, their original profile is Contractor Manager. So satisfy their need of full visibility, we shall use a permission set for these handful of people. This permission set will have View All permission on DHE.

4. Finance Team - These people usually don't need any access on DHE because their work on DHE is limited to month end only. Lets say their work area is another part of the application, for which they have their own Finance Team profile with no access on DHE. A permission Set[Finance MonthEndAccess] with View All access on DHE will be assigned to these users only during month end. So we will expand their access to DHE keeping their original access on the system intact.

5. System Admins - They are the back end guys who keeps the application running and provides any technical support users need. So they need a full access of the system, so Read, Create, Edit, Delete, View All, Modify All access on DHE object. Supermans of this system!


So well and good. All done! Users should be able to get onto log their hours. But wait! We have only decided OLA, what about RLA? We don't want Contractor John to see and edit Contractor Smith's Daily Hours Entry records. We have hide these records, so that only the person who created them should see them.


So we set OWD for DHE to private. But again, we would also have to let the Managers see the records in order to approve them, right? Here is another tool we didn't mention earlier, do you see the little checkbox next to the OWD selection drop-down? Grant Access Using Hierarchies. Just tick this checkbox, this will allow the private records to be visible to the owner's manager. So this little checkbox will take care of our this crucial need.


So now, our records are secured and shared with the creator and his/her manager only. The managers[having profile Contractor Manager], can only read and edit the record based on his profile access. 


Lets put this on a matrix. Click to enlarge the image.




What a beautiful world!


I have tried to cover only the basic of Sharing Settings. Needless to say this is just the tip of the iceberg. However, this is the most crucial part to understand for beginners. Once the co-working of OLA and RLA is understood, rest of the Data Security journey will be effortless.


LWC: Share JavaScript code within a module & across your modules

 Introduction One of the best practices while designing efficient lightning web component is to use utility javascript files to define the h...