UnofficialSF has a new Service Cloud Channels Section

UnofficialSF.com has added a new section devoted to Service Cloud channel functionality, which is increasingly driven by flow-based services.

Check it out here. If you know of a good post or page on the topic, don’t hesitate to let us know via the form on the home page.

From Vincent Finet: Analyze your Org with OrgCheck

OrgCheck is an easy-to-install and easy-to-use Salesforce application in order to quickly analyze your org and its technical debt. Flow users, note that some of what it reports on relates to your existing automations.

Website: https://sfdc.co/OrgCheck
LinkedIn: https://www.linkedin.com/company/sf-orgcheck



How does it work?

  • You install this application directly in the org you want to analyse (sandbox or developer edition). It analyzes many different facets of your org.
  • Then, you navigate through the tabs in the app to discover what it has found.
  • More information at https://vincefinet.github.io/OrgCheck/installation/

How does it look like?

image.png
image.png
image.png
image.png

What are the use cases of the app?

  • Data Model
    • Get all information of an Object in a unique page
    • List all Org Wide Default in a unique page
    • Identity custom fields with bad practices
  • Profile and Permission Set
    • Identity custom profiles that are not assigned
    • Identity permission sets that are not assigned
    • Identify permission sets and profiles correlations
    • List IP and Login Hours restrictions on all profiles
  • Role hierarchy
    • Check if your role hierarchy is not too deep
    • Show role hierarchy in a diagram with empty roles identification
    • List roles with bad practices
  • Users
    • List users that never logged
    • Key system permissions for each users
  • Public group and Queues
    • List groups and queues
    • Identify all users of groups and queues (recursive computation)
  • UI Composants
    • List Visual Force pages and components with bad practices
    • List Aura and LWC components with bad practices
  • Apex Composants
    • List Apex Classes with bad practices (old API version, no explicit sharing, etc.)
    • List Triggers with bad practices (contains logic, DML, SOQL, etc.)
  • Automations
    • Workflow rules without actions
    • Process Builders / Flows
  • Batches
    • Failed jobs
    • Scheduled jobs

A Flow Screen Component that plays sounds

Created by Yumi Ibrahimzade

ABOUT
This is a Lightning Component that plays a sound effect.
It can be used on Flow Screens and Lightning Pages.
In order to play a sound, you have to upload the sound file as a Static Resource and then enter the name of the file to the “Sound File” parameter.

INSTALLATION

PARAMETERS
Sound File – Enter the name of the sound file.

CONSIDERATIONS
This component loads the sound file from Static Resources and plays it. So it is recommended to use smaller file sizes, otherwise it might take some time to load the file.

HOW TO USE
1- Upload the sound file as a Static Resource.

2- Add “SoundCMP” to your Flow Screen.
3- Enter the name of the sound file to the parameter called “Sound File”.

Displaying Map with markers in Flow screen using Lightning Components by Terence Chiu

Load a Visualforce Page with Parameters in Lightning

I was looking to display Visualforce pages using the RecordId inside of my Lightning Record pages. After finding a very elegant solution to pass the RecordId from a Lightning Component container to a Visualforce page displayed in an iframe I decided it was time to move the solution from the Sandbox into Production.

What worked perfectly in the Sandbox gave me nothing but a blank component in Production. After spending way too much time trying to find a solution, I gave up and went to Plan B. (edit: my other component works once I adjusted my clickjack settings)

SANDBOX
PRODUCTION

Plan B

