Close all Tabs in a Lightning Console


There is an idea on the Idea Exchange about looking for a way to close all tabs in a Lightning Console App.  It’s an existing option in Classic that hasn’t yet made its way to Lightning.

Lightning Console: Close all tabs option

I’ve spent way too much time manually closing tabs and wanted a way to make this easier.

I stumbled across a reference to a component that could be used to refresh a tab in a console and saw that it used a reference to lightning:workspaceAPI.  I was able to use this Lightning Console JavaScript API to query the open tabs in a console view and choose which ones I wanted to close.

There is some debate in the comments on the idea exchange about whether or not to leave pinned tabs open when performing a Close All tabs.  I designed my component to take a single parameter to specify if pinned tabs should be closed or left open.

It’s easy to implement on the Utility Bar.


When selected, it pops up a Close Tabs button and the component takes care of the rest.


The component consists of three parts:

  1. Markup (closeConsoleTabs.cmp)
  2. JavaScript Controller (closeConsoleTabsController.js)
  3. Design (parameter) File (

You can get the complete source code and installation instructions here:


Check it out and take advantage of a great time saver.


Implementing a Closed/Lost Reason on Opportunity


A recent blog post by Jared Baker of Cloud My Biz suggests including a Lost Reason picklist field on your Opportunities to assist with understanding why some deals don’t close and allowing you to focus on better quality deals.  Here’s an overview of how I have implemented that for my Sales team.

Create a Picklist of Closed/Lost Reasons

Choose reasons that are meaningful to your organization and will provide useful groupings for your Reports and Dashboards.  Here’s my complete picklist for Lost/Cancelled Reason:


In addition to a custom picklist field for Lost/Cancelled Reason, I also added these fields:

Field Type Description
Trigger_Lost__c Checkbox Use button/link to set this field to trigger the Closed Lost Process Builder and control the Reason picklist values
Closed_Lost_Notes__c Text Area Additional details on why the deal was lost
Competitor_Lost_To__c Picklist List of competitors

Special Processing Note:

I share the Visualforce page and fields outlined in this post to also handle reasons we might Cancel an Opportunity after it has been Closed Won rather than Lost.  The Closed_Lost_Reason__c field is a Dependent Picklist field controlled by the value of Trigger_Lost__c.  I control what selections are available based on the value of the Trigger Lost field.


For more information on Dependent Picklists see:

Dependent Picklists

Try It Out: Create a Dependent Picklist

Add a Custom Button to Trigger the Lost Processing


My Lost button executes some JavaScript that sets my Trigger Lost field to True and opens a custom Visualforce page to collect data for my Reason, Notes and Competitor fields.


var myquery = "SELECT Id, Name, Trigger_Lost__c FROM Opportunity WHERE Id = '{!Opportunity.Id}' limit 1";

sforce.connection.sessionId = "{!$Api.Session_ID}";
result = sforce.connection.query(myquery);
records = result.getArray("records");

var myObject = records[0];
var updateRecord = new Array();

myObject.Trigger_Lost__c = true;

result = sforce.connection.update(updateRecord);

window.location = "/apex/Opportunity_Lost?id=" + "{!Opportunity.Id}";
alert('Could not Trigger Process: '+result);

Provide a Visualforce Page to Collect Details for your Lost Fields

I created a simple page with only the fields I wanted to capture when setting an Opportunity to Lost.


Shared Visualforce page used to present and collect reason for Opportunity
being set to either Closed Lost or to Cancelled.
Closed Lost Reason is a dependent picklist based on the value of Trigger Lost

Eric Smith - GWI - May 2016
<apex:page standardcontroller="Opportunity">
<apex:messages />
<apex:sectionheader title="{!$ObjectType.Opportunity.label} Edit" subtitle="Lost/Cancelled Opportunity"/>

<chatter:feedwithfollowers entityId="{!Opportunity.Id}"/>

<apex:form >
<apex:pageblock mode="edit" title="{!$ObjectType.Opportunity.label} Edit">
<apex:pageblockbuttons >
<apex:commandbutton value="Save" action="{!Save}"/>
<apex:commandbutton value="Cancel" action="{!Cancel}"/>

<apex:pageblocksection title="Lost/Cancelled Details" showheader="true" columns="1">
<apex:outputtext label="Stage" value="{!Opportunity.StageName}"/>
<apex:pageblocksectionitem />
<apex:inputfield value="{!Opportunity.Closed_Lost_Reason__c}" required="true"/>
<apex:pageblocksectionitem />
<apex:inputfield value="{!Opportunity.Closed_Lost_Notes__c}" required="false" style="width: 500px; height: 100px"/>
<apex:pageblocksectionitem />
<apex:inputfield value="{!Opportunity.Competitor_Lost_To__c}" rendered="{!Opportunity.Trigger_Lost__c}" required="true"/>
<apex:pageblocksectionitem />
<!-- This next field needs to be on the page for the dependent picklist to work -->
<!-- 0px keeps it from displaying or being changed -->
<apex:inputfield value="{!Opportunity.Trigger_Lost__c}" style="width: 0px; height: 0px"/>



Special Processing Note:

Competitor Lost To is not rendered if I’m processing a Cancel rather than a Lost and Trigger Lost is on the page because it controls the values displayed in the Closed Lost Reason picklist.

Adding More Control with a Validation Rule

I didn’t want my users to be able to select Other as their reason without explaining why so I added a Validation Rule requiring 50 or more characters in the Closed Lost Notes field if they selected Other as their reason.


Process Builder kicked off by Trigger_Lost__c

When the Lost button Javascript executes, it set the Trigger_Lost__c checkbox field to True and saves the Opportunity record.  That record change causes my Stage: Set Closed Lost Process Builder to execute.  The only action I’m currently doing there is setting my Opportunity Stage to Closed Lost.


How do I use this Data?

Here’s a monthly report I run that lists all of my Lost or Cancelled Opportunities.  It is organized by what Stage the Opportunity was in before it was changed to Lost.


Go ahead and give this one a try

Adding this feature to your org will give you some good practical experience with Custom Buttons, Visual Force pages, Dependent Picklists, Validation Rules, Process Builder and Reports.

Why this element should be first in all of your Visual Workflows


Have you ever wanted to temporarily disable a Visual Workflow?  How about wanting to debug your flow with some test data?

Add this simple Assignment Element to the beginning of your flow and you can run your flow with test data (1), disable your flow (2) or fully deploy your flow (3).


(1) Run your Flow with Test Data

In the Assignments section of the Assignment Element, provide a test data value for each of your flow’s input variables.


When you select Run, your flow will execute with your test data as input.


(2) Disable your Flow

If you want to temporarily keep your flow from executing, just remove the arrow linking your Assignment Element to the next Element.


Don’t worry about the General Warning messages about sections that are never used.  Your flow is still valid but only the Assignment Element will be executed, effectively disabling your flow.


(3) Deploy your Flow for normal usage

Select the first Element after your Assignment Element as the Starting Element and your flow will execute normally.


Again don’t worry about the Warning Message.  Your Flow is ready to go.


Special Admin Tip:

Update the description and save each of your modified flows as a new version so you can Activate whichever version of the flow you want at any time.


There you have it.  One simple Assignment Element at the beginning of your Visual Workflow and you can use it three different ways.



How to tell Process Builder to “Do Nothing”


As you may have seen in my previous post about how to make one Process Builder execute before another Process Builder, I used an action called “Do Nothing”.

How does Process Builder determine its next steps?

d1When a criteria node gets evaluated in Process Builder, it is either True or False.  From there the flow continues to the next criteria node if the evaluation was False or executes one or more actions if the result was True.

After your action(s) execute, you can have the Process Builder stop or continue on to the next node just like it would have if your criteria had been false.

Why would I want to tell Process Builder to do nothing?

pb2dMy use case in setting the order of execution for a couple of Process Builders required that one of my Process Builders would test to see if it was its turn to execute and if it was not, it would stop.

But, in order to stop, the Process Builder requires that at least one action be defined.  When faced with the need to create an action that doesn’t really need to do anything, most administrators probably just create an Update Records action that sets a field equal to itself.


To me, this seemed a bit cumbersome.  I wanted to find a way to create a reusable action that I could easily put in any Process Builder and have it do nothing.

action-typesAll of these actions are designed to do something.  They are either unique to the object your Process Builder is built around, require some additional information, or need a link to something else that already exists like a Chatter Group or email template.

My first attempt was to create an invocable Process Builder that I named “Do Nothing”.  It had one criteria node that was always False (Formula: 1=0) and one action that would never get executed.  My action was the “No Change” update shown above.

The primary drawback to this solution was that I would need to create a new invocable Process Builder for each different object I was working with.

Another solution was to create an Apex class that didn’t do anything and just call that as my action.

public class Do_Nothing {
public static void doNothing() {}

This works for any Process Builder on any object.  However, it is ‘code’ and not ‘clicks’ and you do have to create and deploy it from a sandbox.

How to build your “Do Nothing” Visual Flow

My final solution was to create a Visual Flow that I could call from any Process Builder on any object and have it do all of the nothing I needed to have done.



  1. Create a new Visual Workflow and add an Assignment stepd3
  2. Name the step Do Nothing and give it a descriptiond4
  3. Create a new variable to use in your assignmentd5
  4. Set your assignment step as the flow’s start elementd6
  5. Name your flow Do Nothing and save it as an Autolaunched Flow and don’t forget to Activate your flow
  6. In Process Builder, pick Flows as the Action Type and select your new Do Nothing flowd8

There you go – Something for Nothing!

Update: November 14, 2016

Tip for Visual Workflow:

Say you are trying to debug something where you are using an Autolaunched Flow that is called from Process Builder.  If you want to temporarily disable your Flow and try to deactivate it, you will get an error when running your Process Builder.

Just update your Flow to include the “Do Nothing” step, don’t connect it to anything and make it your start element.


Activate the “Do Nothing” version and your Process Builder won’t generate the missing flow error.


Be sure to change the description so you’ll know what version you’ll need when you’re debugging.



How to make one Process Builder execute before another Process Builder


What is the order execution in Salesforce?

It is all laid out in Salesforce’s Triggers and Order of Execution.  Every type of trigger and action happens in a set order.  What is not set is the order of execution of items of the same type such as a collection of Process Builders.

If your use case requires that a particular Process Builder gets executed before another one then you will need to control the sequence yourself.  One option is to redo all Process Builders for a single object as invocable Process Builders and then call them in order from a controlling Process Builder.

Not wanting to recreate my Process Builders from scratch, I used a different technique to put two Process Builders in the order I wanted.  I had the first Process Builder set a value that the second one looks for.  The second Process Builder will not continue execution if the first hasn’t yet executed and set the value.

My Problem:

I have two Process Builders that I created to act on the Opportunity object.  One contains most of the workflow I’m doing when the Opportunity record changes.  The other one was only for updates I needed when the Opportunity record was created.  This should be fairly straight forward except that the Record Update Process Builder was executing before the Record Create Process Builder.

My Solution:

I was able to resolve the sequence the Process Builders executed by  first creating a checkbox field in my Opportunity that would default to checked when a record was created.  Then my Opportunity Create Process Builder would clear the checkbox as its last action.  My Opportunity Change Process Builder first tests the checkbox and only continues if it has been cleared.


  1. Create a custom field on the Opportunity object.  The field type should be Checkbox with a default value of Checked.  This field does not need to be on any page layouts.field
  2. Add a final criteria step in the “Opportunity – Record Create” Process Builder.  This just needs to execute the actions without testing for any criteria.
  3. Add an action to clear the checkbox field.
  4. Add a first criteria step in the “Opportunity – Record Changes” Process Builder.
  5. The criteria should check if the checkbox field is still checked.
  6. Continue on with the rest of the Process Builder only if the result is False.


With the new field added to Opportunity and the added steps in my Process Builders to test or clear the field, I am able to force my “Opportunity – Record Create” Process Builder to always execute before my “Opportunity – Record Changes” Process Builder when a new Opportunity record is created.

You probably noticed that the first Immediate Action in my Record Update Process Builder says “Do Nothing”.  Read my next post to find out how to tell your Process Builder to do nothing.

Here’s how to produce your own Process Builder OneView documentation as seen in this post.

Process Builder OneView

How often have you gone back to a Process Builder flow and tried to see what all of your selections and settings are?  Have you struggled with trying to create documentation for your Process Builder flows?  How many screen shots do you need to take to try and share your Process Builder?

See below for some of the challenges you face when reviewing your Process Builder flows.

  • You need to hover just to see the full name or description of your Process Builder.Hover_1
  • You can’t see your full field names unless you hover over each one.
  • Values and formulas are hidden as well until you hover over them.Hover_3
  • In order to see the full name of an action you need to click on it.Click_1
  • Certain settings are not visible unless you click to expand.Click_2
  • In order to see your Criteria logic, you need to deactivate, clone and edit your Process Builder.Click_3

I was frustrated with all the steps to go through just to see what I had already created in my Process Builder flows.  I wanted a better way to look at and document my Processes.

Realizing that the details of each flow were stored in my Salesforce organization as XML based metadata, I wondered if there was a way I could extract this data then recreate an entire flow diagram and a descriptive report of all of my criteria, actions, formulas and settings.


I was able to extract all of my flow metadata into individual files using the Workbench utility.


The next, and biggest, challenge I faced was what to do with that data and how could I put it into a format that was readable and useful.  I decided that Excel & VBA offered a way to parse the XML data and had the formatting power I was looking for to create the output I needed.

I started with the diagram itself.  I wanted to be able to see the full names of the Criteria and Actions on the diagram.


With a lot of testing, I made sure I could handle multiple scheduled actions, different action types, large numbers of actions and different types of branching.




The diagram is only a small part of everything you need to see to document your flow so I extended the output with a complete description of all of the steps and settings in the flow.




Once I had the diagram and the details created, I added additional options to print the output or create PDF files, offer portrait or landscape orientation, wrap or shrink text to fit and scale to single or multiple pages.

OneView Screen.PNG

I also provided options to display the diagram and the details together on the same page.


Diagram on Left side



Diagram on Right side


This was a challenging yet interesting project and with this utility, I can now see my entire Process Builder flow in a single, easy to follow document.  It is truly OneView for your Process Builder flows.

Update: Process Builder OneView is now available as a subscription.  $99/year per user.

OneView Product Page


Why won’t Process Builder let me wait less than one hour?

Ok.  I have a Salesforce Process Builder flow I created that sets a few field values, sends out some notifications and creates a Task after I assign a newly closed Opportunity to a member of my Project Management team.  I found that there were times I would change my mind right after making an assignment so I decided to have Process Builder wait for 5 minutes after my assignment before it went and did its thing.

Time Lapse

I can select hours or days but not minutes.  No problem.  Let’s see, 5 minutes is 5/60 of an hour or .083 minutes.  Away we go.

Time Lapse2

It turns out you can only select a whole number of days or hours in Process Builder.  So how can I tell it to wait for only five minutes?


But, 5 minutes from now is 1 hour from 55 minutes ago!  Since I can tell Process Builder to wait for 1 hour after any time field value, all I need to do is to create a custom formula field that is always 55 minutes ago.

My new field needs to be set to the current time, NOW(), less 55 minutes.  I need to specify my minutes as a fraction of a day so I’ll multiply 55 minutes times 1 day divided by 24 hours in a day divided by 60 minutes in an hour.


My new field will always be equal to 55 minutes before the current time when it gets evaluated so I can now tell Process Builder to wait for 1 hour after 55 minutes ago.

Time Lapse4.PNG

You can set this up for any time period you want.  Just change the number of minutes in the formula field from 55 to 60 minus however many minutes you want to wait.