-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
* feat: add sample data import for packaged installations * fix: format sfdx-project.json
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<CustomApplication xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<brand> | ||
<headerColor>#0070D2</headerColor> | ||
<shouldOverrideOrgTheme>false</shouldOverrideOrgTheme> | ||
</brand> | ||
<formFactors>Small</formFactors> | ||
<formFactors>Large</formFactors> | ||
<isNavAutoTempTabsDisabled>true</isNavAutoTempTabsDisabled> | ||
<isNavPersonalizationDisabled>true</isNavPersonalizationDisabled> | ||
<isNavTabPersistenceDisabled>false</isNavTabPersistenceDisabled> | ||
<isOmniPinnedViewEnabled>false</isOmniPinnedViewEnabled> | ||
<label>Sample Data Import</label> | ||
<navType>Standard</navType> | ||
<tabs>Import</tabs> | ||
<uiType>Lightning</uiType> | ||
<utilityBar>Sample_Data_Import_UtilityBar</utilityBar> | ||
</CustomApplication> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<flexiPageRegions> | ||
<name>utilityItems</name> | ||
<type>Region</type> | ||
</flexiPageRegions> | ||
<flexiPageRegions> | ||
<name>backgroundComponents</name> | ||
<type>Background</type> | ||
</flexiPageRegions> | ||
<masterLabel>Sample Data Import UtilityBar</masterLabel> | ||
<template> | ||
<name>one:utilityBarTemplateDesktop</name> | ||
<properties> | ||
<name>isLeftAligned</name> | ||
<value>true</value> | ||
</properties> | ||
</template> | ||
<type>UtilityBar</type> | ||
</FlexiPage> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.container { | ||
text-align: center; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<template> | ||
<div class="container"> | ||
<lightning-button | ||
onclick={handleOnClick} | ||
label="Import sample data" | ||
disabled={isImportActive} | ||
></lightning-button> | ||
<lightning-spinner lwc:if={isImportActive}></lightning-spinner> | ||
</div> | ||
</template> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { LightningElement } from 'lwc'; | ||
import Toast from 'lightning/toast'; | ||
import importData from '@salesforce/apex/DataTreeImporter.importData'; | ||
import generateData from '@salesforce/apex/SampleDataGenerator.generateData'; | ||
|
||
export default class SampleData extends LightningElement { | ||
isImportActive = false; | ||
|
||
handleOnClick() { | ||
this.isImportActive = true; | ||
importData().then(() => { | ||
generateData() | ||
.then(() => { | ||
this.isImportActive = false; | ||
Toast.show({ | ||
label: 'Success', | ||
message: 'Sample data imported successfully', | ||
variant: 'success' | ||
}); | ||
}) | ||
.catch((error) => { | ||
this.isImportActive = false; | ||
Toast.show({ | ||
label: 'Error', | ||
message: error.body.message, | ||
variant: 'error' | ||
}); | ||
}); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>62.0</apiVersion> | ||
<isExposed>true</isExposed> | ||
<targets> | ||
<target>lightning__Tab</target> | ||
</targets> | ||
</LightningComponentBundle> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<RemoteSiteSetting xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<description>Access to sample data in GitHub</description> | ||
<disableProtocolSecurity>false</disableProtocolSecurity> | ||
<isActive>true</isActive> | ||
<url>https://raw.githubusercontent.com</url> | ||
</RemoteSiteSetting> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<CustomTab xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<label>Import</label> | ||
<lwcComponent>sampleData</lwcComponent> | ||
<motif>Custom37: Bridge</motif> | ||
</CustomTab> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
public class DataTreeImporter { | ||
Check warning on line 1 in cc-base-app/main/setup/classes/DataTreeImporter.cls GitHub Actions / scratch-org-testApex classes should declare a sharing model if DML or SOQL is used
|
||
static String githubContacts = 'https://raw.githubusercontent.com/trailheadapps/coral-cloud/main/data/data-Contact.json'; | ||
static String githubExperience = 'https://raw.githubusercontent.com/trailheadapps/coral-cloud/main/data/data-Experience__c.json'; | ||
static String githubGuestReview = 'https://raw.githubusercontent.com/trailheadapps/coral-cloud/main/data/data-Guest_Review__c.json'; | ||
static String githubCase = 'https://raw.githubusercontent.com/trailheadapps/coral-cloud/main/data/data-Case.json'; | ||
|
||
public class SObjectTree { | ||
public List<SObject> records; | ||
} | ||
|
||
@AuraEnabled | ||
public static void importData() { | ||
try { | ||
// Parse JSON data into a list of ObjectData | ||
List<Contact> contacts = (List<Contact>) fetchJsonFromGitHub( | ||
githubContacts | ||
); | ||
|
||
List<Experience__c> experiences = (List<Experience__c>) fetchJsonFromGitHub( | ||
githubExperience | ||
); | ||
|
||
List<Guest_Review__c> reviews = (List<Guest_Review__c>) fetchJsonFromGitHub( | ||
githubGuestReview | ||
); | ||
List<Case> cases = (List<Case>) fetchJsonFromGitHub(githubCase); | ||
|
||
insert contacts; | ||
Check warning on line 28 in cc-base-app/main/setup/classes/DataTreeImporter.cls GitHub Actions / scratch-org-testValidate CRUD permission before SOQL/DML operation
|
||
insert experiences; | ||
Check warning on line 29 in cc-base-app/main/setup/classes/DataTreeImporter.cls GitHub Actions / scratch-org-testValidate CRUD permission before SOQL/DML operation
|
||
|
||
Experience__c experience = [ | ||
SELECT Id | ||
FROM Experience__c | ||
WHERE Name = 'Tropical Snorkel Adventure' | ||
]; | ||
Check warning on line 35 in cc-base-app/main/setup/classes/DataTreeImporter.cls GitHub Actions / scratch-org-testValidate CRUD permission before SOQL/DML operation
|
||
|
||
List<Guest_Review__c> newReviews = new List<Guest_Review__c>(); | ||
for (Guest_Review__c review : reviews) { | ||
review.Experience__c = experience.Id; | ||
review.Contact__c = contacts[0].Id; | ||
newReviews.add(review); | ||
} | ||
insert newReviews; | ||
Check warning on line 43 in cc-base-app/main/setup/classes/DataTreeImporter.cls GitHub Actions / scratch-org-testValidate CRUD permission before SOQL/DML operation
|
||
|
||
Contact cont = [ | ||
SELECT Id | ||
FROM Contact | ||
WHERE LastName = 'Rodriguez' | ||
]; | ||
Check warning on line 49 in cc-base-app/main/setup/classes/DataTreeImporter.cls GitHub Actions / scratch-org-testValidate CRUD permission before SOQL/DML operation
|
||
for (Case c : cases) { | ||
c.ContactId = cont.Id; | ||
} | ||
insert cases; | ||
Check warning on line 53 in cc-base-app/main/setup/classes/DataTreeImporter.cls GitHub Actions / scratch-org-testValidate CRUD permission before SOQL/DML operation
|
||
|
||
System.debug('Data import completed successfully!'); | ||
} catch (Exception e) { | ||
System.debug('Error during data import: ' + e.getMessage()); | ||
} | ||
} | ||
|
||
private static List<sObject> fetchJsonFromGitHub(String url) { | ||
HttpRequest req = new HttpRequest(); | ||
req.setEndpoint(url); | ||
req.setMethod('GET'); | ||
|
||
Http http = new Http(); | ||
HttpResponse res = http.send(req); | ||
|
||
if (res.getStatusCode() == 200) { | ||
SObjectTree treeData = (SObjectTree) JSON.deserialize( | ||
res.getBody(), | ||
SObjectTree.class | ||
); | ||
|
||
// Parse JSON data into a list of ObjectData | ||
List<sObject> records = treeData.records; | ||
return records; | ||
} else { | ||
throw new CalloutException( | ||
'Failed to fetch JSON data. Status: ' + res.getStatus() | ||
); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>62.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,74 @@ | ||
{ | ||
"packageDirectories": [ | ||
{ | ||
"path": "cc-base-app", | ||
"default": true, | ||
"package": "Coral Cloud - Base", | ||
"versionName": "v1.0", | ||
"versionDescription": "Base package for the Coral Cloud sample app", | ||
"versionNumber": "1.0.0.NEXT", | ||
"definitionFile": "config/cc-base-project-scratch-def.json" | ||
"packageDirectories": [ | ||
{ | ||
"path": "cc-base-app", | ||
"default": true, | ||
"package": "Coral Cloud - Base", | ||
"versionName": "v1.0", | ||
"versionDescription": "Base package for the Coral Cloud sample app", | ||
"versionNumber": "1.0.0.NEXT", | ||
"definitionFile": "config/cc-base-project-scratch-def.json" | ||
}, | ||
{ | ||
"path": "cc-employee-app" | ||
}, | ||
{ | ||
"path": "cc-service-app" | ||
} | ||
], | ||
"name": "Coral Cloud Resorts", | ||
"namespace": "", | ||
"sfdcLoginUrl": "https://login.salesforce.com", | ||
"sourceApiVersion": "62.0", | ||
"packageAliases": { | ||
"Coral Cloud - Base": "0HoWx00000000mPKAQ", | ||
"Coral Cloud - [email protected]": "04tWx0000001REHIA2" | ||
}, | ||
{ | ||
"path": "cc-employee-app" | ||
}, | ||
{ | ||
"path": "cc-service-app" | ||
} | ||
], | ||
"name": "Coral Cloud Resorts", | ||
"namespace": "", | ||
"sfdcLoginUrl": "https://login.salesforce.com", | ||
"sourceApiVersion": "62.0", | ||
"packageAliases": { | ||
"Coral Cloud - Base": "0HoWx00000000mPKAQ", | ||
"Coral Cloud - [email protected]": "04tWx0000001REHIA2" | ||
}, | ||
"replacements": [ | ||
{ | ||
"filename": "cc-service-app/main/default/digitalExperiences/site/coral_cloud1/sfdc_cms__view/home/content.json", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_DOMAIN%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_DOMAIN" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/bots/Coral_Cloud_Agent/Coral_Cloud_Agent.bot-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_USERNAME%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_USERNAME" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/setup/classes/SetupServiceAgentUser.cls", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_USERNAME%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_USERNAME" | ||
}, | ||
{ | ||
"glob": "cc-service-app/**/networks/*.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_USERNAME%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_USERNAME" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Agent.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_AGENT_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_AGENT_ID" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Agent.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_CHANNEL_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_CHANNEL_ID" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Agent.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_QUEUE_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_QUEUE_ID" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Queue.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_CHANNEL_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_CHANNEL_ID" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Queue.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_QUEUE_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_QUEUE_ID" | ||
} | ||
] | ||
} | ||
"replacements": [ | ||
{ | ||
"filename": "cc-service-app/main/default/digitalExperiences/site/coral_cloud1/sfdc_cms__view/home/content.json", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_DOMAIN%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_DOMAIN" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/bots/Coral_Cloud_Agent/Coral_Cloud_Agent.bot-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_USERNAME%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_USERNAME" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/setup/classes/SetupServiceAgentUser.cls", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_USERNAME%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_USERNAME" | ||
}, | ||
{ | ||
"glob": "cc-service-app/**/networks/*.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_USERNAME%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_USERNAME" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Agent.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_AGENT_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_AGENT_ID" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Agent.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_CHANNEL_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_CHANNEL_ID" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Agent.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_QUEUE_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_QUEUE_ID" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Queue.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_CHANNEL_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_CHANNEL_ID" | ||
}, | ||
{ | ||
"filename": "cc-service-app/main/default/flows/Route_to_Queue.flow-meta.xml", | ||
"stringToReplace": "%%SF_CC_PLACEHOLDER_FLOW_QUEUE_ID%%", | ||
"replaceWithEnv": "SF_CC_PLACEHOLDER_FLOW_QUEUE_ID" | ||
} | ||
] | ||
} |