Nerd @ Work

When Salesforce is life!

[Salesforce] ORGanizer for Salesforce is on the AppExchange!

That’s one small step for [a] man, one giant leap for mankind” (cit.)

It’s with huge pride that I announce that the ORGanizer for Salesforce Chrome Extension has successfully passed the security review and it is finally on the AppExchange!

We’ve just celebrated 1 year since the pubblication on the Chrome Web Store and after 1 month since the request sent to the AppExchange team, we’ve been delivered this awesome gift.

Now we can proudly show this amazing logo:

From now on the ORGanizer for Salesforce Chrome Extension will be listed as a free app on the AppExchange.

A huge thank you to all my Ohana, who constantly supports me in this free-time project: this achievement is your achievement!

Remember that ORGanizer for Salesforce Chrome Extension is a free app, so please share your love and if you can, donate to the cause!

ORGanizer loves you all!

[Salesforce / Chrome Extension] Happy birthday to the ORGanizer: 1 year on the store!

Checking my diary agenda I could not believe: ORGanizer‘s first go live was exactly 365 days ago!

I wanted to share my love and expertise for Salesforce in one single Chrome Extension to be free for all, and after 1 year I receive cheers from my Salesforce pals because ORGanizer helps them successing in their daily tasks!

Here are some quick numbers:

  • 20 releases
  • users from 127 countries
  • 4000 active users ca.
  • 28 new features (7 suggested by you)
  • 47 enhancements (17 suggested by you)
  • 32 bug fix (9 suggested by you)
  • 81500 login actions in the last month
  • 222 daily logins in the last month

The analytics (recently introduced) say that the numbers are rapidly increasing and the adoption rate is getting higher and higher.

The most important number is the active users:

And indicates the number of users that day after day keep getting the ORGanizer on their Google Chrome browsers…and it is incresing day by day, and I cannot be happier!

The ORGanizer is more than the extension itself.

Trying to make it the most amazing Chrome Extension ever, there an ecosystem of side projects and systems to help me achieving this aim.

ORGanizer site

This is the central information repository for the extension.

FAQ page

A complete extension guide updated at every release.

Video guides

Support

Active support site where you can report a bug or suggest a new feature.

This is linked to my Salesforce CRM org where I store all the stuff.
It also uses an Heroku app to send the email used to confirm your identity.

Next Release page

This page contains all features and bugfix in development or developed, that will be release in the next release.
Also this feature is related to my personal ORGanizer CRM org.

Change Log

A list of all features delivered in all releases.

Donations and Swag Store

Donations link and a link to the Swag Store to get some cool ORGanizer swag to allow me keeping the extension free for all.

Live Messages

Live messages to get live data to users about the extension, like unexpected bugs or general info.
I use ORGanizer like you do, so I wanted to put in place a feature to communicate with my ORGanusers.

Online reviews
I received amazing reviews from Salesforce community leaders:

Who made it?
I’m the only person behind the ORGanizer but my dear friend Davide D’Annibale is helping me with all the graphics (I litteraly have not taste in graphics 🙂 ) to get it the most professional appearance it can have!

Amazing feedbacks
What’s the best way to thank all supporters? Let’s show some of the best tweets I got from the web!

[Salesforce / Lightning] Trigger automatic Lightning Quick Action popup close

Few days ago my #AwesomeAdmin buddy Tom Blamire asked me:

“Do you know if I can automatically close a Quick Action popup window after triggering an action that does not require a UI (like downloading something from a Visualforce page)?”

The flow was simple as he asked me: click on a quick action on a standard layout page (with Lightning Experience enabled), trigger something (that can be a call to a Visualforce page or simply a backend elaboration from Apex) and close automatically the popup.

This is the solution: in this case the setTimeout() call was necessary because you need to get a bit “asynchronous”, but if you make an Apex controller callback, you don’t need it.

Thanks to Salesforce Lightning framework it is easy as it seem:

[Salesforce] Mason Frank Salesforce Salary Survey: you play the game!

It’s that time of year again. The annual Salesforce Salary Survey is now open!

Mason Frank, global Salesforce recruiters, have begun collecting responses for the their annual Salesforce salary survey!

The survey is formed through collecting insights from people working with Salesforce all over the world and forms to create a crucial resource for the Salesforce industry.

How much should you be earning in your job?

How do your benefits and perks compare?

Which factors can advance your earning potential?

