diff --git a/client/src/app/api/ontimeApi.js b/client/src/app/api/ontimeApi.js
index 4ebc5f73b..71b4678b7 100644
--- a/client/src/app/api/ontimeApi.js
+++ b/client/src/app/api/ontimeApi.js
@@ -28,7 +28,6 @@ export const downloadEvents = async () => {
};
export const uploadEvents = async (file) => {
- console.log('uploading', file);
const formData = new FormData();
formData.append('jsondb', file); // appending file
await axios
@@ -40,3 +39,7 @@ export const uploadEvents = async (file) => {
.then((res) => console.log(res.data))
.catch((err) => console.error(err));
};
+
+export const uploadEventsWithPath = async (filepath) => {
+ await axios.post(ontimeURL + '/dbpath', { path: filepath });
+};
diff --git a/client/src/features/menu/MenuBar.jsx b/client/src/features/menu/MenuBar.jsx
index cc400a978..3d32ea0bf 100644
--- a/client/src/features/menu/MenuBar.jsx
+++ b/client/src/features/menu/MenuBar.jsx
@@ -1,4 +1,6 @@
-import { downloadEvents } from 'app/api/ontimeApi';
+import { useMutation, useQueryClient } from 'react-query';
+import { downloadEvents, uploadEventsWithPath } from 'app/api/ontimeApi';
+import { EVENTS_TABLE } from 'app/api/apiConstants';
import DownloadIconBtn from './buttons/DownloadIconBtn';
import SettingsIconBtn from './buttons/SettingsIconBtn';
import InfoIconBtn from './buttons/InfoIconBtn';
@@ -7,15 +9,49 @@ import MinIconBtn from './buttons/MinIconBtn';
import QuitIconBtn from './buttons/QuitIconBtn';
import style from './MenuBar.module.css';
import HelpIconBtn from './buttons/HelpIconBtn';
-const { ipcRenderer } = window.require('electron');
+import UploadIconBtn from './buttons/UploadIconBtn';
+
+const { ipcRenderer, remote } = window.require('electron');
export default function MenuBar(props) {
const { onOpen, onClose } = props;
+ const queryClient = useQueryClient();
+ const uploaddbPath = useMutation(uploadEventsWithPath, {
+ onSettled: () => {
+ queryClient.invalidateQueries(EVENTS_TABLE);
+ },
+ });
const handleDownload = () => {
downloadEvents();
};
+ const handleUpload = () => {
+ remote.dialog
+ .showOpenDialog({
+ title: 'Select the File to be uploaded',
+ buttonLabel: 'Upload',
+ filters: [
+ {
+ name: 'Text Files',
+ extensions: ['json'],
+ },
+ ],
+ // Specifying the File Selector Property
+ properties: ['openFile'],
+ })
+ .then((file) => {
+ // Stating whether dialog operation was
+ // cancelled or not.
+ if (!file.canceled) {
+ uploaddbPath.mutate(file.filePaths[0].toString());
+ }
+ })
+ .catch((err) => {
+ console.log(err);
+ });
+ };
+
const handleIPC = (action) => {
switch (action) {
case 'min':
@@ -55,11 +91,17 @@ export default function MenuBar(props) {
clickhandler={() => handleIPC('help')}
/>
+
+
+ }
+ colorScheme='white'
+ onClick={clickhandler}
+ _focus={{ boxShadow: 'none' }}
+ {...rest}
+ />
+
+ );
+}
diff --git a/server/main.js b/server/main.js
index 31c3f3bf1..f8770d887 100644
--- a/server/main.js
+++ b/server/main.js
@@ -7,10 +7,10 @@ const {
dialog,
ipcMain,
shell,
+ Notification,
} = require('electron');
const path = require('path');
const { electron } = require('process');
-const { Notification } = require('electron');
const env = process.env.NODE_ENV || 'prod';
@@ -100,6 +100,7 @@ function createWindow() {
// TODO: what are recommended alternatives to node integration?
nodeIntegration: true,
contextIsolation: false,
+ enableRemoteModule: true,
},
});
diff --git a/server/src/controllers/ontimeController.js b/server/src/controllers/ontimeController.js
index 981d6265e..ed5a8dd9c 100644
--- a/server/src/controllers/ontimeController.js
+++ b/server/src/controllers/ontimeController.js
@@ -29,6 +29,7 @@ async function deleteFile(file) {
// parses version 1 of the data system
async function parsev1(jsonData) {
+ let numEntries = 0;
if ('events' in jsonData) {
let events = [];
let ids = [];
@@ -51,15 +52,19 @@ async function parsev1(jsonData) {
isPublic: e.isPublic,
id: e.id,
});
+ numEntries++;
} else if (e.type === 'delay') {
events.push({ ...delayDef, duration: e.duration });
+ numEntries++;
} else if (e.type === 'block') {
events.push({ ...blockDef });
+ numEntries++;
}
}
// write to db
db.data.events = events;
db.write();
+ console.log(`Uploaded file with ${numEntries} entries`);
}
if ('event' in jsonData) {
@@ -99,15 +104,7 @@ export const dbDownload = async (req, res) => {
});
};
-// Create controller for POST request to '/ontime/db'
-// Returns -
-export const dbUpload = async (req, res) => {
- if (!req.file) {
- res.status(400).send({ message: 'File not found' });
- return;
- }
-
- const file = req.file.path;
+const upload = async (file, req, res) => {
if (!fs.existsSync(file)) {
res.status(500).send({ message: 'Upload failed' });
return;
@@ -115,11 +112,8 @@ export const dbUpload = async (req, res) => {
try {
// get file
- let rawdata = fs.readFileSync(file);
- let uploadedJson = JSON.parse(rawdata);
-
- // delete file
- deleteFile(file);
+ const rawdata = fs.readFileSync(file);
+ const uploadedJson = JSON.parse(rawdata);
// check version
if (uploadedJson.settings.version === 1) parsev1(uploadedJson);
@@ -134,3 +128,25 @@ export const dbUpload = async (req, res) => {
res.status(400).send({ message: error });
}
};
+
+// Create controller for POST request to '/ontime/db'
+// Returns -
+export const dbUpload = async (req, res) => {
+ if (!req.file) {
+ res.status(400).send({ message: 'File not found' });
+ return;
+ }
+
+ const file = req.file.path;
+ upload(file, req, res);
+};
+
+// Create controller for POST request to '/ontime/dbpath'
+// Returns -
+export const dbPathToUpload = async (req, res) => {
+ if (!req.body.path) {
+ res.status(400).send({ message: 'Path to file not found' });
+ return;
+ }
+ upload(req.body.path, req, res);
+};
diff --git a/server/src/routes/ontimeRouter.js b/server/src/routes/ontimeRouter.js
index e5b5e5670..8c1141170 100644
--- a/server/src/routes/ontimeRouter.js
+++ b/server/src/routes/ontimeRouter.js
@@ -2,10 +2,17 @@ import express from 'express';
import uploadJson from '../utils/upload.js';
export const router = express.Router();
-import { dbDownload, dbUpload } from '../controllers/ontimeController.js';
+import {
+ dbDownload,
+ dbUpload,
+ dbPathToUpload,
+} from '../controllers/ontimeController.js';
// create route between controller and '/ontime/db' endpoint
router.get('/db', dbDownload);
// create route between controller and '/ontime/db' endpoint
router.post('/db', uploadJson, dbUpload);
+
+// create route between controller and '/ontime/dbpath' endpoint
+router.post('/dbpath', dbPathToUpload);