SFDX and Lightning Development
# create project lexbook_prj1
$ sfdx force:project:create -n lexbook_prj1
target dir = /Users/mchinnappan/LEX-book/dx
create lexbook_prj1/sfdx-project.json
create lexbook_prj1/README.md
create lexbook_prj1/.forceignore
create lexbook_prj1/config/project-scratch-def.json
# scrath org definition
$ cat lexbook_prj1/config/project-scratch-def.json
{
"orgName": "mchinnappan Company",
"edition": "Developer",
"orgPreferences" : {
"enabled": ["S1DesktopEnabled"]
}
}
## view the project folder contents
~/lex-book/dx/lexbook_prj1:
$ tree
.
├── README.md
├── config
│ └── project-scratch-def.json
├── force-app
│ └── main
│ └── default
│ └── aura
└── sfdx-project.json
5 directories, 3 files
# create a scratch org for our dev
$ sfdx force:org:create -s -f lexbook_prj1/config/project-scratch-def.json -a lexbook_prj1_org1 --setdefaultusername
## Web Login into DevHub101
$ sfdx force:auth:web:login -a DevHub101
# list the org using sfdx force:org:list
$ sfdx force:org:list
=== Orgs
ALIAS USERNAME ORG ID CONNECTED STATUS
─── ───────── ──────────────────────────────────── ────────────────── ─────────────────
(D) DevHub101 mohan.chinnappan.dh101@gmail.com 00Df4000003l2kBEAQ Connected
ALIAS SCRATCH ORG NAME USERNAME ORG ID EXPIRATION DATE
─── ──────────────── ─────────────────── ───────────────────────────── ────────────────── ───────────────
(U) lexbook_prj1_org1 mchinnappan Company test-chpgw6fd8a2j@example.com 00D3C000000LHDqUAO 2018-06-05
## open the just created Scratch org
$ sfdx force:org:open
Access org 00D3C000000LHDqUAO as user test-chpgw6fd8a2j@example.com with the following URL: https://connect-java-2931-dev-ed.cs60.my.salesforce.com/secur/frontdoor.jsp?sid=00D3C000000LHDq!AR8AQITg3Xqf3p2y_Go3I5yJcFZ4inIFJe4yPJbDAaPMfttnQQ2BJZ1VFTnG05kIkcpnHGqjielydZavaq7QXE.ipd3huGDI
## create a lightning component
$ sfdx force:lightning:component:create --help
Usage: sfdx force:lightning:component:create -n <string> [-t <string>] [-d <string>] [-a <string>] [--json] [--loglevel <string>]
create a Lightning component
Flags:
-a, --apiversion APIVERSION API version number (42.0*,41.0)
-n, --componentname COMPONENTNAME (required) name of the generated Lightning
component
-d, --outputdir OUTPUTDIR folder for saving the created files
-t, --template TEMPLATE template to use for file creation
(DefaultLightningCmp*)
--json JSON output
--loglevel LOGLEVEL logging level for this command invocation
(error*,trace,debug,info,warn,fatal)
If not supplied, the apiversion, template, and outputdir use default values.
The outputdir can be an absolute path or relative to the current working directory.
Examples:
$ sfdx force:lightning:component:create -n mycomponent
$ sfdx force:lightning:component:create -n mycomponent -d lightning
## Create Ligtning Component 'Training'
```bash
$ sfdx force:lightning:component:create -n Training -d force-app/main/default/aura
target dir = /Users/mchinnappan/LEX-book/dx/lexbook_prj1/force-app/main/default/aura
create Training/Training.cmp
create Training/Training.cmp-meta.xml
create Training/TrainingController.js
create Training/TrainingHelper.js
create Training/Training.css
create Training/TrainingRenderer.js
create Training/Training.svg
create Training/Training.auradoc
create Training/Training.design
Load the project in VS Code
$ code .
## Update the Training Component in the VS Code
```xml
<aura:component>
<lightning:card title="Training">
<p>Training Component</p>
</lightning:card>
</aura:component>
source push
$ sfdx force:source:push -u lexbook_prj1_org1
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
───── ────────────────────────────── ──────────────────── ──────────────────────────────────────────────────────────
Add Training/Training.auradoc AuraDefinitionBundle force-app/main/default/aura/Training/Training.auradoc
Add Training/Training.cmp AuraDefinitionBundle force-app/main/default/aura/Training/Training.cmp
Add Training/Training.cmp AuraDefinitionBundle force-app/main/default/aura/Training/Training.cmp-meta.xml
Add Training/Training.css AuraDefinitionBundle force-app/main/default/aura/Training/Training.css
Add Training/Training.design AuraDefinitionBundle force-app/main/default/aura/Training/Training.design
Add Training/Training.svg AuraDefinitionBundle force-app/main/default/aura/Training/Training.svg
Add Training/TrainingController.js AuraDefinitionBundle force-app/main/default/aura/Training/TrainingController.js
Add Training/TrainingHelper.js AuraDefinitionBundle force-app/main/default/aura/Training/TrainingHelper.js
Add Training/TrainingRenderer.js AuraDefinitionBundle force-app/main/default/aura/Training/TrainingRenderer.js
Add implements for Training Component in the VS Code
<aura:component implements="flexipage:availableForAllPageTypes">
<lightning:card title="Training">
<p>Training Component</p>
</lightning:card>
</aura:component>
source push again
$ sfdx force:source:push -u lexbook_prj1_org1
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
─────── ───────────────────── ──────────────────── ─────────────────────────────────────────────────
Changed Training/Training.cmp AuraDefinitionBundle force-app/main/default/aura/Training/Training.cmp
app:create -- create lightning app to test Training Compoment
$ sfdx force:lightning:app:create -h
Usage: sfdx force:lightning:app:create -n <string> [-t <string>] [-d <string>] [-a <string>] [--json] [--loglevel <string>]
create a Lightning app
Flags:
-a, --apiversion APIVERSION API version number (42.0*,41.0)
-n, --appname APPNAME (required) name of the generated Lightning app
-d, --outputdir OUTPUTDIR folder for saving the created files
-t, --template TEMPLATE template to use for file creation
(DefaultLightningApp*)
--json JSON output
--loglevel LOGLEVEL logging level for this command invocation
(error*,trace,debug,info,warn,fatal)
If not supplied, the apiversion, template, and outputdir use default values.
The outputdir can be an absolute path or relative to the current working directory.
Examples:
$ sfdx force:lightning:app:create -n myapp
$ sfdx force:lightning:app:create -n myapp -d lightning
## create TestApp now
$ sfdx force:lightning:app:create -n TestApp -d force-app/main/default/aura
target dir = /Users/mchinnappan/LEX-book/dx/lexbook_prj1/force-app/main/default/aura
create TestApp/TestApp.app
create TestApp/TestApp.app-meta.xml
create TestApp/TestAppController.js
create TestApp/TestAppHelper.js
create TestApp/TestApp.css
create TestApp/TestAppRenderer.js
create TestApp/TestApp.svg
create TestApp/TestApp.auradoc
Update TestApp.app to Training Component
<aura:application>
<c:Training />
</aura:application>
source:push
sfdx force:source:push -u lexbook_prj1_org1
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
───── ──────────────────────────── ──────────────────── ────────────────────────────────────────────────────────
Add TestApp/TestApp.app AuraDefinitionBundle force-app/main/default/aura/TestApp/TestApp.app
Add TestApp/TestApp.app AuraDefinitionBundle force-app/main/default/aura/TestApp/TestApp.app-meta.xml
Add TestApp/TestApp.auradoc AuraDefinitionBundle force-app/main/default/aura/TestApp/TestApp.auradoc
Add TestApp/TestApp.css AuraDefinitionBundle force-app/main/default/aura/TestApp/TestApp.css
Add TestApp/TestApp.svg AuraDefinitionBundle force-app/main/default/aura/TestApp/TestApp.svg
Add TestApp/TestAppController.js AuraDefinitionBundle force-app/main/default/aura/TestApp/TestAppController.js
Add TestApp/TestAppHelper.js AuraDefinitionBundle force-app/main/default/aura/TestApp/TestAppHelper.js
Add TestApp/TestAppRenderer.js AuraDefinitionBundle force-app/main/default/aura/TestApp/TestAppRenderer.js
Open the App
$ sfdx force:org:open -u lexbook_prj1_org1 -p c/TestApp.app
Access org 00D3C000000LHDqUAO as user test-chpgw6fd8a2j@example.com with the following URL: https://connect-java-2931-dev-ed.cs60.my.salesforce.com/secur/frontdoor.jsp?sid=00D3C000000LHDq!AR8AQGL1sv0_mn2EY3zjnANRI7VBjsgDPiwc0G8DzeaVARLTFrexA0Ec.7HGNolC3aOBoOdZWSfDdTlbPkpTXBTHJs75LUM9&retURL=c%2FTestApp.app
~/lex-book/dx/lexbook_prj1
Demo Time
adding SLDS style to the our test app
<aura:application extends="force:slds">
<c:Training />
</aura:application>
source push
$ sfdx force:source:push -u lexbook_prj1_org1
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
─────── ─────────────────── ──────────────────── ───────────────────────────────────────────────
Changed TestApp/TestApp.app AuraDefinitionBundle force-app/main/default/aura/TestApp/TestApp.app
Create Student Custom Object
Source:pull from the org to our project folder
# this includes our Lightning app and Custom object Student__c, custom tab, Profile for Student__c
$ sfdx force:source:pull -u lexbook_prj1_org1
=== Pulled Source
STATE FULL NAME TYPE PROJECT PATH
───── ───────────────────────── ──────────── ──────────────────────────────────────────────────────────────────────────
Add Student__c CustomObject force-app/main/default/objects/Student__c/Student__c.object-meta.xml
Add Student__c-Student Layout Layout force-app/main/default/layouts/Student__c-Student Layout.layout-meta.xml
Add Lex_Book_App_1 FlexiPage force-app/main/default/flexipages/Lex_Book_App_1.flexipage-meta.xml
Add Lex_Book_App_1 CustomTab force-app/main/default/tabs/Lex_Book_App_1.tab-meta.xml
Add Student__c CustomTab force-app/main/default/tabs/Student__c.tab-meta.xml
Add Custom: Sales Profile Profile force-app/main/default/profiles/Custom: Sales Profile.profile-meta.xml
Add Custom: Marketing Profile Profile force-app/main/default/profiles/Custom: Marketing Profile.profile-meta.xml
Add Custom: Support Profile Profile force-app/main/default/profiles/Custom: Support Profile.profile-meta.xml
Add Admin Profile force-app/main/default/profiles/Admin.profile-meta.xml
How to get the Student record we created in UI in SFDX
$ sfdx force:data:record:get -h
Usage: sfdx force:data:record:get -s <string> [-i <id>] [-w <string>] [-t] [--perfloglevel <string>] [-u <string>] [--json] [--loglevel <string>]
view a record
Flags:
-i, --sobjectid SOBJECTID the ID of the record you’re retrieving
-s, --sobjecttype SOBJECTTYPE (required) the type of the record you’re
retrieving
-u, --targetusername TARGETUSERNAME username or alias for the target org;
overrides default target org
-t, --usetoolingapi retrieve the record with Tooling API
-w, --where WHERE a list of <fieldName>=<value> pairs to
search for
--json format output as json
--loglevel LOGLEVEL logging level for this command invocation
(error*,trace,debug,info,warn,fatal)
--perfloglevel PERFLOGLEVEL get API performance data.
(basic*,detailed)
Specify an sObject type and either an ID or a list of <fieldName>=<value> pairs.
The format of a field-value pair is <fieldName>=<value>.
Enclose all field-value pairs in one set of double quotation marks, delimited by spaces.
Enclose values that contain spaces in single quotes.
To get data on API performance metrics, specify both --perfloglevel and --json.
Examples:
$ sfdx force:data:record:get -s Account -i 001D000000Kv3dl
$ sfdx force:data:record:get -s Account -w "Name=Acme"
$ sfdx force:data:record:get -s Account -w "Name='Universal Containers'"
$ sfdx force:data:record:get -s Account -w "Name='Universal Containers' Phone='(123) 456-7890'"
$ sfdx force:data:record:get -t -s TraceFlag -i 7tf170000009cUBAAY --perfloglevel "basic" --json
## Let us get it
$ sfdx force:data:record:get -s Student__c -u lexbook_prj1_org1 -i a003C0000010ogjQAA
attributes:
type: "Student__c"
url: "/services/data/v42.0/sobjects/Student__c/a003C0000010ogjQAA"
Id: "a003C0000010ogjQAA"
OwnerId: "0053C000000rMsrQAE"
IsDeleted: null
Name: "Mohan Chinnappan"
CreatedDate: "2018-05-29T20:17:06.000+0000"
CreatedById: "0053C000000rMsrQAE"
LastModifiedDate: "2018-05-29T20:17:06.000+0000"
LastModifiedById: "0053C000000rMsrQAE"
SystemModstamp: "2018-05-29T20:17:06.000+0000"
LastViewedDate: "2018-05-29T20:46:57.000+0000"
LastReferencedDate: "2018-05-29T20:46:57.000+0000"
Add Report Type and Report
Pull from the Org to Project Folder
$ sfdx force:source:pull -u lexbook_prj1_org1
=== Pulled Source
STATE FULL NAME TYPE PROJECT PATH
─────── ───────────────────────────── ────────────── ──────────────────────────────────────────────────────────────────────────────────
Add TrainingCat GlobalValueSet force-app/main/default/globalValueSets/TrainingCat.globalValueSet-meta.xml
Add Training__c CustomObject force-app/main/default/objects/Training__c/Training__c.object-meta.xml
Add Training__c.CompletionDate__c CustomField force-app/main/default/objects/Training__c/fields/CompletionDate__c.field-meta.xml
Add Training__c.Student__c CustomField force-app/main/default/objects/Training__c/fields/Student__c.field-meta.xml
Add Training__c.TrainingCat__c CustomField force-app/main/default/objects/Training__c/fields/TrainingCat__c.field-meta.xml
Add Training_Report ReportType force-app/main/default/reportTypes/Training_Report.reportType-meta.xml
Add Training_Reports ReportFolder force-app/main/default/reports/Training_Reports.reportFolder-meta.xml
Add Training_Reports ReportFolder force-app/main/default/reports/Training_Reports
Add Training__c-Training Layout Layout force-app/main/default/layouts/Training__c-Training Layout.layout-meta.xml
Changed Custom: Sales Profile Profile force-app/main/default/profiles/Custom: Sales Profile.profile-meta.xml
Changed Custom: Marketing Profile Profile force-app/main/default/profiles/Custom: Marketing Profile.profile-meta.xml
Changed Custom: Support Profile Profile force-app/main/default/profiles/Custom: Support Profile.profile-meta.xml
Changed Admin Profile force-app/main/default/profiles/Admin.profile-meta.xml
View this in IDE
Adding charts in Lightning Component
Create component MedalsByCountry
$ sfdx force:lightning:component:create -n MedalsByCountry -d force-app/main/default/aura
target dir = /Users/mchinnappan/LEX-book/dx/lexbook_prj1/force-app/main/default/aura
create MedalsByCountry/MedalsByCountry.cmp
create MedalsByCountry/MedalsByCountry.cmp-meta.xml
create MedalsByCountry/MedalsByCountryController.js
create MedalsByCountry/MedalsByCountryHelper.js
create MedalsByCountry/MedalsByCountry.css
create MedalsByCountry/MedalsByCountryRenderer.js
create MedalsByCountry/MedalsByCountry.svg
create MedalsByCountry/MedalsByCountry.auradoc
create MedalsByCountry/MedalsByCountry.design
# open the org
$ sfdx force:org:open -u lexbook_prj1_org1
Access org 00D3C000000LHDqUAO as user test-chpgw6fd8a2j@example.com with the following URL: https://connect-java-2931-dev-ed.cs60.my.salesforce.com/secur/frontdoor.jsp?sid=00D3C000000LHDq!AR8AQNUV7uq_Ux1HW7ZwzgfqXBYoQvEU1gjiO.xYdK82mo00pUoFug.0MPqb2HPF8YOXX07h9PWbqbDLRYVIfJsM_i9jqMU7
Create source pull the static resources
$ sfdx force:source:pull -u lexbook_prj1_org1
=== Pulled Source
STATE FULL NAME TYPE PROJECT PATH
─────── ────────────────── ────────────── ───────────────────────────────────────────────────────────────────────────
Add ChartJS23 StaticResource force-app/main/default/staticresources/ChartJS23.resource-meta.xml
Changed ChartJS23 StaticResource force-app/main/default/staticresources/ChartJS23.js
Add OlympicDataService StaticResource force-app/main/default/staticresources/OlympicDataService.resource-meta.xml
Changed OlympicDataService StaticResource force-app/main/default/staticresources/OlympicDataService.js
Update Component and Controller
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global" >
<ltng:require scripts="{!join(',',
$Resource.ChartJS23,
$Resource.OlympicDataService)}"
afterScriptsLoaded="{!c.scriptsLoaded}" />
<aura:attribute name="title" type="String" default="Medal distribution by country"/>
<aura:attribute name="medalType" type="String" default="Gold"/>
<aura:handler event="c:ChartEvent" action="{!c.chartChange}"/>
<div>
<div class="slds-text-heading--medium">{!v.title}</div>
<canvas aura:id="chart" height="350"></canvas>
</div>
</aura:component>
({
scriptsLoaded : function(component, event, helper) {
var ctx = component.find("chart").getElement();
component.chart = new Chart(ctx,{
type: 'bar',
data: {
labels: [],
datasets: [
{
label: "",
data: [],
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
},
chartChange: function(component, event, helper) {
var colors = {
gold: "rgba(255,203,75,.7)",
silver: "rgba(143,134,132,.7)",
bronze: "rgba(153,119,61,.7)"
};
var filters = event.getParam("data");
if (!filters || !filters.year) {
return;
}
var medalType;
if (filters.medalType) {
medalType = filters.medalType;
component.set("v.medalType", medalType);
} else {
medalType = component.get("v.medalType");
}
var years = window.olympicDataService.getData();
years.forEach(function(year) {
if (year.year == filters.year) {
component.set("v.title", year.venue + " " + year.year + ", " + medalType + " Medals");
var labels = [];
var values = [];
year.countries.forEach(function(country) {
labels.push(country.country);
values.push(country[medalType.toLowerCase()]);
});
component.chart.data.labels = labels;
component.chart.data.datasets[0].label = medalType;
component.chart.data.datasets[0].data = values;
component.chart.data.datasets[0].backgroundColor = colors[medalType.toLowerCase()];
component.chart.update();
return;
}
})
}
})
MedalsTimeline Component
$ sfdx force:lightning:component:create -n MedalsTimeline -d force-app/main/default/aura
target dir = /Users/mchinnappan/LEX-book/dx/lexbook_prj1/force-app/main/default/aura
create MedalsTimeline/MedalsTimeline.cmp
create MedalsTimeline/MedalsTimeline.cmp-meta.xml
create MedalsTimeline/MedalsTimelineController.js
create MedalsTimeline/MedalsTimelineHelper.js
create MedalsTimeline/MedalsTimeline.css
create MedalsTimeline/MedalsTimelineRenderer.js
create MedalsTimeline/MedalsTimeline.svg
create MedalsTimeline/MedalsTimeline.auradoc
create MedalsTimeline/MedalsTimeline.design
<aura:component implements="flexipage:availableForAllPageTypes" access="global" >
<ltng:require scripts="{!join(',',
$Resource.ChartJS23,
$Resource.OlympicDataService)}"
afterScriptsLoaded="{!c.scriptsLoaded}" />
<aura:registerEvent name="chartEvent" type="c:ChartEvent"/>
<div>
<div class="slds-text-heading--medium">Medals Timeline</div>
<canvas aura:id="chart" height="380"></canvas>
</div>
</aura:component>
// MedalsTimelineController.js
({
scriptsLoaded : function(component, event, helper) {
var colors = [
'rgba(23, 48, 91, 1)',
'rgba(62, 159, 222, 1)',
'rgba(48, 165, 154, 1)',
'rgba(132, 220, 214, 1)',
'rgba(222, 159, 0, 1)',
'rgba(223, 205, 114, 1)'
];
var years = window.olympicDataService.getData();
var labels = [];
var datasets = [];
var countries = {};
years.forEach(function(year) {
labels.push(year.year);
year.countries.forEach(function(country) {
var total = country.gold + country.silver + country.bronze;
if (countries[country.country]) {
countries[country.country].push(total);
} else {
countries[country.country] = [total];
}
})
});
var i=0;
for (var key in countries) {
datasets.push({
label: key,
data: countries[key],
fill: false,
borderWidth: 1.5,
backgroundColor: colors[i++],
borderColor: colors[i],
pointBackgroundColor: "#FFFFFF",
pointBorderWidth: 4,
pointHoverRadius: 8,
pointRadius: 6,
pointHitRadius: 10,
});
}
var ctx = component.find("chart").getElement();
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: datasets
},
options: {
responsive: true,
maintainAspectRatio :false,
onClick: function(event) {
var elements = chart.getElementAtEvent(event);
// console.log("elements");
// console.log(elements);
if (elements.length === 1) {
var year = labels[elements[0]._index];
var country = datasets[elements[0]._datasetIndex].label;
var chartEvent = $A.get("e.c:ChartEvent");
chartEvent.setParams({
data: {year: year, country: country}
});
chartEvent.fire();
}
}
}
});
}
})
sfdx force:source:push -u lexbook_prj1_org1
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
───── ────────────────────────────────────────── ──────────────────── ──────────────────────────────────────────────────────────────────────
Add MedalsTimeline/MedalsTimeline.auradoc AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimeline.auradoc
Add MedalsTimeline/MedalsTimeline.cmp AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimeline.cmp
Add MedalsTimeline/MedalsTimeline.cmp AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimeline.cmp-meta.xml
Add MedalsTimeline/MedalsTimeline.css AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimeline.css
Add MedalsTimeline/MedalsTimeline.design AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimeline.design
Add MedalsTimeline/MedalsTimeline.svg AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimeline.svg
Add MedalsTimeline/MedalsTimelineController.js AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimelineController.js
Add MedalsTimeline/MedalsTimelineHelper.js AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimelineHelper.js
Add MedalsTimeline/MedalsTimelineRenderer.js AuraDefinitionBundle force-app/main/default/aura/MedalsTimeline/MedalsTimelineRenderer.js
ChartEvent
<aura:event type="APPLICATION" description="Event template" access="global">
<aura:attribute name="data" type="Object"/>
</aura:event>
MedalsByType component
$ sfdx force:lightning:component:create -n MedalsByType -d force-app/main/default/aura
target dir = /Users/mchinnappan/LEX-book/dx/lexbook_prj1/force-app/main/default/aura
create MedalsByType/MedalsByType.cmp
create MedalsByType/MedalsByType.cmp-meta.xml
create MedalsByType/MedalsByTypeController.js
create MedalsByType/MedalsByTypeHelper.js
create MedalsByType/MedalsByType.css
create MedalsByType/MedalsByTypeRenderer.js
create MedalsByType/MedalsByType.svg
create MedalsByType/MedalsByType.auradoc
create MedalsByType/MedalsByType.design
$ sfdx force:source:push -u lexbook_prj1_org1
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
───── ────────────────────────────────────── ──────────────────── ──────────────────────────────────────────────────────────────────
Add MedalsByType/MedalsByType.auradoc AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.auradoc
Add MedalsByType/MedalsByType.cmp AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.cmp
Add MedalsByType/MedalsByType.cmp AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.cmp-meta.xml
Add MedalsByType/MedalsByType.css AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.css
Add MedalsByType/MedalsByType.design AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.design
Add MedalsByType/MedalsByType.svg AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.svg
Add MedalsByType/MedalsByTypeController.js AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByTypeController.js
Add MedalsByType/MedalsByTypeHelper.js AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByTypeHelper.js
Add MedalsByType/MedalsByTypeRenderer.js AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByTypeRenderer.js
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global" >
<ltng:require scripts="{!join(',',
$Resource.ChartJS23,
$Resource.OlympicDataService)}"
afterScriptsLoaded="{!c.scriptsLoaded}" />
<aura:attribute name="year" type="String"/>
<aura:attribute name="country" type="String"/>
<aura:attribute name="title" type="String" default="Medal breakdown"/>
<aura:handler event="c:ChartEvent" action="{!c.chartChange}"/>
<div>
<div class="slds-text-heading--medium">{!v.title}</div>
<canvas aura:id="chart" height="280"></canvas>
</div>
</aura:component>
MedalsByType controller
// MedalsByTypeController.js
({
scriptsLoaded : function(component, event, helper) {
var data = {
labels: ["Gold", "Silver", "Bronze"],
datasets: [
{
data: [0, 0, 0],
backgroundColor: [
"rgba(255,203,75,.8)",
"rgba(143,134,132,.8)",
"rgba(153,119,61,.8)"
],
hoverBackgroundColor: [
"rgba(255,203,75,1)",
"rgba(143,134,132,1)",
"rgba(143,125,92,1)"
]
}
]
};
var ctx = component.find("chart").getElement();
component.chart = new Chart(ctx,{
type: 'doughnut',
data: data,
options: {
responsive: true,
maintainAspectRatio: false,
onClick: function(event) {
var elements = component.chart.getElementAtEvent(event);
if (elements.length === 1) {
var chartEvent = $A.get("e.c:ChartEvent");
chartEvent.setParams({
data: {
year: component.get("v.year"),
country: component.get("v.country"),
medalType: component.chart.data.labels[elements[0]._index]
}
});
chartEvent.fire();
}
}
}
});
},
chartChange: function(component, event, helper) {
var filters = event.getParam("data");
component.set("v.year", filters.year);
component.set("v.country", filters.country);
var years = window.olympicDataService.getData();
years.forEach(function(year) {
if (year.year == filters.year) {
year.countries.forEach(function(country) {
if (country.country == filters.country) {
component.set("v.title", year.venue + ' ' + year.year + ", " + filters.country + " (" + (country.gold + country.silver + country.bronze) + " medals)");
var medals = [country.gold, country.silver, country.bronze];
component.chart.data.datasets[0].data = medals;
component.chart.update();
return;
}
});
}
});
}
})
$ sfdx force:source:pull -u lexbook_prj1_org1
=== Pulled Source
STATE FULL NAME TYPE PROJECT PATH
─────── ────────────────────────────────────── ──────────────────── ────────────────────────────────────────────────────────────────────────
Changed MedalsByType/MedalsByType.cmp AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.cmp-meta.xml
Changed MedalsByType/MedalsByTypeRenderer.js AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByTypeRenderer.js
Changed MedalsByType/MedalsByType.css AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.css
Changed MedalsByType/MedalsByTypeController.js AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByTypeController.js
Changed MedalsByType/MedalsByTypeHelper.js AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByTypeHelper.js
Changed MedalsByType/MedalsByType.cmp AuraDefinitionBundle force-app/main/default/aura/MedalsByType/MedalsByType.cmp
Changed Lex_Book_Chart_Page FlexiPage force-app/main/default/flexipages/Lex_Book_Chart_Page.flexipage-meta.xml
Demo time
Org Shape (Currently in Pilot)
$ sfdx force:org:shape:create -u lexbook_prj1_org1
ERROR: The org needs to be enabled for org shape before one can be created.
Reference
Building Lightning Components with Chart.js
Killing OAuth redirect server running on port 1717
$ sudo lsof -i tcp:1717
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 55682 mchinnappan 16u IPv4 0x5f5d9576988493f7 0t0 TCP localhost:fj-hdnet (LISTEN)
$ sudo kill -9 55682
CI with SFDX
Videos about SFDX
How Everyone Can Leverage Salesforce DX Packaging
### Video: Copying Your Org's Shape into Scratch Orgs
### App Hub [Introduction to App Hub](https://www.salesforce.com/video/1770885/) ### Video: Test Automation and Continuous Integration In SDLC Using Salesforce DX