What is your Salesforce working culture really like?

If you work with Salesforce, helps make the survey as accurate and representative as possible by contributing your answers.

Take the survey and you’ll also be entered for a chance to win either a Nintendo Switch or Apple Watch 2!

The survey should take you no longer than 15 minutes and will close on the 29th September 2017.

Mason Frank will be launching the results at Dreamforce 2017 and your own copy of the report will be sent directly to you.

Thank you for your input and good luck!

[Salesforce] ORGanizer 0.6.2 “Birthday” Release is live!

h1.chapter-title{
font-size:20pt;
}
div.post-content a{
color: blue;
font-weight: bold;
}

Happy Birthday to me!

To party in the best way my birthday, a new ORGanizer release is live!

If you haven’t, try out the ORGanizer for Saleforce Chrome Extension, you’ll never regret!

All new features has been requested by you all guys, the best ORGanusers of all time!

This is a beta and free extension, I encourage you to help me in my effort!

What’s inside?

Login as plugin

The Quick Console shows a the new Login As plugin: it helps you log in as another internal user.

To access it use the CTRL/CMD + SHIFT + 8 shortcut.

This plugin allows you to:

  • Show the User detail page (white button)
  • Login As in a new tab (green button)
  • Login As in incognito mode (red button): only works if extension has incognito mode enabled

SOSL queries

The Quick Query plugin now supports SOSL queries as well.

Each result is handled as a separate record set:

To ease the results view, each section displays the Sobject type.

Sobject fields ID clipper

The Sobject Fields plugin now is related to a new quick action, that you can recall with the CTRL/CMD + ALT + 4 shortcut, which copy the Salesforce Object ID that is present in the url in the following forms:

  • /[SF_ID] (typical Salesforce Classic sobject page)
  • /custom_url?id=[SF_ID] (id passed on the “id” url parameter)
  • #/sObject/[SF_ID] (typical Salesforce Lightning Experiece sobject page)

Change Salesforce API level

You can now select which API version the ORGanizer works with: this allow you to use the latest API level when dealing with sandboxes or preview ORGs.

To access this configuration go to ORGanizer Options page.

Change ORGanizer button position

You can now change the ORGanizer button position on the vertical / horizontal orientation.

For example this configuration:

Leads to:

While this other configuration:

Leads to:

New default ORG icon colors

New default colors has been added to the popup’s ORG icon selection color:

Remeber to share the love and to visit the Swag Store to help me keep the ORGanizer free!

[Salesforce / Einstein] Playing around with apples and Einstein Prediction APIs

The machines are not going to rule humanity…for now.

So don’t be afraid of AI in your daily job as Awesome Developer / Admin / Adminloper.

A new revolution has come in the CRM world and Salesforce leads it as usual.

Einstein is AI brought to our beloved CRM platform, in may ways: enriches your sales decisions, marketing strategies, smartifies your communities and your social behavior.

I know what you are thinking, how can a humble Salesforce developer empower Artificial Intelligence?

Again, afraid be not!

Salesforce conveys a set of APIs for image recognition or text analysis, so you can integrate the power of AI into your application, whether inside Salesforce or not.

What can you do with Einstein APIs?

At the time of writing, you can:

  • Classify images
  • Detect number, size and position of objects inside images
  • Classify sentiment in text
  • Categorize unstructured text into user-defined labels

Read the complete documentation at metamind.readme.io.

In this post I’ll cover an example of how to classify images using Einstein Vision.

Use Case

Can you guess a business use case for this API?

A particulas piece of my fridge just broke down and it is difficult to explain by words which part should be replaced.

Just take a picture of the part and submit to the Einstein Vision engine (properly trained): the backoffice user may now be able to tell the “replacemente department” which part should be sent to the customer.

Another example, my hoven is not working and I don’t remember the model: take a pic, send to Einstein engine, the system can guess the model and execute the proper actions.

In our example we’ll just try to classify apples, not a cool business use case but it effectively shows how the library works.

First configurations

First thing to do is registering for the free Einstein Vision tier.

Go to https://api.einstein.ai/signup, register with your Developer ORG edition (use the Salesforce flow) and then download and save the provided key in the einstein_platform.pem file.

Go to your ORG and create a new Static Resource for this certificate and call it Einstein_Platform: this will be used to generate a JWT OAuth token every time it is needed.

Now create a new Remote Site Setting adding the https://api.metamind.io endpoint (this is the Einstein Vision API endpoint).

