Skip to content

Commit

Permalink
merge upload and download in webUI #577
Browse files Browse the repository at this point in the history
  • Loading branch information
proddy committed Jul 20, 2022
1 parent d707e92 commit 4420ae3
Show file tree
Hide file tree
Showing 9 changed files with 786 additions and 1,695 deletions.
691 changes: 600 additions & 91 deletions interface/package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions interface/package.json
Expand Up @@ -8,10 +8,10 @@
"@emotion/styled": "^11.9.3",
"@msgpack/msgpack": "^2.7.2",
"@mui/icons-material": "^5.8.4",
"@mui/material": "^5.9.0",
"@table-library/react-table-library": "4.0.7",
"@mui/material": "^5.9.1",
"@table-library/react-table-library": "4.0.10",
"@types/lodash": "^4.14.182",
"@types/node": "^18.0.3",
"@types/node": "^18.0.6",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@types/react-router-dom": "^5.3.3",
Expand Down
104 changes: 97 additions & 7 deletions interface/src/framework/system/GeneralFileUpload.tsx
@@ -1,8 +1,20 @@
import { FC, useContext } from 'react';
import { AxiosPromise } from 'axios';
import { FC } from 'react';

import { Typography, Button, Box } from '@mui/material';

import { FileUploadConfig } from '../../api/endpoints';
import { MessageBox, SingleUpload, useFileUpload } from '../../components';
import { SingleUpload, useFileUpload } from '../../components';

import { AuthenticatedContext } from '../../contexts/authentication';

import DownloadIcon from '@mui/icons-material/GetApp';

import { useSnackbar } from 'notistack';

import { extractErrorMessage } from '../../utils';

import * as EMSESP from '../../project/api';

