mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-07 15:29:10 +00:00
feat: upload file
This commit is contained in:
@@ -28,7 +28,6 @@ export const downloadEvents = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const uploadEvents = async (file) => {
|
export const uploadEvents = async (file) => {
|
||||||
console.log('uploading', file);
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('jsondb', file); // appending file
|
formData.append('jsondb', file); // appending file
|
||||||
await axios
|
await axios
|
||||||
@@ -40,3 +39,7 @@ export const uploadEvents = async (file) => {
|
|||||||
.then((res) => console.log(res.data))
|
.then((res) => console.log(res.data))
|
||||||
.catch((err) => console.error(err));
|
.catch((err) => console.error(err));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const uploadEventsWithPath = async (filepath) => {
|
||||||
|
await axios.post(ontimeURL + '/dbpath', { path: filepath });
|
||||||
|
};
|
||||||
|
|||||||
@@ -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 DownloadIconBtn from './buttons/DownloadIconBtn';
|
||||||
import SettingsIconBtn from './buttons/SettingsIconBtn';
|
import SettingsIconBtn from './buttons/SettingsIconBtn';
|
||||||
import InfoIconBtn from './buttons/InfoIconBtn';
|
import InfoIconBtn from './buttons/InfoIconBtn';
|
||||||
@@ -7,15 +9,49 @@ import MinIconBtn from './buttons/MinIconBtn';
|
|||||||
import QuitIconBtn from './buttons/QuitIconBtn';
|
import QuitIconBtn from './buttons/QuitIconBtn';
|
||||||
import style from './MenuBar.module.css';
|
import style from './MenuBar.module.css';
|
||||||
import HelpIconBtn from './buttons/HelpIconBtn';
|
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) {
|
export default function MenuBar(props) {
|
||||||
const { onOpen, onClose } = props;
|
const { onOpen, onClose } = props;
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const uploaddbPath = useMutation(uploadEventsWithPath, {
|
||||||
|
onSettled: () => {
|
||||||
|
queryClient.invalidateQueries(EVENTS_TABLE);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const handleDownload = () => {
|
const handleDownload = () => {
|
||||||
downloadEvents();
|
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) => {
|
const handleIPC = (action) => {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'min':
|
case 'min':
|
||||||
@@ -55,11 +91,17 @@ export default function MenuBar(props) {
|
|||||||
clickhandler={() => handleIPC('help')}
|
clickhandler={() => handleIPC('help')}
|
||||||
/>
|
/>
|
||||||
<SettingsIconBtn style={{ fontSize: '1.5em' }} size='lg' disabled />
|
<SettingsIconBtn style={{ fontSize: '1.5em' }} size='lg' disabled />
|
||||||
|
<div className={style.gap} />
|
||||||
<InfoIconBtn
|
<InfoIconBtn
|
||||||
style={{ fontSize: '1.5em' }}
|
style={{ fontSize: '1.5em' }}
|
||||||
size='lg'
|
size='lg'
|
||||||
clickhandler={onOpen}
|
clickhandler={onOpen}
|
||||||
/>
|
/>
|
||||||
|
<UploadIconBtn
|
||||||
|
style={{ fontSize: '1.5em' }}
|
||||||
|
size='lg'
|
||||||
|
clickhandler={handleUpload}
|
||||||
|
/>
|
||||||
<DownloadIconBtn
|
<DownloadIconBtn
|
||||||
style={{ fontSize: '1.5em' }}
|
style={{ fontSize: '1.5em' }}
|
||||||
size='lg'
|
size='lg'
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { IconButton } from '@chakra-ui/button';
|
||||||
|
import { Tooltip } from '@chakra-ui/tooltip';
|
||||||
|
import { FiUpload } from 'react-icons/fi';
|
||||||
|
|
||||||
|
export default function UploadIconBtn(props) {
|
||||||
|
const { clickhandler, ...rest } = props;
|
||||||
|
return (
|
||||||
|
<Tooltip label='Upload File'>
|
||||||
|
<IconButton
|
||||||
|
size={props.size || 'xs'}
|
||||||
|
icon={<FiUpload />}
|
||||||
|
colorScheme='white'
|
||||||
|
onClick={clickhandler}
|
||||||
|
_focus={{ boxShadow: 'none' }}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
+2
-1
@@ -7,10 +7,10 @@ const {
|
|||||||
dialog,
|
dialog,
|
||||||
ipcMain,
|
ipcMain,
|
||||||
shell,
|
shell,
|
||||||
|
Notification,
|
||||||
} = require('electron');
|
} = require('electron');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { electron } = require('process');
|
const { electron } = require('process');
|
||||||
const { Notification } = require('electron');
|
|
||||||
|
|
||||||
const env = process.env.NODE_ENV || 'prod';
|
const env = process.env.NODE_ENV || 'prod';
|
||||||
|
|
||||||
@@ -100,6 +100,7 @@ function createWindow() {
|
|||||||
// TODO: what are recommended alternatives to node integration?
|
// TODO: what are recommended alternatives to node integration?
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
contextIsolation: false,
|
contextIsolation: false,
|
||||||
|
enableRemoteModule: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ async function deleteFile(file) {
|
|||||||
|
|
||||||
// parses version 1 of the data system
|
// parses version 1 of the data system
|
||||||
async function parsev1(jsonData) {
|
async function parsev1(jsonData) {
|
||||||
|
let numEntries = 0;
|
||||||
if ('events' in jsonData) {
|
if ('events' in jsonData) {
|
||||||
let events = [];
|
let events = [];
|
||||||
let ids = [];
|
let ids = [];
|
||||||
@@ -51,15 +52,19 @@ async function parsev1(jsonData) {
|
|||||||
isPublic: e.isPublic,
|
isPublic: e.isPublic,
|
||||||
id: e.id,
|
id: e.id,
|
||||||
});
|
});
|
||||||
|
numEntries++;
|
||||||
} else if (e.type === 'delay') {
|
} else if (e.type === 'delay') {
|
||||||
events.push({ ...delayDef, duration: e.duration });
|
events.push({ ...delayDef, duration: e.duration });
|
||||||
|
numEntries++;
|
||||||
} else if (e.type === 'block') {
|
} else if (e.type === 'block') {
|
||||||
events.push({ ...blockDef });
|
events.push({ ...blockDef });
|
||||||
|
numEntries++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// write to db
|
// write to db
|
||||||
db.data.events = events;
|
db.data.events = events;
|
||||||
db.write();
|
db.write();
|
||||||
|
console.log(`Uploaded file with ${numEntries} entries`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('event' in jsonData) {
|
if ('event' in jsonData) {
|
||||||
@@ -99,15 +104,7 @@ export const dbDownload = async (req, res) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create controller for POST request to '/ontime/db'
|
const upload = async (file, req, res) => {
|
||||||
// Returns -
|
|
||||||
export const dbUpload = async (req, res) => {
|
|
||||||
if (!req.file) {
|
|
||||||
res.status(400).send({ message: 'File not found' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = req.file.path;
|
|
||||||
if (!fs.existsSync(file)) {
|
if (!fs.existsSync(file)) {
|
||||||
res.status(500).send({ message: 'Upload failed' });
|
res.status(500).send({ message: 'Upload failed' });
|
||||||
return;
|
return;
|
||||||
@@ -115,11 +112,8 @@ export const dbUpload = async (req, res) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// get file
|
// get file
|
||||||
let rawdata = fs.readFileSync(file);
|
const rawdata = fs.readFileSync(file);
|
||||||
let uploadedJson = JSON.parse(rawdata);
|
const uploadedJson = JSON.parse(rawdata);
|
||||||
|
|
||||||
// delete file
|
|
||||||
deleteFile(file);
|
|
||||||
|
|
||||||
// check version
|
// check version
|
||||||
if (uploadedJson.settings.version === 1) parsev1(uploadedJson);
|
if (uploadedJson.settings.version === 1) parsev1(uploadedJson);
|
||||||
@@ -134,3 +128,25 @@ export const dbUpload = async (req, res) => {
|
|||||||
res.status(400).send({ message: error });
|
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);
|
||||||
|
};
|
||||||
|
|||||||
@@ -2,10 +2,17 @@ import express from 'express';
|
|||||||
import uploadJson from '../utils/upload.js';
|
import uploadJson from '../utils/upload.js';
|
||||||
export const router = express.Router();
|
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
|
// create route between controller and '/ontime/db' endpoint
|
||||||
router.get('/db', dbDownload);
|
router.get('/db', dbDownload);
|
||||||
|
|
||||||
// create route between controller and '/ontime/db' endpoint
|
// create route between controller and '/ontime/db' endpoint
|
||||||
router.post('/db', uploadJson, dbUpload);
|
router.post('/db', uploadJson, dbUpload);
|
||||||
|
|
||||||
|
// create route between controller and '/ontime/dbpath' endpoint
|
||||||
|
router.post('/dbpath', dbPathToUpload);
|
||||||
|
|||||||
Reference in New Issue
Block a user