Now you are ready to use the provided package.

Before starting you should install the following Apex packages into your ORG (they are open source Einstein Vision wrappers):

Download and install into your ORG the following code from REPO: it’s just 2 pages and 2 classes.

Before starting be sure to change your Einstein APi email address in the EinsteinVisionDemoController:

public static String getAccessToken(){
    String keyContents = [Select Body From StaticResource Where Name = 'Einstein_Platform' limit 1].Body.toString();
    keyContents = keyContents.replace('-----BEGIN RSA PRIVATE KEY-----', '');
    keyContents = keyContents.replace('-----END RSA PRIVATE KEY-----', '');
    keyContents = keyContents.replace('n', '');

    // Get a new token
    JWT jwt = new JWT('RS256');
    jwt.pkcs8 = keyContents;
    jwt.iss = 'developer.force.com';
    jwt.sub = '[email protected]';
    jwt.aud = 'https://api.metamind.io/v1/oauth2/token';
    jwt.exp = '3600';
    String access_token = JWTBearerFlow.getAccessToken('https://api.metamind.io/v1/oauth2/token', jwt);
    return access_token;    
}

Configure the Dataset

This repo has a configuration page (for model training) and a prediction page (see a live demo here ).

Let’s open the administration page named EinsteinVisionDemoAdmin.

In the Dataset URL input copy the following dataset URL: https://raw.githubusercontent.com/enreeco/sf-einstein-vision-prediction-demo/master/dataset/mele.zip.

This ZIP file contains 6 folders: each folder represent a kind of apple (the folder name is the corresponding name) and it contains a list of 40/50 images of that kind of apple (I’m not an expert of apples, so some pictures may not be correct!).

Now press the Create Model Async button: there are 2 kinds of API for this porporuse, one is sync (and accepts zip files of up to 5 MB) and the other one is async (and accepts size of more than 5 MB).

This means that in this example we’ll be using only the async API: the request is taken in charge:

DATASET:

{
  "updatedAt" : "2017-07-11T14:17:33.000Z",
  "totalLabels" : null,
  "totalExamples" : 0,
  "statusMsg" : "UPLOADING",
  "name" : "mele",
  "labelSummary" : {
    "labels" : [ ]
  },
  "id" : 1006545,
  "createdAt" : "2017-07-11T14:17:33.000Z",
  "available" : false
}

Now you can press the button labelled Get All Datasets and Models to watch the upload operation complete:

Datasets: 1

{
  "updatedAt" : "2017-07-11T14:17:37.000Z",
  "totalLabels" : 6,
  "totalExamples" : 266,
  "statusMsg" : "SUCCEEDED",
  "name" : "mele",
  "labelSummary" : {
    "labels" : [ {
      "numExamples" : 38,
      "name" : "red_delicious",
      "id" : 52011,
      "datasetId" : 1006545
    }, {
      "numExamples" : 44,
      "name" : "granny_smith",
      "id" : 52012,
      "datasetId" : 1006545
    }, {
      "numExamples" : 45,
      "name" : "royal_gala",
      "id" : 52013,
      "datasetId" : 1006545
    }, {
      "numExamples" : 42,
      "name" : "golden",
      "id" : 52014,
      "datasetId" : 1006545
    }, {
      "numExamples" : 53,
      "name" : "renetta",
      "id" : 52015,
      "datasetId" : 1006545
    }, {
      "numExamples" : 44,
      "name" : "fuji",
      "id" : 52016,
      "datasetId" : 1006545
    } ]
  },
  "id" : 1006545,
  "createdAt" : "2017-07-11T14:17:33.000Z",
  "available" : true
}

Now we can train our model by copying the dataset id into the Dataset ID input box and pressing the Train Model button: Einstein analyzes the images with its deep learning algorithm to allow prediction.

MODEL:

{
  "updatedAt" : "2017-07-11T14:21:05.000Z",
  "trainStats" : null,
  "trainParams" : null,
  "status" : "QUEUED",
  "queuePosition" : 1,
  "progress" : 0.0,
  "name" : "My Model 2017-07-11 00:00:00",
  "modelType" : "image",
  "modelId" : "UOHHRLYEH2NGBPRAS64JQLPCNI",
  "learningRate" : 0.01,
  "failureMsg" : null,
  "epochs" : 3,
  "datasetVersionId" : 0,
  "datasetId" : 1006545,
  "createdAt" : "2017-07-11T14:21:05.000Z"
}

