-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated dependencies and moved to ES6 syntax
- Loading branch information
Showing
17 changed files
with
4,406 additions
and
3,221 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# List files or directories below to ignore them when running prettier | ||
# More information: https://prettier.io/docs/en/ignore.html | ||
# | ||
|
||
package-lock.json | ||
public/** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"trailingComma": "none", | ||
"singleQuote": true, | ||
"tabWidth": 2, | ||
"printWidth": 200 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,47 @@ | ||
# Salesforce React.js integration | ||
# Salesforce React integration | ||
|
||
## About | ||
Sample integration project between Salesforce and a React.js application. | ||
|
||
This application demonstrates the following concepts: | ||
Sample integration project between Salesforce and a React application. | ||
|
||
This app demonstrates the following concepts: | ||
|
||
- using [JSforce](https://jsforce.github.io) as a Salesforce client | ||
- authenticating with OAuth 2.0 (login, logout, retrieving session info) | ||
- using the REST API to run a SOQL query | ||
- using the [Salesforce Lightning Design System](https://www.lightningdesignsystem.com) (SLDS) in a web application (all the CSS is provided by SLDS) | ||
- authenticating with OAuth 2.0 (login, logout, retrieving session info) | ||
- using the REST API to run a SOQL query | ||
- using the [Lightning Design System](https://www.lightningdesignsystem.com) (LDS) in a React application (all the CSS and icons of this app are provided by LDS) | ||
|
||
The source code of this app is structured in the following way: | ||
|
||
- the `client` directory holds the React app | ||
- the `server` directory holds the node.js app that acts as a middleware with the Salesforce Platform | ||
|
||
If you are building a React app with LDS, consider using the [React LDS base components](https://react.lightningdesignsystem.com/). | ||
|
||
## Installation | ||
|
||
1. Create a [Connected App](https://help.salesforce.com/articleView?id=connected_app_create.htm) in Salesforce. | ||
|
||
1. Create a `.env` file in the root directory with this content (make sure to replace the values): | ||
``` | ||
domain='https://login.salesforce.com' | ||
callbackUrl='http://localhost:8080/auth/callback' | ||
consumerKey='YOUR_CLIENT_KEY' | ||
consumerSecret='YOUR_CLIENT_SECRET' | ||
apiVersion='48.0' | ||
1. Create a `.env` file in the root directory of this project and add this content (make sure to replace the values): | ||
|
||
``` | ||
loginUrl='https://login.salesforce.com' | ||
callbackUrl='http://localhost:8080/auth/callback' | ||
consumerKey='YOUR_CLIENT_KEY' | ||
consumerSecret='YOUR_CLIENT_SECRET' | ||
apiVersion='53.0' | ||
isHttps='false' | ||
sessionSecretKey='A_SECRET_STRING' | ||
``` | ||
isHttps='false' | ||
sessionSecretKey='A_SECRET_STRING' | ||
``` | ||
|
||
1. Run `npm run build` to build the app. | ||
|
||
1. Run `npm start` to start the app. | ||
|
||
## Screenshots | ||
<div style="text-align:center;"> | ||
|
||
<div align="center"> | ||
<img src="screenshots/login.png" width="45%" alt="Login screen"/> | ||
<img src="screenshots/main.png" width="45%" alt="Main screen"/> | ||
</div> |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import React from 'react'; | ||
|
||
import NavBar from './NavBar.js'; | ||
import LoginPanel from './LoginPanel.js'; | ||
import QueryForm from './QueryForm.js'; | ||
import QueryResults from './QueryResults.js'; | ||
|
||
export default class App extends React.Component { | ||
state = { | ||
user: null | ||
}; | ||
|
||
componentDidMount() { | ||
// Get logged in user | ||
fetch('/auth/whoami', { | ||
method: 'get', | ||
headers: { | ||
Accept: 'application/json', | ||
'Content-Type': 'application/json' | ||
} | ||
}).then((response) => { | ||
if (response.ok) { | ||
response.json().then((json) => { | ||
this.setState({ user: json }); | ||
}); | ||
} else if (response.status !== 401) { | ||
// Ignore 'unauthorized' responses before logging in | ||
console.error('Failed to retrieve logged user.', JSON.stringify(response)); | ||
} | ||
}); | ||
} | ||
|
||
handleQueryExecution = (data) => { | ||
// Send SOQL query to server | ||
const queryUrl = '/query?q=' + encodeURI(data.query); | ||
fetch(queryUrl, { | ||
headers: { | ||
Accept: 'application/json' | ||
}, | ||
cache: 'no-store' | ||
}).then((response) => { | ||
response.json().then((json) => { | ||
if (response.ok) { | ||
this.setState({ result: JSON.stringify(json, null, 2) }); | ||
} else { | ||
this.setState({ | ||
result: 'Failed to retrieve query result.' | ||
}); | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
render() { | ||
return ( | ||
<div> | ||
<NavBar user={this.state.user} /> | ||
{this.state.user == null ? ( | ||
<LoginPanel /> | ||
) : ( | ||
<div className="slds-m-around--xx-large"> | ||
<QueryForm onExecuteQuery={this.handleQueryExecution} /> | ||
{this.state.result ? <QueryResults result={this.state.result} /> : null} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.