133 lines
3.5 KiB
TypeScript
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>
|
|
);
|
|
}
|