Sunday 30 April 2023

Reactive Flow Components in Spring 23


Introduction

A typical scenarios where I favour lightning pages over flows is where a user's decisions around field values need to have a major impact on the rest of the elements being displayed, and where a wizard interface would slow the user down too much. A great example of this is our BrightMEDIA order booking page. As the user inputs information about the type of advert, where it needs to appear, what size it is and when it appears, the price is dynamically recalculated and displayed. The user typically has the customer on the phone, and there may be a few cycles of tweaking the details to hit a price point - what happens if we make it a bit smaller, move it to another section etc. Paging back and forward through the wizard wouldn't be a great experience, along with the need to keep saving the order as navigation between pages takes place. 

With the Spring 23 release of Salesforce, it looks like in future flow will become a candidate for this kind of user interface with the advent of the Reactive Flow Components beta. Simply put, you can wire the input of one component up to the output of another component, and react when changes occur. 

As this is a beta, you'll have to opt-in to it for any org where you want to use reactive components by checking the box in the Automation Settings 

The Sample

A lot of the demos around reactive anything tends to be a table of accounts that updates when the user inputs the desired number of entries. That's exactly what I started with to get a handle on how this works, but it's not overly interesting, so I decided to return to our BrightMEDIA accelerator for inspiration. 

One of the more complex Lightning Components we have in the order booking page is the data picker. This can render as a drop down or a calendar, with dates available for selection rendered in specific styles depending on whether capacity is available, if they are contiguous with a selected start date, and many other rules. 

So for my sample I have a couple of custom Lightning Web Components:

  • A Publication Picker - this is a simple choice style component, but I've had to go custom as the standard choice component doesn't yet have reactive support. Each publication has a checkbox that indicates if it publishes on weekends as well as weekdays.
  • A Date Picker - this is a calendar component that by default displays a 7 day week, but if the selected Publication doesn't publish on weekends, switches to a 5 day week.
I create a simple screen flow and add a two column screen component, with my two custom components:



The Publication Picker defines an output property named publishesWeekends, which is set to the value from the selected Publication. I wire this to the weekends input property on the datePicker:


When I run the flow, as I switch my choices between Publications, the Date Picker changes how it renders to reflect 7 days a week publishing:


or 5 days a week:


It's early days for this, but definitely a step in the right direction. This feels like an area where you'll benefit from developer support to create truly reactive experiences, as this will really pop with custom components that can change their styling based on user selections. 

The Code


You can find the code behind the sample in Github. Spin up a scratch org, deploy the code, create a couple of publications and run the flow.  Don't forget to opt in to the beta as outlined above, or like me you'll sit there scratching your head trying to figure out what you've broken :)
More Information



Saturday 15 April 2023

BrightSIGN: Updating a Record when a Signature is Captured


It's been a while since I've had the time to work on the BrightSIGN (formerly known as Signature Capture), but I had a couple of days off this week and what better way to spend them than a bit of front end coding.

The Problem

A feature requested by a user posting a review on the app exchange was the ability to update a field on the record that the signature image is attached to. There are a number of ways to achieve this, but one thing was for sure - this wasn't going into the package. Dynamically generating update statements to change records in the subscriber org is the kind of thing that really slows down the security review!

The scenario I wanted to satisfy was a Lightning App Builder page that would show a BrightSIGN component, and once the user had saved the signature image, update the record and hide the BrightSIGN component so they weren't asked to sign multiple times.

I was originally thinking that I'd go the route of a trigger on Attachment/ContentDocument, depending on how the component was configured, but I decided against this for a couple of reasons - 

  1. I'd have to make some assumptions about the name of the attachment/content document in order to determine that it had been created by BrightSIGN, which would lead to false positives if attachments/documents with the same name were used elsewhere
  2. I'd be detached from the front end and unable to signal to the container that the record had been updated - this is key when I want to conditionally render parts of the page depending on whether the record has been 'signed' or not.

The Solution


I ended up writing very little code to satisfy this requirement, as I was able to leverage the existing SignatureCaptured event and the force:recordData standard component.  In the example scenario I'm setting a field with the API name 'Signature_Captured__c' on an Account record once the user has 'signed' it.

