Newer Version Available
Sample Custom Components for Lightning for Outlook (Beta)
Review samples of custom Lightning components that you can implement
in the Email Application Pane for Lightning for Outlook.
Here’s an example of a custom Lightning Component you can include in your email
application pane for Lightning for Outlook or Lightning for Gmail (Pilot). This
component leverages the context of the selected email or appointment.
1<aura:component implements="clients:availableForMailAppAppPage,clients:hasItemContext">
2
3<!--
4 Add these handlers to customize what happens when the attributes change
5 <aura:handler name="change" value="{!v.subject}" action="{!c.handleSubjectChange}" />
6 <aura:handler name="change" value="{!v.people}" action="{!c.handlePeopleChange}" />
7-->
8
9 <div id="content">
10 <h1><b>Email subject</b></h1>
11 <span id="subject">{!v.subject}</span>
12
13 <h1>To:</h1>
14 <aura:iteration items="{!v.people.to}" var="to">
15 {!to.name} - {!to.email} <br/>
16 </aura:iteration>
17
18 <h1>From:</h1>
19 {!v.people.from.name} - {!v.people.from.email}
20
21 <h1>CC:</h1>
22 <aura:iteration items="{!v.people.cc}" var="cc">
23 {!cc.name} - {!cc.email} <br/>
24 </aura:iteration>
25
26 <span class="greeting">{!v.greeting}</span>, {!v.subject}!
27 </div>
28</aura:component>In this example, the custom component displays account and opportunity information based
on the email recipients’ email addresses. The component calls a JavaScript controller
function, handlePeopleChange(), on initialization.
The JavaScript controller calls methods on an Apex server-side controller to query the
information and compute the accounts ages and oppotunities days until closing. The Apex
controller, JavaScript controller, and helper are listed next.
1<!--
2This component handles the email context on initialization.
3It retrieves accounts and opportunities based on the email addresses included
4in the email recipients list.
5It then calculates the account and opportunity ages based on when the accounts
6were created and when the opportunities will close.
7-->
8
9<aura:component
10 implements="clients:availableForMailAppAppPage,clients:hasItemContext"
11 controller="ComponentController">
12
13 <aura:handler name="init" value="{!this}" action="{!c.handlePeopleChange}" />
14 <aura:attribute name="accounts" type="List" />
15 <aura:attribute name="opportunities" type="List" />
16 <aura:iteration items="{!v.accounts}" var="acc">
17 {!acc.name} => {!acc.age}
18 </aura:iteration>
19 <aura:iteration items="{!v.opportunities}" var="opp">
20 {!opp.name} => {!opp.closesIn} Days till closing
21 </aura:iteration>
22
23</aura:component>1/*
2On the server side, the Apex controller includes
3Aura-enabled methods that accept a list of emails as parameters.
4*/
5
6public class ComponentController {
7 /*
8 This method searches for Contacts with matching emails in the email list,
9 and includes Account information in the fields. Then, it filters the
10 information to return a list of objects to use on the client side.
11 */
12 @AuraEnabled
13 public static List<Map<String, Object>> findAccountAges(List<String> emails) {
14 List<Map<String, Object>> ret = new List<Map<String, Object>>();
15 List<Contact> contacts = [SELECT Name, Account.Name, Account.CreatedDate
16 FROM Contact
17 WHERE Contact.Email IN :emails];
18 for (Contact c: contacts) {
19 Map<String, Object> item = new Map<String, Object>();
20 item.put('name', c.Account.Name);
21 item.put('age',
22 Date.valueOf(c.Account.CreatedDate).daysBetween(
23 System.Date.today()));
24 ret.add(item);
25 }
26 return ret;
27}
28
29 /*
30 This method searches for OpportunityContactRoles with matching emails
31 in the email list.
32 Then, it calculates the number of days until closing to return a list
33 of objects to use on the client side.
34 */
35 @AuraEnabled
36 public static List<Map<String, Object>> findOpportunityCloseDateTime(List<String> emails) {
37 List<Map<String, Object>> ret = new List<Map<String, Object>>();
38 List<OpportunityContactRole> contacts =
39 [SELECT Opportunity.Name, Opportunity.CloseDate
40 FROM OpportunityContactRole
41 WHERE isPrimary=true AND Contact.Email IN :emails];
42 for (OpportunityContactRole c: contacts) {
43 Map<String, Object> item = new Map<String, Object>();
44 item.put('name', c.Opportunity.Name);
45 item.put('closesIn',
46 System.Date.today().daysBetween(
47 Date.valueOf(c.Opportunity.CloseDate)));
48 ret.add(item);
49 }
50 return ret;
51 }
52}1({
2/*
3This JavaScript controller is called on component initialization and relies
4on the helper functionality to build a list of email addresses from the
5available people. It then makes a caller to the server to run the actions to
6display information.
7Once the server returns the values, it sets the appropriate values to display
8on the client side.
9*/
10 handlePeopleChange: function(component, event, helper){
11 var people = component.get("v.people");
12 var peopleEmails = helper.filterEmails(people);
13 var action = component.get("c.findOpportunityCloseDateTime");
14 action.setParam("emails", peopleEmails);
15
16 action.setCallback(this, function(response){
17 var state = response.getState();
18 if(component.isValid() && state === "SUCCESS"){
19 component.set("v.opportunities", response.getReturnValue());
20 } else{
21 component.set("v.opportunities",[]);
22 }
23});
24 $A.enqueueAction(action);
25 var action = component.get("c.findAccountAges");
26 action.setParam("emails", peopleEmails);
27
28 action.setCallback(this, function(response){
29 var state = response.getState();
30 if(component.isValid() && state === "SUCCESS"){
31 component.set("v.accounts", response.getReturnValue());
32 } else{
33 component.set("v.accounts",[]);
34 }
35});
36$A.enqueueAction(action);
37}
38})1({
2 /*
3 This helper function filters emails from objects.
4 */
5 filterEmails : function(people){
6 return this.getEmailsFromList(people.to).concat(
7 this.getEmailsFromList(people.cc));
8 },
9
10 getEmailsFromList : function(list){
11 var ret = [];
12 for (var i in list) {
13 return push(list[i].email);
14 }
15 return ret;
16 }
17})