Skip to content

Commit b34f331

Browse files
authored
Merge pull request #9 from oslabs-beta/electron-react
Development Version 0.0.5
2 parents 8b4c983 + 88e6c3f commit b34f331

30 files changed

+1174
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.eslintrc.js
3+
package-lock.json

LISENCE.md renamed to LICENSE.md

File renamed without changes.

Main.js

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
const { app, BrowserWindow, ipcMain } = require('electron');
2+
const fs = require('fs');
3+
const path = require('path');
4+
const connectSQL = require('./model/sql-connect');
5+
const connectMongoose = require('./model/mongoose-connect');
6+
const CommunicationSchema = require('./model/mongoose-communicatonSchema');
7+
const HealthInfoSchema = require('./model/mongoose-healthInfoSchema');
8+
9+
let win;
10+
function createWindow() {
11+
win = new BrowserWindow({
12+
width: 900,
13+
height: 800,
14+
icon: path.join(__dirname, 'app/assets/icons/icon.png'),
15+
webPreferences: {
16+
nodeIntegration: true,
17+
},
18+
});
19+
20+
// Development
21+
win.loadURL('http://localhost:8080/');
22+
23+
// Production
24+
// win.loadURL(`file://${path.join(__dirname, './dist/index.html')}`);
25+
26+
win.on('closed', () => {
27+
win = null;
28+
});
29+
}
30+
app.on('ready', createWindow);
31+
32+
app.on('window-all-closed', () => {
33+
if (process.platform !== 'darwin') {
34+
app.quit();
35+
}
36+
});
37+
38+
app.on('activate', () => {
39+
if (win === null) {
40+
createWindow();
41+
}
42+
});
43+
44+
// Load settings JSON and returns current setup status back to the render process.
45+
ipcMain.on('setup', (message) => {
46+
const state = JSON.parse(
47+
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), {
48+
encoding: 'UTF-8',
49+
}),
50+
);
51+
const { setupRequired } = state;
52+
message.returnValue = setupRequired;
53+
});
54+
55+
// Loads existing settings JSON and update settings to include new services entered by the user.
56+
ipcMain.on('submit', (message, newService) => {
57+
const state = JSON.parse(
58+
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), {
59+
encoding: 'UTF-8',
60+
}),
61+
);
62+
// if statement is used to remove hard coded data.
63+
if (state.michelleWasHere) {
64+
state.setupRequired = false;
65+
state.michelleWasHere = false;
66+
state.services = [JSON.parse(newService)];
67+
fs.writeFileSync(path.resolve(__dirname, './user/settings.json'), JSON.stringify(state));
68+
} else {
69+
state.setupRequired = false;
70+
state.services.push(JSON.parse(newService));
71+
fs.writeFileSync(path.resolve(__dirname, './user/settings.json'), JSON.stringify(state));
72+
}
73+
});
74+
75+
// Load settings JSON and returns updated state back to the render process.
76+
ipcMain.on('dashboard', (message) => {
77+
const state = JSON.parse(
78+
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), {
79+
encoding: 'UTF-8',
80+
}),
81+
);
82+
const { services } = state;
83+
const dashboardList = services.reduce((acc, curVal) => {
84+
acc.push(curVal[0]);
85+
return acc;
86+
}, []);
87+
message.returnValue = dashboardList;
88+
});
89+
90+
// Queries the database for communications information and returns it back to the render process.
91+
ipcMain.on('overviewRequest', (message, index) => {
92+
const databaseType = JSON.parse(
93+
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), { encoding: 'UTF-8' }),
94+
).services[index][1];
95+
96+
if (databaseType === 'MongoDB') {
97+
connectMongoose(index);
98+
CommunicationSchema.find({}, (err, data) => {
99+
if (err) {
100+
console.log(`An error occured while querying the database: ${err}`);
101+
message.sender.send('overviewResponse', JSON.stringify(err));
102+
}
103+
const queryResults = JSON.stringify(data);
104+
// Asynchronous event emitter used to transmit query results back to the render process.
105+
message.sender.send('overviewResponse', queryResults);
106+
});
107+
}
108+
109+
if (databaseType === 'SQL') {
110+
const pool = connectSQL(index);
111+
const getCommunications = 'SELECT * FROM communications';
112+
pool.query(getCommunications, (err, result) => {
113+
if (err) {
114+
console.log(err);
115+
message.sender.send(JSON.stringify('Database info could not be retreived.'));
116+
}
117+
const queryResults = JSON.stringify(result.rows);
118+
// Asynchronous event emitter used to transmit query results back to the render process.
119+
message.sender.send('overviewResponse', queryResults);
120+
});
121+
}
122+
});
123+
124+
// Queries the database for computer health information and returns it back to the render process.
125+
ipcMain.on('detailsRequest', (message, index) => {
126+
const databaseType = JSON.parse(
127+
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), { encoding: 'UTF-8' }),
128+
).services[index][1];
129+
130+
if (databaseType === 'MongoDB') {
131+
connectMongoose(index);
132+
HealthInfoSchema.find({}, (err, data) => {
133+
if (err) {
134+
message.sender.send('detailsResponse', JSON.stringify(err));
135+
}
136+
const queryResults = JSON.stringify(data);
137+
console.log('QUERY RESULTS =>', queryResults);
138+
// Asynchronous event emitter used to transmit query results back to the render process.
139+
message.sender.send('detailsResponse', queryResults);
140+
});
141+
}
142+
143+
if (databaseType === 'SQL') {
144+
const pool = connectSQL(index);
145+
const getHealth = 'SELECT * FROM healthInfo';
146+
pool.query(getHealth, (err, result) => {
147+
if (err) {
148+
message.sender.send('detailsResponse', JSON.stringify('Database info could not be retreived.'));
149+
}
150+
const queryResults = JSON.stringify(result.rows);
151+
// Asynchronous event emitter used to transmit query results back to the render process.
152+
message.sender.send('detailsResponse', queryResults);
153+
});
154+
}
155+
});