The process is asynchronous and takes some time to complete (it depends on the parameters passed to the train API, see code).

Press the Get All Datasets and Models button to see the process ending:

Datasets: 1

{
  "updatedAt" : "2017-07-11T14:17:37.000Z",
  "totalLabels" : 6,
  "totalExamples" : 266,
  "statusMsg" : "SUCCEEDED",
  "name" : "mele",
  "labelSummary" : {
    "labels" : [ {
      "numExamples" : 38,
      "name" : "red_delicious",
      "id" : 52011,
      "datasetId" : 1006545
    }, {
      "numExamples" : 44,
      "name" : "granny_smith",
      "id" : 52012,
      "datasetId" : 1006545
    }, {
      "numExamples" : 45,
      "name" : "royal_gala",
      "id" : 52013,
      "datasetId" : 1006545
    }, {
      "numExamples" : 42,
      "name" : "golden",
      "id" : 52014,
      "datasetId" : 1006545
    }, {
      "numExamples" : 53,
      "name" : "renetta",
      "id" : 52015,
      "datasetId" : 1006545
    }, {
      "numExamples" : 44,
      "name" : "fuji",
      "id" : 52016,
      "datasetId" : 1006545
    } ]
  },
  "id" : 1006545,
  "createdAt" : "2017-07-11T14:17:33.000Z",
  "available" : true
}

{
  "updatedAt" : "2017-07-11T14:22:33.000Z",
  "trainStats" : null,
  "trainParams" : null,
  "status" : "SUCCEEDED",
  "queuePosition" : null,
  "progress" : 1.0,
  "name" : "My Model 2017-07-11 00:00:00",
  "modelType" : "image",
  "modelId" : "UOHHRLYEH2NGBPRAS64JQLPCNI",
  "learningRate" : null,
  "failureMsg" : null,
  "epochs" : null,
  "datasetVersionId" : 3796,
  "datasetId" : 1006545,
  "createdAt" : "2017-07-11T14:21:05.000Z"
}

We are almost ready!

Predict!

The only thing you have to do is to open the EinsteinVisionDemo demo passing the above Model Id (e.g. /apex/EinsteinVisionDemo?model=UOHHRLYEH2NGBPRAS64JQLPCNI):

The data set used is not the best dataset out there, it’s been created with the help of Google and a little of common sense, also the number of images for folder is only 40/50, this means the algorithm does not have enough data to get the job done…but actually it does its job!

May the Force.com be with you!” [cit. Yodeinstein]

[Salesforce] Summer17 Awesome Features Selection

.summer17 .title{
font-size:16pt;
}
.summer17 a{
color:red;
}
.summer17 img{
max-width: 400px;
}

Salesforce Summer ’17 release notes have been online for weeks and now it’s my turn to show you my favourite ones.

I’ve been busy recently with my work but also for our first joint Milano & Cagliari Salesforce DUG and for the Milano Essentials 2017.

I presented a huge deck for Summer 17 at our first meetup: this deck is only a selection of the gigantic official release notes.

In this post I’ll highlight an even smaller selection of the amazing features we find in the next release of the platform we all love.

The release is centered on Lightning Experience and we can see all the efforts Salesorce is putting to make LEX becoming fully compliant (and better for sure) to Classic UI.

Restyled Lightning Experience Migration Assistant (Classic)

The first improvement is related to the new and restyled Migration Assistant:

The assistant is meant to help you gradually migrate to LEX highlighting:

  • Problems related to components that may not work in LEX (e.g. custom buttons, links, …)
  • A list of profiles that are more or less ready to switch to LEX
  • An extensive check list on the actions to be completed to enable LEX
  • A component to enable users to LEX on the fly

Users that cannot be switched don’t have the Lightning Experience User permission:

Once you are 100% sure that certain users cannot switch to Classi anymore, change their profiles or apply a permission set with the following permission:

Keyboard Shortcuts (LEX)

Press Ctrl + / or Cmd + / to show a popup with the most useful shortcuts for LEX or the Lightning Cloud Console:

LEX app

LEX Cloud Console

Simplified Favorites List (LEX)

The Favorites list has been improved and easily accessible on the global actions section of the main app:

External Search Engines with Federated Search (GA)

A new type of External Data Source has been added, allowing to use the Federated Search protocol: basically you can search from Salesforce Global Search into an external service.