I was able to use a Lightning Component to navigate to a URL, so I built a component to build the URL for the Visualforce page including the parameter for the RecordId of the page.

    doInit : function(component, event, helper) {
        var params = new Array();
        params.push(component.get('v.recordIdVar') + '=' + component.get('v.recordId'));
        params.push(component.get('v.otherParams'));
        component.set('v.queryString', params.join('&'))
    },

    openPage : function(component, event, helper) {

        // Show spinner once button is pressed
        var spinner = component.find('spinner');
        $A.util.removeClass(spinner, 'slds-hide');

        // Build url for Visualforce page
        var vfURL = 'https://' + component.get("v.domain") + '--c.visualforce.com/apex/';
        vfURL = vfURL + component.get("v.pageName") + '?';
        vfURL = vfURL + component.get("v.queryString");
        console.log("VF URL: ",vfURL);

On a standard Lightning page, the component switches from the Record page to the Visualforce page, returning to the Record page when the Visualforce page exits.

                // Handle non-console user
                console.log("Not in Console");
                var urlEvent = $A.get("e.force:navigateToURL");
                urlEvent.setParams({
                     "url": vfURL
                });
                urlEvent.fire();

It is a bit different on a Console page where the Visualforce Page is loaded in a new Tab which reverts to the Record page Tab when exiting. This normally leaves a second “dead” Record page Tab behind so I made sure the component saved the ID of the Calling Tab or Subtab and closed the “dead” tab when finishing with the Visualforce page.

// Check to see if running in a Console
    var workspaceAPI = component.find("workspace");
    workspaceAPI.isConsoleNavigation().then(function(consoleResponse) {            
        console.log("IsConsole: ", consoleResponse);
        if (consoleResponse) {

            // Save current tab info
            workspaceAPI.getFocusedTabInfo().then(function(tabResponse) {
                var closeTabId = tabResponse.tabId;
                var closeTitle = tabResponse.title;
                var parentTabId = tabResponse.parentTabId;
                var isSubtab = tabResponse.isSubtab;
                console.log("Current Tab: ", closeTabId + " | " + closeTitle);
                console.log("Is Sub: ",isSubtab," ParentId: ",parentTabId);

                // Open Visualforce Page in a new tab
                if (isSubtab) {
                    workspaceAPI.openSubtab({
                        parentTabId: parentTabId,
                        url: vfURL,
                        focus: true
                    }).then(function(openSubResponse) {
                        console.log("New SubTab Id: ", openSubResponse);
                    })
                    .catch(function(error) {
                        console.log(error);
                    });                        
                } else {
                    workspaceAPI.openTab({
                        url: vfURL,
                        focus: true
                    }).then(function(openParResponse) {
                        console.log("New ParentTab Id: ", openParResponse);
                    })
                    .catch(function(error) {
                        console.log(error);
                    });                        
                }

                // Because exiting the VF page will reopen the object record,
                // close the tab we started on
                if (tabResponse.closeable && !tabResponse.pinned) {
                    workspaceAPI.closeTab({
                        tabId: closeTabId
                    }).then(function(closeResponse) {
                        console.log("Closed: ", closeTitle);                      
                    })
                    .catch(function(error) {
                        console.log(error);
                    });                            
                } else {
                    console.log("Left Open: ", tabResponse.title);
                }
            })
            .catch(function(error) {
                console.log(error);
            })

Rather than load the Visualforce page immediately, I display a button. On the button press, the component loads the Visualforce page.

<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">

    <lightning:workspaceAPI aura:id="workspace" />

    <aura:attribute name="buttonLabel" type="String" />
    <aura:attribute name="buttonVariant" type="String" default="neutral" />
    <aura:attribute name="domain" type="String" />
    <aura:attribute name="pageName" type="String" />
    <aura:attribute name="recordIdVar" type="String" />
    <aura:attribute name="otherParams" type="String" />

    <aura:attribute name="queryString" type="String" />

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

    <lightning:card>
        <lightning:layoutItem padding="around-small">
            <lightning:button label="{!v.buttonLabel}" variant="{!v.buttonVariant}" onclick="{!c.openPage}" />
            <lightning:spinner aura:id="spinner" alternativeText="Loading" variant="brand" size="large" class="slds-hide" />
        </lightning:layoutItem>
    </lightning:card>

</aura:component>

I’ve made the component as generic as possible by providing the following attributes one can use when placing the component on their Lightning Record page.

  • Button Label (Text to appear on the Button)
  • Button Variant (Button styling: base, neutral, brand, destructive, success)
  • Domain Name (Your Production or Sandbox domain name)
  • Visualforce Page Name (The API Name of the Visualforce Page)
  • RecordId Parameter Name (The name of the URL parameter for the RecordId)
  • Additional URL Parameters (Any other URL parameters & values)

Here’s the Component in Action