Kanban using Lightning Components

Not sure if you have seen my old blog post that I wrote like 2 years ago on building a Lead Kanban (when actually Lightning Components just took off) using Visualforce Pages – https://shrutisridharan.wordpress.com/2016/08/22/creating-a-kanban-view-for-leads/

I am still a fan of Visualforce Pages and given a chance I would still develop in Visualforce Pages. But yes things have changed and adding Lightning Development Skills to your toolbelt has become inevitable! There is so much demand for Lightning Developers these days and it’s a mandatory skill to have on your Resume.

That being said, I thought it would be a great start to step into Lightning by polishing my old classic Lead Kanban and re-building it using Lightning Components. And luckily I was successful. It wasn’t easy(I swear!) and it indeed was a roller coaster ride. So let me take you all into the ride and I am sure at the end you are gonna love what Lightning Components can offer!

Why Build a Kanban?!?

So the first thing that would strike you is – Why should I even develop the old Lead Kanban(built using Visualforce Pages) in Lightning when Salesforce offers a Kanban View out of the box ?

So here is the answer to it –

  1. To get a hang of Lightning Components Framework
  2. To understand how external libraries like jQuery, jQuery UI etc. plays along with the Lightning Component Framework
  3. To learn about standard Lightning Events
  4. You can customize it however you want – add buttons for example!
  5. And last – to have some fun!

So let’s get started!

Sneak Peek

Screenshot_1

So that’s how the Kanban would look like in Lightning at the end 🙂 Now, at first glimpse you would have that typical “everything in here should be a component feeling“! Well I say it isn’t wrong! Lightning Component is indeed about breaking down your page or app into indivisible components and then building the App by tieing them all together just like how you would build using your Lego Bricks.

But I have felt that this practice of decomposing is not required all the time. It’s much easier when you don’t decompose into multiple sub-components. The additional overhead that would come your way when you have multiple components is facilitating the interaction between all of them using Custom Events. So for now let’s build this thing as a single component and keep it as simple and lucid as possible.

Apex Controller

At the heart, the initialize() method returns the columns for our Kanban Board and also the Lead Records. The Lead Records are grouped with respect to the LeadStatus and is contained within a Map. The DataFetchResult class encapsulates all these information and is returned back to the Component from the initialize method. On the other hand the updateLeadStatus() does two things – 

  1. Changes the LeadStatus on the Lead
  2. Also updates order of appearance of a Lead within a lane or  column on the Kanban Board

Drop Prohibited Columns

A new feature that isn’t available in the old Classic Kanban but I have introduced in the Lightning Component is – Drop Prohibition. There could be instances where the Sales Users are not allowed to drag and drop a Lead into a certain status. This is achieved by setting up a Custom Setting wherein the Admins can specify the prohibited statuses as comma separated values like as shown below –

 

Screenshot_2

Component Markup

The afterScriptsLoaded event on the ltng:require component kicks-off a chain of actions. We will get to the actions a bit later. Let’s look at the Column/Lane Headings of our Kanban Board.

The columns headers are displayed using the Path Component from the Lightning Design System. An aura:iteration iterates through the list columns and repeats the markup for each item on the Path Component.

Each column is rendered using the Lightning Design Grid System framework.

The most important tag to make a note of would be –

<aura:handler name="render" value="{!this}" action="{!c.applySortable}"/>

This handler listens to the standard render event and then fires the applySortable method in order to enable the drag and drop using jQuery UI.

It’s very important to note that this event is fired multiple times during the rendering life-cycle and at various instances such as when the DOM is updated as a result of dirty-checking and so on. So it’s mandatory that we put restrictions in place to ensure that the handler(i.e., applySortable) isn’t executed MANY times and ONLY when it’s needed.

Component Controller

The init method in the constructor is responsible for invoking the method from the Apex Controller that would return an instance of the DataFetchResult class that encapsulates the Columns and the Records.

Now we have a problem! Like as I mentioned before, the records are populated as a Map (grouped by LeadStatus) which would be represented as an Object in JavaScript. We cannot use the aura:iteration to loop over the keys of an object(this is such a deal breaker!). Thus we iterate the keys of the Object(which was a Map in Apex) to convert it to a linear array for the aura:iteration to work.

var rows = [];
for( var key in result.rows ) {
    rows.push( { value: result.rows[key], key: cols[key] } );
}

As discussed earlier, the applySortable function is responsible for applying the jQuery Sortable to our Kanban Columns thus making it function like a Trello Board(that drag and drop fantasy!). Now before even you start using jQuery to manipulate your DOM, you need to remember three things:

  1. Ensure your Scripts(jQuery Libraries) are loaded
  2. The DOM is ready(so damn important)
  3. You haven’t applied Sortable already

And thus we have all these checks in place –

/**
 * Apply the jQuery Sortable
 * when the DOM is ready and 
 * the Scripts have been loaded.
 */
if( scriptsLoaded && 
 !sortableApplied && 
 jQuery( ".slds-lane" ).length > 0
) {
   component.set( "v.sortableApplied", true );
 
   helper.applySortable( component );
}

Helper

The helper houses some utility methods such as show/hideSpinner, showToasts and the applySortable that is responsible for applying jQuery Sortable to the columns or lanes.

Now the most important thing to note while working with libraries like jQuery is the usage of –

$A.getCallback()

We need to make sure all the jQuery Event Handlers are wrapped within $A.getCallback since these libraries executes and modifies the DOM outside the rendering context of the Lightning Component Framework.

The Wrap!

Voila! That’s all you need to get this up and running. To make it easier, I have created an Unmanaged Package that you can install to bring all this Kanban goodness on the click of a button –

https://login.salesforce.com/packaging/installPackage.apexp?p0=04t0I000000qqzY

Here is a video that shows the Kanban in action –

 

 

Advertisements

10 thoughts on “Kanban using Lightning Components

  1. thanks for putting this together. i went down a kanban rabbit hole for an idea and this being easy to get up and running led me in some interesting directions. its also a final push to commit to components. keep on making cool shit!

    Like

  2. Hi Shruti, can this kanban view auto refresh. Say i have two teams working on the list of leads and one of them updates the record and it moves to different stage, will the data be reflected for both the users.

    Like

    1. Hello! Thanks for reading my blog. So if they have the tab open, NO, they will not see the change unless they refresh it. In case if you want to do this, you will have to use the Streaming API along with the lightning:empApi component to make this possible. Please let me know if you need any directions on how to achieve this.

      Like

  3. Hi Shruti,
    I appreciate your efforts in making this cool awesome kanban, I was looking for a similar one for my project.
    I am very new to salesforce and there by to lightning components, though I was able to understand the implementation details. I see that you are loading jQuery files from the resource folder – is it possible to share the files that have to be loaded ? or is it already mentioned n the blog? (if yes sorry for not noticing 🙂 )
    Expecting your reply, thanks !

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s