The configuration is easy:

Streamlined Handling of Potential Duplicates (LEX)

Duplicate checking is enhanced in LEX.

Conigure your Matching Rule:

Activate the Duplicate Rule deciding whether record creation must be blocked or display only a warning upon duplicate found:

And this is the result:

Not Blocking:

Blocking:

If the rule matches to many record on current dataset (more than 100) the rule is not activated:

Person Accounts Show All Cases in Related Lists (LEX)

If a Case is related to a Person Account by AccountId or ContactId fields, then it is shown in the “Cases” related list on the Account.

Compact Case Feed (LEX)

Feeds can be filtered by type, nodes are closed by default but you can expande all nodes:

Create, Edit, Delete Case Comments (LEX)

Create your Case Comments directly from the publisher using a Quick Action.

View, Edit and Delete them from the Case Comments related list.

Partner Central Community Template

It’s been designed with PRM in mind.

  • Overview of entire partner life cycle
  • Partner recruitment, onboarding, channel sales, channel marketing in one place
  • Automate lead ditribution
  • Configure quick actions to get partners access to company’s channel sales pipeline
  • Share sales data in a central repository
    Integrates with Service Cloud features (partners can open cases)
  • Customize global search
  • Like other Lightning communities:
    • Build custom pages and use custom branding
    • Expose wathever CRM objects suites to your needs
    • Customize content on partner geo-location

Communities Workspaces

Enable Communities Workspace (from

Setup > Communities Settings

) to have a better place for managing your communities.

Connect Your Content Management System (CMS) to Your Community (Beta)

CMS Connect lets you bring your AEM content, such as headers, footers, and banners, into your community.

Dynamically render your components, CSS, and JavaScript on community pages for consistent branding, authentication, and ease of maintenance.

CMS Connect is available in communities that are based on Customer Service (Napili), Partner Central, and any Lightning Bolt solutions.

When creating a new CMS connection set the base CMS server url and a root path to configure language and components to access the
proper CMS artifacts:

Define the language you’ll be using on your site:

Define up to 10 CSS and 10 JS file per CMS connection:

By defining multiple CMS connections, define the load order (css and script files):

From the Community Builder you can now set the header and footer:

You can even import specific CMS components:

Communities fully supported by Change Sets

Change sets are now available for Lightning communities and Salesforce Tabs and Visualforce communities.

Create, customize, and test your community in your sandbox environment and then migrate the community to production when testing is complete.

Communities are located under the Network component type.

Keep in mind that:

  • you can only make updates with change sets, create the community in the target ORG first
  • When you deploy an inbound change set, it completely overwrites the community in the destination org (e.g. deletes pages)
  • Navigation Menu items are supported. However, for menu items that link to objects, list views are reset to the default list view. Also, custom list views for standard objects aren’t included as dependency
  • Community migration is also supported via the Metadata API

Analyze and Improve Community Performance (Dev Prev)

A new awesome Chrome Extension has been delivered to analyze Communities preformances, the Salesforce Community Page Optimizer.

  • Overall score against major Lightning best practices
  • Waterfall of network requests
  • Timelines gives a profile of each component’s rendering life
  • Memory Usage
  • Components displays the life cycle of each component, to target potential leaks or unexpected rendering behavior
  • Cost tab displays the amount of time each component was busy processing: the lower the better
  • List of all actions performed on the page, along with their timing information
Improve Community Performance with Browser Caching

f you use many components in your Lightning community, improve community performance with browser caching.

Performance is about the same for the first page load, but subsequent page loads are faster.

The cache is encrypted and secure.

Share Public Links to Your Files (LEX)

Create public links sharable outside the Community:

Chatter Rich Publisher Apps for Communities (Pilot)

Use Chatter Rich Publisher Apps to integrate your custom apps into the Chatter publisher and to view the app’s payload in a feed.

Enjoy More Room for Files

Attachments and Documents should be migrated to Salesforce Files in LEX.

To increase adoption, new limits have been pushed.

Previously, the maximum number of files per org was 10 million.

We’ve tripled this limit, raising it to 30 million.

The number of daily content versions (files that you can add or modify in a 24-hour period) has increased from 36,000 to 200,000.

The delivery bandwidth limit has doubled from 10 GB to 20 GB.

Open More Tabs from Setup with Right-Click (LEX)

