git clone https://github.com/alexdevero/electron-react-webpack-boilerplate.git
{
"tenant"
:
"<yourtenant>.sharepoint.com"
,
"tenantID"
"<tenant ID>"
"ClientID"
"<client ID>"
"resource"
"https://graph.microsoft.com"
"redirectURL"
"https://login.microsoftonline.com/common/oauth2/nativeclient"
"listID"
"<SharePoint List ID>"
}
01.
ipcMain.on(
'loginPrompt'
, (event, args) => {
02.
let authWindow =
new
BrowserWindow(
03.
04.
alwaysOnTop:
true
// keeps this window on top of others
05.
modal:
06.
autoHideMenuBar:
07.
parent: mainWindow,
08.
frame:
09.
show:
false
10.
webPreferences: {
11.
nodeIntegration:
// No need to specify these if Electron v4+ but showing for demo
12.
contextIsolation:
// we can isolate this window
13.
14.
15.
);
16.
17.
authWindow.on(
'closed'
, () => {
18.
this
.authWindow =
null
;
19.
});
20.
21.
authWindow.setMenu(
22.
23.
let filter = { urls: [settings.redirectURL] };
24.
25.
authWindow.webContents.on(
'did-finish-load'
26.
authWindow.show();
27.
28.
29.
authWindow.loadURL(`https:
//login.microsoftonline.com/` + settings.tenantID + `/oauth2/authorize?
30.
client_id=`+ settings.ClientID + `
31.
&response_type=token
32.
&scope=openid
33.
&redirect_uri=`+settings.redirectURL+`
34.
&response_mode=fragment
35.
&nonce=678911
36.
&state=12345
37.
&resource=`+ encodeURIComponent(settings.resource));
38.
39.
40.
session.defaultSession.webRequest.onCompleted(filter, (details) => {
41.
var
url = details.url;
42.
let accessToken = url.match(/\
#(?:access_token)\=([\S\s]*?)\&/)[1];
43.
event.returnValue = accessToken;
44.
authWindow.close();
45.
46.
componentDidMount() {
accessToken = ipcRenderer.sendSync(
, {});
npm i office-ui-fabric-react
001.
import React, { Component } from
'react'
002.
import { TextField, PrimaryButton, DefaultButton } from
'office-ui-fabric-react'
003.
import
'../assets/css/App.css'
004.
import * as settings from
'../../settings'
005.
const electron = window.require(
"electron"
006.
const ipcRenderer = electron.ipcRenderer
007.
const request = require(
'request'
008.
let accessToken;
009.
class App extends React.Component {
010.
constructor(props) {
011.
super
(props);
012.
.state = {
013.
tableContent:
014.
015.
.buttonClick =
.buttonClick.bind(
016.
017.
018.
buttonClick(e) {
019.
e.preventDefault();
020.
021.
.addEmployee(
.employeeName.value,
.employeeDesignation.value, accessToken).then(() => {
022.
.getAllEmployees().then((htmlContent) => {
.setState({ tableContent: htmlContent }); });
023.
024.
025.
026.
027.
028.
if
(accessToken !== undefined) {
029.
030.
031.
032.
033.
addEmployee(employeeName, desgination) {
034.
return
Promise((resolve, reject) => {
035.
const options = {
036.
method:
'POST'
037.
url:
'https://graph.microsoft.com/v1.0/sites/'
+ settings.tenant +
'/lists/'
+ settings.listID +
'/items'
038.
headers: {
039.
'Authorization'
'Bearer '
+ accessToken,
040.
'content-type'
'application/json'
041.
},
042.
body: JSON.stringify({
043.
"fields"
: {
044.
"Title"
: employeeName,
045.
"Designation"
: desgination
046.
047.
})
048.
};
049.
050.
request(options, (error, response, body) => {
051.
const result = JSON.parse(body);
052.
(response.statusCode == 201) {
053.
resolve(result);
054.
else
055.
reject(result);
056.
057.
058.
059.
060.
061.
getAllEmployees() {
062.
063.
064.
'GET'
065.
'/items?expand=fields(select=Title,Designation)'
066.
067.
068.
069.
070.
071.
072.
073.
let htmlContent = [];
074.
(response.statusCode == 200) {
075.
Promise.all(result.value.map((eachItem, i) => {
076.
htmlContent.push(<div className=
"w3-container w3-border-bottom w3-border-blue ms-Grid-col ms-sm12 ms-md10 ms-lg9"
>
077.
<div className=
"ms-Grid-col ms-sm6 ms-md6 ms-lg6"
078.
{result.value[i].fields.Title}
079.
</div>
080.
"w3-border-blue ms-Grid-col ms-sm6 ms-md6 ms-lg6"
081.
{result.value[i].fields.Designation}
082.
083.
</div>);
084.
})).then(() => {
085.
resolve(htmlContent);
086.
087.
088.
089.
090.
091.
092.
093.
094.
render() {
095.
"ms-Grid center"
096.
"ms-Grid-row"
097.
"ms-Grid-col ms-sm12 ms-md10 ms-lg9"
098.
<TextField label=
"Employee Name"
componentRef={(ref) => {
.employeeName = ref }} placeholder=
"Enter Name"
/>
099.
</div></div>
100.
101.
102.
.employeeDesignation = ref }} placeholder=
103.
</div></div><br />
104.
105.
"ms-Grid-col ms-sm12 ms-md10 ms-lg6"
106.
<PrimaryButton onClick={
.buttonClick} >Add Employee</PrimaryButton>
107.
108.
109.
<DefaultButton>Cancel</DefaultButton>
110.
111.
112.
<br />
113.
114.
115.
116.
"w3-container w3-pale-blue w3-leftbar w3-border-blue ms-Grid-col ms-sm12 ms-md10 ms-lg9"
117.
118.
Employee Name
119.
120.
121.
Designation
122.
123.
124.
.state.tableContent}
125.
126.
127.
128.
129.
export
default
App
.w3-border-blue, .w3-hover-border-blue:hover {
border-color: skyblue!important;
.w3-border-bottom {
border-bottom: 1px solid
#ccc!important;
.w3-container, .w3-panel {
padding: 0.01em 16px;
*, *:before, *:after {
box-sizing: inherit;
div.linebreak::before{
display: block;
.center {
margin: auto;
width: 60%;
padding: 10px;
border-color:
#2196F3!important;
.w3-pale-blue, .w3-hover-pale-blue:hover {
color:
#000!important;
background-color:
#ddffff!important;
.w3-leftbar {
border-left: 6px solid
#0466ad!important;
body {
#6dbef9;
npm run package
npm run prod