interface UploadFileProps {
uploadGeneralFile: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
Expand All @@ -11,16 +23,94 @@ interface UploadFileProps {
const GeneralFileUpload: FC<UploadFileProps> = ({ uploadGeneralFile }) => {
const [uploadFile, cancelUpload, uploading, uploadProgress] = useFileUpload({ upload: uploadGeneralFile });

const { me } = useContext(AuthenticatedContext);
const { enqueueSnackbar } = useSnackbar();

const saveFile = (json: any, endpoint: string) => {
const a = document.createElement('a');
const filename = 'emsesp_' + endpoint + '_json.txt';
a.href = URL.createObjectURL(
new Blob([JSON.stringify(json, null, 2)], {
type: 'text/plain'
})
);
a.setAttribute('download', filename);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
enqueueSnackbar('File downloaded', { variant: 'info' });
};

const downloadSettings = async () => {
try {
const response = await EMSESP.getSettings();
if (response.status !== 200) {
enqueueSnackbar('Unable to get settings', { variant: 'error' });
} else {
saveFile(response.data, 'settings');
}
} catch (error: unknown) {
enqueueSnackbar(extractErrorMessage(error, 'Problem with downloading'), { variant: 'error' });
}
};

const downloadCustomizations = async () => {
try {
const response = await EMSESP.getCustomizations();
if (response.status !== 200) {
enqueueSnackbar('Unable to get customizations', { variant: 'error' });
} else {
saveFile(response.data, 'customizations');
}
} catch (error: unknown) {
enqueueSnackbar(extractErrorMessage(error, 'Problem with downloading'), { variant: 'error' });
}
};

return (
<>
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
Upload
</Typography>
{!uploading && (
<MessageBox
message="Upload a new firmware (.bin) file or an exported settings or customizations (.json) file below. EMS-ESP will restart afterwards to apply the new changes."
level="warning"
my={2}
/>
<Box mb={2} color="warning.main">
<Typography variant="body2">
Upload a new firmware (.bin) file, settings or customizations (*_json.txt) file below.
</Typography>
</Box>
)}
<SingleUpload onDrop={uploadFile} onCancel={cancelUpload} uploading={uploading} progress={uploadProgress} />

<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
Download
</Typography>
{me.admin && (
<>
<Box color="warning.main">
<Typography mb={1} variant="body2">
Download the application settings. Be careful when sharing your settings as this file contains passwords
and other sensitive system information.
</Typography>
</Box>
<Button startIcon={<DownloadIcon />} variant="outlined" color="primary" onClick={() => downloadSettings()}>
settings
</Button>

<Box color="warning.main">
<Typography mt={2} mb={1} variant="body2">
Download the entity customizations.
</Typography>
</Box>
<Button
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => downloadCustomizations()}
>
customizations
</Button>
</>
)}
</>
);
};
Expand Down
2 changes: 1 addition & 1 deletion interface/src/framework/system/System.tsx
Expand Up @@ -26,7 +26,7 @@ const System: FC = () => {
<Tab value="log" label="System Log" />

{features.ota && <Tab value="ota" label="OTA Settings" disabled={!me.admin} />}
{features.upload_firmware && <Tab value="upload" label="Upload" disabled={!me.admin} />}
{features.upload_firmware && <Tab value="upload" label="Upload/Download" disabled={!me.admin} />}
</RouterTabs>
<Routes>
<Route path="status" element={<SystemStatusForm />} />
Expand Down
2 changes: 1 addition & 1 deletion interface/src/framework/system/UploadFileForm.tsx
Expand Up @@ -17,7 +17,7 @@ const UploadFileForm: FC = () => {
});

return (
<SectionContent title="Upload File" titleGutter>
<SectionContent title="Upload/Download" titleGutter>
{restarting ? <RestartMonitor /> : <GeneralFileUpload uploadGeneralFile={uploadFile.current} />}
</SectionContent>
);
Expand Down
132 changes: 29 additions & 103 deletions interface/src/project/HelpInformation.tsx
@@ -1,10 +1,8 @@
import { FC, useContext } from 'react';
import { FC } from 'react';

import { Typography, Button, Box, List, ListItem, ListItemText, Link, ListItemAvatar } from '@mui/material';

import { SectionContent, ButtonRow, MessageBox } from '../components';

import { AuthenticatedContext } from '../contexts/authentication';
import { SectionContent } from '../components';

import { useSnackbar } from 'notistack';

Expand All @@ -13,7 +11,6 @@ import MenuBookIcon from '@mui/icons-material/MenuBookTwoTone';
import GitHubIcon from '@mui/icons-material/GitHub';
import StarIcon from '@mui/icons-material/Star';
import DownloadIcon from '@mui/icons-material/GetApp';
import TuneIcon from '@mui/icons-material/Tune';

import { extractErrorMessage } from '../utils';

Expand All @@ -22,11 +19,9 @@ import * as EMSESP from './api';
const HelpInformation: FC = () => {
const { enqueueSnackbar } = useSnackbar();

const { me } = useContext(AuthenticatedContext);

const saveFile = (json: any, endpoint: string) => {
const a = document.createElement('a');
const filename = 'emsesp_' + endpoint + '.json';
const filename = 'emsesp_' + endpoint + '_json.txt';
a.href = URL.createObjectURL(
new Blob([JSON.stringify(json, null, 2)], {
type: 'text/plain'
Expand Down Expand Up @@ -56,60 +51,27 @@ const HelpInformation: FC = () => {
}
};

const downloadSettings = async () => {
try {
const response = await EMSESP.getSettings();
if (response.status !== 200) {
enqueueSnackbar('Unable to get settings', { variant: 'error' });
} else {
saveFile(response.data, 'settings');
}
} catch (error: unknown) {
enqueueSnackbar(extractErrorMessage(error, 'Problem with downloading'), { variant: 'error' });
}
};

const downloadCustomizations = async () => {
try {
const response = await EMSESP.getCustomizations();
if (response.status !== 200) {
enqueueSnackbar('Unable to get customizations', { variant: 'error' });
} else {
saveFile(response.data, 'customizations');
}
} catch (error: unknown) {
enqueueSnackbar(extractErrorMessage(error, 'Problem with downloading'), { variant: 'error' });
}
};

return (
<SectionContent title="Application Information &amp; Support" titleGutter>
<SectionContent title="Support Information" titleGutter>
<List>
<ListItem>
<ListItemAvatar>
<TuneIcon />
<MenuBookIcon />
</ListItemAvatar>
<ListItemText>
For a help on each of the Application Settings see&nbsp;
Visit the online&nbsp;
<Link target="_blank" href="https://emsesp.github.io/docs" color="primary">
{'Wiki'}
</Link>
&nbsp;to get instructions on how to&nbsp;
<Link
target="_blank"
href="https://emsesp.github.io/docs/#/Configure-firmware?id=ems-esp-settings"
color="primary"
>
{'Configuring EMS-ESP'}
</Link>
</ListItemText>
</ListItem>

<ListItem>
<ListItemAvatar>
<MenuBookIcon />
</ListItemAvatar>
<ListItemText>
For general information about EMS-ESP visit the online&nbsp;
<Link target="_blank" href="https://emsesp.github.io/docs" color="primary">
{'Documentation'}
{'configure'}
</Link>
&nbsp;EMS-ESP and access other information.
</ListItemText>
</ListItem>

Expand All @@ -122,77 +84,41 @@ const HelpInformation: FC = () => {
<Link target="_blank" href="https://discord.gg/3J3GgnzpyT" color="primary">
{'Discord'}
</Link>
&nbsp;server
&nbsp;server.
</ListItemText>
</ListItem>

<ListItem>
<ListItemAvatar>
<GitHubIcon />
</ListItemAvatar>

<ListItemText>
To report an issue or request a feature, please&nbsp;
<Link component="button" variant="body1" onClick={() => callAPI('info')}>
download
</Link>
&nbsp;the debug information and include in a new&nbsp;
Submit a&nbsp;
<Link target="_blank" href="https://github.com/emsesp/EMS-ESP32/issues/new/choose" color="primary">
GitHub issue
support issue
</Link>
&nbsp;for requesting a new feature or reporting a bug.
<br />
Make sure you also&nbsp;
<Button startIcon={<DownloadIcon />} variant="outlined" color="primary" onClick={() => callAPI('info')}>
download
</Button>
&nbsp; and attach your system details for a faster response.
</ListItemText>
</ListItem>
</List>

{me.admin && (
<>
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
Download Settings
</Typography>
<Box color="warning.main">
<Typography variant="body2">
Export the application settings and any customizations to a JSON file. These files can later be uploaded
via System&rarr;Upload.
</Typography>
</Box>
<Box sx={{ display: 'flex' }}>
<ButtonRow>
<Button
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => downloadSettings()}
>
settings
</Button>
<Button
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => downloadCustomizations()}
>
customizations
</Button>
</ButtonRow>
</Box>
<MessageBox
my={2}
level="warning"
message="Be careful when sharing your Settings as the file contains passwords and other sensitive system
information!"
/>
</>
)}

<Box bgcolor="secondary.info" border={1} p={1} mt={4}>
<Typography align="center" variant="h6">
EMS-ESP is a free and open-source project.
<br></br>Please consider supporting us by giving it a&nbsp;
<StarIcon style={{ fontSize: 16, color: '#fdff3a', verticalAlign: 'middle' }} /> on&nbsp;
<Box border={1} p={1} mt={4}>
<Typography align="center" variant="h6" color="orange">
EMS-ESP will always be a free and open-source project
<br></br>Please consider supporting it with a&nbsp;
<StarIcon style={{ fontSize: 16, color: 'yellow', verticalAlign: 'middle' }} /> on&nbsp;
<Link href="https://github.com/emsesp/EMS-ESP32" color="primary">
{'GitHub'}
</Link>
&nbsp;!
</Typography>
<Typography align="center">@proddy @MichaelDvP</Typography>
</Box>
</SectionContent>
);
Expand Down

0 comments on commit 4420ae3

Please sign in to comment.