Simple but usefull enhancements for Developers and admins: setup links can now be opened with right click.

Find Your Way to Object Manager More Quickly (LEX)

The Object Manager tab lets you access quick actions, recent list views, and recent items. It also gives you a shortcut to create a new object

Object setup pages have been enhanced as well: object details always visible, scrolling details page, quick find search.

Block Execution of JavaScript in the HYPERLINK Function (Critical Update)

You cannot execute JS on HYPERLINK function on formula fields anymore.

HYPERLINK("javascript:window.location.reload()","TEXT")

  • Custom button or link to execute onClick JavaScript.
    • See Custom Buttons or Links (Classic)
  • Lightning Experience Quick Action button.
    • Create JavaScript in a Lightning Experience component executed through a Quick Action button (LEX)
  • Custom Visualforce page with an Apex controller to redirect to the correct URL.
    • Take this approach if you can execute client-side conditional logic to redirect the user to where you want. Create an empty Visualforce page and an Apex controller.
      Pass the required values from the link to the controller. Then execute the logic to determine the URL in the controller method, to perform the redirect

Embed your Flows in Lightning Pages (GA)

There is a brand new (and GA) flow components on your Lightning App Builder:

Dynamically Update Flow Screen Fields (Pilot)

Turn your flows into guided UIs that respond to users’ inputs and selections: display fields based on defined conditions.

This lower the number of flow steps needed to implement your scripts.

New Time Field Type (Pilot)

The Time type tracks time or indicates date-independent time.

You can use it to indicate business hours, preferred contact times, repeated event times, …

The Time type is essentially a timestamp without the date included.

The Time type uses a 24-hour notation.

You can display time in HH:MM, for example, 14:40
Time can include milliseconds (HH:MM:SS.MS): e.g. 14:40:50.617.

Time values are not localized or associated with a time zone, e.g. if you enter 15:00, for 3 pm, all users see the same value.

Define Default Values at the Field Level for Picklists

Define a default formula to define a default value based on the context: if the formula returns a blank value, that the value default is used.

SAML Single Logout (SLO) Is Available (Beta)

If enabled, logging out of your org logs you out of all connected apps (where Salesforce is the Identity Provider and the connected apps are Service Providers).

Balance security and usability when determining whether to use it. Logging the user out of all connected apps improves security, but not necessarily usability.

Override Standard Actions with Lightning Components

Override View, New, Edit, and Tab object actions using Lightning components:

Overrides that use Lightning components don’t affect Salesforce Classic.

If you override a standard action with a Visualforce page, it overrides the action in Salesforce Classic, Lightning Experience, and Salesforce1.

If you override a standard action with a Lightning component, it overrides the action in Lightning Experience and Salesforce1, but the standard Salesforce page is used in Salesforce Classic.

A Lightning record page for an object takes precedence over an override of the object’s View action.

That is, if you override the View action for an object, and you also create and assign a Lightning record page for the object, the Lightning record page is used. The override has no effect. This is true whether the override uses a Lightning component or a Visualforce page

force:hasRecordId

Enable the component to be assigned the ID of the current record and adds the component’s attribute recordId.

force:hasSObjectName

Enable the component to be assigned the API name of current record’s sObject type and adds the component’s attribute sObjectName.

Lightning Data Service (Beta)

Use Lightning Data Service to load, create, edit, or delete a record in your component, without using Apex code.

  • Lightning Data Service handles sharing rules and field-level security for you.
  • Lightning Data Service also improves performance and user-interface consistency
    Use the new force:recordData component (force:recordPreview deprecated)
  • Target record complies with the UI API
  • targetFields shows a simplified version of the object and updates when the Lightning Data Service detects a record change
    e.g. v.targetFields.name is equivalent
    to v.targetRecord.fields.Name.value
Find Component Markup Errors Faster with Improved Error Messages

Display more details for Lightning component errors:

It’s now easier for your users to report errors they encounter, and for you to find and fix those errors.

This change affects all users, and doesn’t depend on debug mode being enabled.

The framework logs a browser console warning if your component has a JavaScript function (client-side action) with the same name as an Apex method (server-side action).

The warning is logged only in debug mode and can help in troubleshooting an otherwise hard-to-debug issue.

WARNING: Component 'c:myComponent' has server and client action name conflicts: handleMethod
Use the aura:valueRender Event Instead of a Custom Renderer