app/assets/icon2.png

27.7 KB
Loading

app/assets/icons/icon.png

761 KB
Loading

app/assets/logo2.png

54.3 KB
Loading

app/charts/detail-chart-template.jsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React, { useContext } from 'react';
2+
// You can change the chart property imported to the one that suits your needs.
3+
import { Doughnut } from 'react-chartjs-2';
4+
import HealthContext from '../context/DetailsContext';
5+
6+
const RequestTypesChart = () => {
7+
// ! Do not change the variables related to context.
8+
const healthData = useContext(HealthContext);
9+
const health = healthData.detailsData;
10+
11+
// Helper function
12+
const createChart = () => {
13+
// Object for storing data
14+
const /*<MY OBJECT>*/ = {
15+
};
16+
17+
// Iterate through HealthInfo to creat an object with data needed to create your graph.
18+
for (let i = 0; i < health.length; i += 1) {
19+
20+
}
21+
22+
// ! Chart Data
23+
// * --- Change the object used in data to the one you created.
24+
// * --- Labels must be in the same order as the keys in your object.
25+
const chartData = {
26+
datasets: [
27+
{
28+
label: 'Breakdown of Requests by Type',
29+
data: Object.values(requestObj),
30+
backgroundColor: [
31+
'rgb(2, 210, 249)',
32+
'rgb(198, 42, 177)',
33+
'rgb(252, 170, 52)',
34+
'rgb(239, 91, 145)',
35+
'rgb(182, 219, 26)',
36+
'rgb(254, 255, 0)',
37+
],
38+
},
39+
],
40+
labels: ['DELETE', 'GET', 'PATCH', 'POST', 'PUSH', 'PUT'],
41+
};
42+
43+
return <Doughnut data={chartData} />;
44+
};
45+
46+
// Return div with helper function invoked
47+
return <div>{createChart()}</div>;
48+
};
49+
50+
export default RequestTypesChart;