To start with, I created a Lightning App Builder record page for Accounts, which I dropped a BrightSIGN component onto. This component is conditionally rendered and only appears if the Signature_Captured__c checkbox is not set :



I then created a new local component - SigCapUpdateRecord - which retrieves the field that I'm interested in for the current record using the force:recordData component, thus saving me writing any Apex code :
<force:recordData aura:id="recordUpdater"
    recordId="{!v.recordId}"
    fields="Signature_Captured__c"
    targetFields="{!v.theRecordFields}"
    targetError="{!v.recordLoadError}"
    mode="EDIT"
    />    

This component also has a handler for the SignatureCaptured event:

<aura:handler event="BGSIGCAP:SignatureCapturedEvt" action="{!c.handleCaptured}"/>

Thus when the user saves the signature image, the handleCaptured method from my component's controller is invoked. This sets the Signature_Captured__c field and updates the record using the force:recordData component, again avoiding me having to write any Apex code. Once the update is complete, the view is refreshed to notify the container that it's changed and allow any conditional rendering to be re-evaluated:

handleCaptured : function(component, event, helper) 
{
    component.get('v.theRecordFields').Signature_Captured__c=true;

    component.find("recordUpdater").saveRecord(function(saveResult) {
        var resultsToast = $A.get("e.force:showToast");
        if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
            resultsToast.setParams({
                "type":"success",
                "title": "Record Signed",
                "message": "The record whas been marked as signed."
            });

            resultsToast.fire();

            $A.get("e.force:refreshView").fire();
        }
        
        // error handling
    });
}

You can see a very brief video of this below :


The Code


You can find the code in the BrightSIGN Samples repository - look for the SigCapUpdateRecord component. Note that you will need to either deploy the samples or manually create a Signature_Captured__c field on the Account sObject in order to try this out.

Related Posts




Saturday 1 April 2023

Artificial Indolence - Your Automated Accomplice



Hot on the heels of the Einstein GPT launch at TrailblazerDX, it gives me great pleasure to announce Artificial Indolence. If you are lazy, workshy, or just plain incompetent, Artificial Indolence can help you to hang on to your job while underperforming, far longer than anyone would reasonably expect.

Artificial Indolence is a general purpose tool (GPT), with use cases across the enterprise, including:

Case Work Deflector

The lazy service rep's worst nightmare - in spite of the best efforts of Einstein, the customer was able to raise a case and it's been assigned to you. Drawing on a training set of over a billion work-dodging communications, Artificial Indolence presents you with a tailored response that clearly explains why you are the worst person to be assigned work for the specific customer and problem. Clearly calling out your lack of ability and experience, it will be obvious to any manager that this can only end in disaster. If you've chosen the Communication Bus add-on, it will also identify a range of your peers who the work would be better assigned to and throw them under the bus.

Closed Lost Justifier

Our most successful feature to date, and perfect for the sales rep who just can't be bothered. When your lack of effort inevitably leads to an Opportunity being marked Closed Lost, Artificial Indolence generates a plausible reason why the stars didn't align in spite of your herculean efforts.

Activity Delayer

Rather than disappointing your customer all at once by not completing a job on time, drip feed the disappointment over weeks if not months with Artificial Indolence Activity Delayer - the customer will receive confusing communications outside working hours, and with any luck will blame themselves for not responding. If you've sprung for the Meeting Avoidance add-on, Indolence will automatically schedule meetings when most of the invitees have conflicts - the meeting will never happen and it's because everyone other than you is too busy!

Coverage Concealer

One for the developers who aren't interested in writing unit tests - Artificial Indolence will generate huge classes with 100% test coverage to bring the org coverage up to 75%. As these classes are based on genuine examples found in other orgs, they serve a real purpose (unless the examples were also generated by Indolence of course). Good enough to convince Salesforce to increase your Apex character limit, or three months free!


As befits it's purpose, Artificial Indolence is right now a collection of smoke, mirrors, mock ups and brochureware. Stay tuned for details of the pilot program that nobody will be accepted on to.