When a component is rendered or rerendered, the aura:valueRender event, also known as the render event, is fired.

Handle this event to perform post-processing on the DOM or react to component rendering or rerendering.

The event is preferred and easier to use than the alternative of creating a custom renderer file.

<aura:handler name="render" value="{!this}" action="{!c.onRender}" />
Streamlined Validity Checks for Components

  • If a component is invalid, cmp.get() returns null.

    Previously, the framework returned an InvalidComponent error.

  • If you call cmp.set() on an invalid component, nothing happens and no error occurs.
  • The cmp.isValid() call returns false for an invalid component.

    You don’t need a cmp.isValid() check in the callback in a client-side controller when you reference the component associated with the client-side controller. The framework automatically checks that the component is valid.

    Similarly, you don’t need a cmp.isValid() check during event handling or in a framework lifecycle hook, such as the init event. If you reference a component in asynchronous code, such as setTimeout() or setInterval(), or when you use Promises, a cmp.isValid() call checks that the component is still valid before processing the results of the asynchronous request.

    In many scenarios, the cmp.isValid() call isn’t necessary because a null check on a value retrieved from cmp.get() is sufficient.

    The main reason to call cmp.isValid() is if you’re making multiple calls against the component and you want to avoid a null check for each result.

Use Advanced PDF to Render Visualforce Pages as PDF Files (Pilot)

Advanced PDF renders Visualforce pages as PDF files with broader support for modern HTML standards, such as CSS3, JavaScript, and HTML5.

This change applies to both Lightning Experience and Salesforce Classic.

To use Advanced PDF, set renderAs=”advanced_pdf” in the tag of a Visualforce page with API version 40.0 or later.

Advanced PDF pages time out after rendering for 2 minutes, which includes asynchronous processing time.

Because Advanced PDF is built on Chromium, it’s easy to preview your Visualforce pages in Google Chrome. To preview a page, from Chrome, select File > Print.

Access Visualforce Page Metrics Using the SOAP API

Make a SOQL query in Workbench to get information from the VisualforceAccessMetrics object.

SELECT Id, ApexPageId, DailyPageViewCount, MetricsDate From VisualforceAccessMetrics

Each VisualforceAccessMetrics object tracks the daily page view count in the DailyPageViewCount field.

The date the metrics were collected is specified in MetricsDate, and the ID of the tracked Visualforce page is specified in ApexPageId.

Page views are tallied the day after the page is viewed, and each VisualforceAccessMetrics object is removed after 90 days.

Roll Back Changes in Your Org When Remote JavaScript Methods Throw Exceptions

When a JavaScript method in an Apex class calling a remote action throws an exception, the action isn’t completed.

Previously, when a method threw an exception, the action was completed.

For example, when you created an Apex class that used a remote action to add an account to your org and that method threw an exception, the account was added. Now, the account isn’t added.

With this enhancement, JavaScript remoting methods that throw exceptions no longer cause changes in your org.

Retrieve and Deploy Metadata in Apex

Access to Metadata in Apex with the Metadata Namespace.

Metadata is used for org settings that admins control, or configuration information applied by installed apps and packages.

Previously, accessing metadata required using the Metadata API, but you can now use classes in the Metadata namespace to access metadata components from Apex code.

Metadata access in Apex is currently limited to custom metadata records and page layouts. You can retrieve, create, or update custom metadata, but you cannot delete metadata through Apex.

Details on the features here.

Extended Deadline for TLS 1.0 Disablement in Communities

On July 22, 2017, Salesforce is disabling support for TLS 1.0 for all ORGs in production.

To give admins more time to prepare community users, the TLS 1.0 disablement deadline for Salesforce Communities has been extended to March 2018. The extended March 2018 deadline applies to both Lightning and Visualforce communities.

Partner portals, customer portals, and Force.com and Site.com sites are still subject to the July 2017 deadline.

All licensed and unlicensed community users (guest users) must upgrade to browsers that are compliant with TLS 1.1 or above.

Details on TLS1.0 retirement here.

Be prepared for the deactivation.

  • Add appropriate messaging to your communities to inform your users about TLS 1.0 disablement. Educate both licensed and guest users about browser requirements for TLS version compatibility.
  • Encourage users to check their browsers for compatibility with our test site. If their browser is compliant, the web site displays a “Test passed” message.
  • Ensure that the TLS 1.1 or above is enabled for your API integrations.
Critical Update Activation: LockerService in Communities