app/charts/memory-chart.jsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import React, { useContext } from 'react';
2+
import { Line } from 'react-chartjs-2';
3+
import HealthContext from '../context/DetailsContext';
4+
5+
const MemoryChart = () => {
6+
const healthData = useContext(HealthContext);
7+
// const health = healthData.detailData;
8+
9+
const createChart = () => {
10+
let free = [];
11+
let used= [];
12+
let active = [];
13+
let total = [];
14+
15+
for (let i = 0; i < healthData.length; i += 1) {
16+
// If Mongo
17+
if (healthData[i].freeMemory && healthData[i].activeMemory && healthData[i].usedMemory && healthData[i].totalMemory) {
18+
free.push(healthData[i].freeMemory);
19+
active.push(healthData[i].activeMemory);
20+
used.push(healthData[i].usedMemory);
21+
total.push(healthData[i].totalMemory);
22+
} else {
23+
free.push(healthData[i].freememory);
24+
active.push(healthData[i].activememory);
25+
used.push(healthData[i].usedmemory);
26+
total.push(healthData[i].totalmemory);
27+
}
28+
}
29+
30+
31+
32+
const memoryObj = {
33+
freeMem: free,
34+
usedMem: used,
35+
activeMem: active,
36+
totalMem: total
37+
}
38+
39+
const chartData = {
40+
datasets: [
41+
{
42+
label: "Free Memory",
43+
data: Object.values(memoryObj.freeMem),
44+
backgroundColor: [
45+
"rgb(2, 210, 249)"
46+
]
47+
},
48+
{
49+
label: "Used Memory",
50+
data: Object.values(memoryObj.usedMem),
51+
backgroundColor: [
52+
"rgb(198, 42, 177)",
53+
]
54+
},
55+
{
56+
label: "Active Memory",
57+
data: Object.values(memoryObj.activeMem),
58+
backgroundColor: [
59+
"rgb(252, 170, 52)"
60+
]
61+
},
62+
{
63+
label: "Total Memory",
64+
data: Object.values(memoryObj.activeMem),
65+
backgroundColor: [
66+
"rgb(239, 91, 145)"
67+
]
68+
},
69+
],
70+
labels: ["Free Memory", "Active Memory", "Used Memory", "Total Memory"]
71+
};
72+
73+
return <Line data={chartData} />;
74+
};
75+
76+
// Return div with helper function invoked
77+
return <div>{createChart()}</div>;
78+
};
79+
80+
export default MemoryChart;

app/charts/request-type-chart.jsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { useContext } from 'react';
2+
import { Doughnut } from 'react-chartjs-2';
3+
import CommunicationsContext from '../context/OverviewContext';
4+
5+
const RequestTypesChart = () => {
6+
const communicationsData = useContext(CommunicationsContext);
7+
const communications = communicationsData.overviewData;
8+
9+
const createRequestChart = () => {
10+
const requestObj = {
11+
DELETE: 0,
12+
GET: 0,
13+
PATCH: 0,
14+
POST: 0,
15+
PUSH: 0,
16+
PUT: 0,
17+
};
18+
19+
for (let i = 0; i < communications.length; i += 1) {
20+
const element = communications[i];
21+
// if Mongo
22+
if (element.reqType in requestObj) requestObj[element.reqType] += 1;
23+
// if SQL
24+
else if (element.reqtype in requestObj) requestObj[element.reqtype] += 1;
25+
}
26+
27+
const chartData = {
28+
datasets: [
29+
{
30+
label: 'Breakdown of Requests by Type',
31+
data: Object.values(requestObj),
32+
backgroundColor: [
33+
'rgb(2, 210, 249)',
34+
'rgb(198, 42, 177)',
35+
'rgb(252, 170, 52)',
36+
'rgb(239, 91, 145)',
37+
'rgb(182, 219, 26)',
38+
'rgb(254, 255, 0)',
39+
],
40+
},
41+
],
42+
labels: ['DELETE', 'GET', 'PATCH', 'POST', 'PUSH', 'PUT'],
43+
};
44+
45+
return <Doughnut data={chartData} />;
46+
};
47+
48+
return <div>{createRequestChart()}</div>;
49+
};
50+
51+
export default RequestTypesChart;

0 commit comments

Comments
 (0)