Files
SolarEnergy/central_frontend/src/dialogs/UploadUpdateDialog.tsx

133 lines
3.5 KiB
TypeScript

import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
FormControl,
InputLabel,
MenuItem,
Select,
styled,
} from "@mui/material";
import React from "react";
import { OTAAPI } from "../api/OTAApi";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
import { checkVersion } from "../utils/StringsUtils";
import { TextInput } from "../widgets/forms/TextInput";
const VisuallyHiddenInput = styled("input")({
clip: "rect(0 0 0 0)",
clipPath: "inset(50%)",
height: 1,
overflow: "hidden",
position: "absolute",
bottom: 0,
left: 0,
whiteSpace: "nowrap",
width: 1,
});
export function UploadUpdateDialog(p: {
platforms: string[];
onClose: () => void;
onCreated: () => void;
}): React.ReactElement {
const alert = useAlert();
const snackbar = useSnackbar();
const loadingMessage = useLoadingMessage();
const [platform, setPlatform] = React.useState<string | undefined>();
const [version, setVersion] = React.useState<string | undefined>();
const [file, setFile] = React.useState<File | undefined>();
const canSubmit = platform && version && checkVersion(version) && file;
const upload = async () => {
try {
loadingMessage.show("Uploading firmware...");
await OTAAPI.UploadFirmware(platform!, version!, file!);
snackbar("Successfully uploaded new firmware!");
p.onCreated();
} catch (e) {
console.error(e);
alert(`Failed to upload firmware: ${e}`);
} finally {
loadingMessage.hide();
}
};
return (
<Dialog open={true} onClose={p.onClose}>
<DialogTitle>Submit a new update</DialogTitle>
<DialogContent>
<DialogContentText>
You can upload a new firmware using this form.
</DialogContentText>
<br />
<FormControl fullWidth>
<InputLabel>Platform</InputLabel>
<Select
label="Platform"
value={platform}
onChange={(e) => setPlatform(e.target.value)}
variant="standard"
>
{p.platforms.map((p) => (
<MenuItem key={p} value={p}>
{p}
</MenuItem>
))}
</Select>
</FormControl>
<br />
<br />
<TextInput
editable
label="Version"
helperText="The version shall follow semantics requirements"
value={version}
onValueChange={setVersion}
checkValue={checkVersion}
/>
<br />
<Button
fullWidth
component="label"
role={undefined}
variant={file ? "contained" : "outlined"}
tabIndex={-1}
startIcon={<CloudUploadIcon />}
>
Upload file
<VisuallyHiddenInput
type="file"
onChange={(event) =>
setFile(
(event.target.files?.length ?? 0) > 0
? event.target.files![0]
: undefined
)
}
multiple
/>
</Button>
</DialogContent>
<DialogActions>
<Button onClick={p.onClose}>Cancel</Button>
<Button type="submit" disabled={!canSubmit} onClick={upload}>
Upload
</Button>
</DialogActions>
</Dialog>
);
}