Critical update since Summer ’16, is enforced for all orgs in Summer ’17.

LockerService, a powerful security architecture for custom Lightning components, is enforced for all Lightning components created in Summer ’17 (API version 40.0) and later.

LockerService isn’t enforced for components with API version 39.0 and lower, which covers any component created before Summer ’17.

  • JavaScript ES5 Strict Mode Enforcement “use strict”
    • JavaScript strict mode makes code more robust and supportable, enforces errors if (e.g.):
      • You must declare variables with the var keyword
      • You must explicitly attach a variable to the window object to make the variable available outside a library
      • The libraries that your components use must also work in strict mode
  • DOM Access Containment
    • A component can only traverse the DOM and access elements created by a component in the same namespace. This behavior prevents the anti-pattern of reaching into DOM elements owned by components in another namespace
    • It’s an anti-pattern for any component to “reach into” another component, regardless of namespace. LockerService only prevents cross-namespace access. Your good judgment should prevent cross-component access within your own namespace as it makes components tightly coupled and more likely to break
  • Restrictions to Global References
    • LockerService applies restrictions to global references: window, element and document objects expose only a subset of their APIs, to guarantee DOM access containment and isolate components
    • Details here
  • Access to Supported JavaScript API Framework Methods Only
    • You can access published, supported JavaScript API framework methods only
    • Previously, unsupported methods were accessible, which exposed your code to the risk of breaking when unsupported methods were changed or removed

When a component is set to at least API version 40.0, which is the version for Summer ’17, LockerService is enabled.

LockerService is disabled for any component created before Summer ’17 because these components have an API version less than 40.0.

To disable LockerService for a component, set its API version to 39.0 or lower.

LockerService is enabled for a component or an application purely based on component version.
The containment hierarchy within an application or a component doesn’t factor into LockerService enforcement.

For consistency and ease of debugging, we recommend that you set the same API version for all components in your app, when possible.

[Salesforce / CloudConsole] How to get if a tab is the primary tab

This is a quick post for the future me that will be struggling with Cloud Console and tab handling.

I wanted to get it a tab is a primary tab, in order to decide whether to open a new page in a new primary tab or in a subtab.

The problem is that if you try to get the primary tab id of a primary tab with the

sforce.console.getEnclosingPrimaryTabId()

function and get the value with the

sforce.console.getEnclosingTabId()

(expecting the same value for primary tabs), we instead get different values, as if the primary tab is enclosed in a super primary tab.

To solve this problem, just get the page info details and check if the enclosing primary tab has the same URL of the enclosing tab, and that’s it:

function isPrimaryTab(callback){
  sforce.console.getEnclosingPrimaryTabId(function (result){
    currentPrimaryTabId = result.id;
    sforce.console.getEnclosingTabId(function (subtabResult){
        thisTabId = subtabResult.id;
        sforce.console.getPageInfo(currentPrimaryTabId, function(pageinfo1){
            sforce.console.getPageInfo(thisTabId, function(pageinfo2){
                return callback && callback(JSON.parse(pageinfo2.pageInfo).url === JSON.parse(pageinfo1.pageInfo).url);
            });
        });
    }); 
  });
});

isPrimaryTab(function(result){
   alert(((result)?'IT IS':'IT IS NOT') + ' A PRIMARY TAB!');
});

[Salesforce / Lightning] Simple Custom Modal Alert

Hello everybody!

This is an “easy peasy” post that comes from a recent two-weeks full immersion on Lightning Components task I got into at work: there will be more content from this activity and a Cagliari DG presentation as well.

For all the TL;DR guys (and again, I’m one of you!), here is the Github Repository.

The Alert Modal shows an alert modal through a custom event fired from your Lightning components:

var evt = $A.get("e.c:AlertEvt");
        evt.setParams({
            "show": true,                     //shos alert
            "mode": 'prompt',                 //alert mode: prompt, alert, toast
            "fixed": false,                   //fixed does not shows any "close" button
            "type": 'info',                   //type of alert: info, success, warning, error
            "message": 'Title Message',       //main title
            "details": 'Message Details. . .' //details message
        });
        evt.fire();

The event is caught up by the AlertCmp Lightning component that shows the request alert:

Besides the prompt mode, you can use the alert mode:

And a toast mode:

You can test the component in the provided Lightning app:

Page 15 of 26

Powered by WordPress & Theme by Anders Norén