Create the dialog to select the deployment target
This commit is contained in:
parent
e4da44b5ce
commit
386f0439e4
117
central_frontend/src/dialogs/DeployOTAUpdateDialogProvider.tsx
Normal file
117
central_frontend/src/dialogs/DeployOTAUpdateDialogProvider.tsx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogContentText,
|
||||||
|
DialogTitle,
|
||||||
|
FormControl,
|
||||||
|
FormControlLabel,
|
||||||
|
FormGroup,
|
||||||
|
FormLabel,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import React from "react";
|
||||||
|
import { Device, DeviceApi } from "../api/DeviceApi";
|
||||||
|
import { OTAUpdate } from "../api/OTAApi";
|
||||||
|
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||||
|
|
||||||
|
export function DeployOTAUpdateDialogProvider(p: {
|
||||||
|
update: OTAUpdate;
|
||||||
|
onClose: () => void;
|
||||||
|
}): React.ReactElement {
|
||||||
|
const [devicesList, setDevicesList] = React.useState<Device[] | undefined>();
|
||||||
|
|
||||||
|
const loadDevicesList = async () => {
|
||||||
|
let list = await DeviceApi.ValidatedList();
|
||||||
|
list = list.filter((e) => e.info.reference == p.update.platform);
|
||||||
|
setDevicesList(list);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [allDevices, setAllDevices] = React.useState(false);
|
||||||
|
const [selectedDevices, setSelectedDevices] = React.useState<string[]>([]);
|
||||||
|
|
||||||
|
const startDeployment = () => {};
|
||||||
|
return (
|
||||||
|
<Dialog open={true} onClose={p.onClose}>
|
||||||
|
<DialogTitle>
|
||||||
|
Deploy update <i>{p.update.version}</i> for platform{" "}
|
||||||
|
<i>{p.update.platform}</i>
|
||||||
|
</DialogTitle>
|
||||||
|
<AsyncWidget
|
||||||
|
loadKey={1}
|
||||||
|
load={loadDevicesList}
|
||||||
|
errMsg="Failed to load the list of devices!"
|
||||||
|
build={() => (
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText>
|
||||||
|
You can choose to deploy update to all device or to target only a
|
||||||
|
part of devices:
|
||||||
|
</DialogContentText>
|
||||||
|
|
||||||
|
<FormControl>
|
||||||
|
<FormLabel>Gender</FormLabel>
|
||||||
|
<RadioGroup
|
||||||
|
name="radio-buttons-group"
|
||||||
|
value={allDevices}
|
||||||
|
onChange={(v) => setAllDevices(v.target.value == "true")}
|
||||||
|
>
|
||||||
|
<FormControlLabel
|
||||||
|
value={true}
|
||||||
|
control={<Radio />}
|
||||||
|
label="Deploy the update to all the devices of the platform"
|
||||||
|
/>
|
||||||
|
<FormControlLabel
|
||||||
|
value={false}
|
||||||
|
control={<Radio />}
|
||||||
|
label="Deploy the update to a limited range of devices"
|
||||||
|
/>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
{!allDevices && (
|
||||||
|
<Typography>
|
||||||
|
There are no devices to which the update can be deployed.
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
{!allDevices && (
|
||||||
|
<FormGroup>
|
||||||
|
{devicesList?.map((d) => (
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
checked={selectedDevices.includes(d.id)}
|
||||||
|
onChange={(_e, v) => {
|
||||||
|
if (v) {
|
||||||
|
selectedDevices.push(d.id);
|
||||||
|
setSelectedDevices([...selectedDevices]);
|
||||||
|
} else
|
||||||
|
setSelectedDevices(
|
||||||
|
selectedDevices.filter((e) => e != d.id)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={d.name}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
</DialogContent>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={p.onClose}>Cancel</Button>
|
||||||
|
<Button
|
||||||
|
onClick={startDeployment}
|
||||||
|
autoFocus
|
||||||
|
disabled={!allDevices && selectedDevices.length == 0}
|
||||||
|
>
|
||||||
|
Start deployment
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import { mdiFolderUploadOutline } from "@mdi/js";
|
||||||
|
import Icon from "@mdi/react";
|
||||||
import DeleteIcon from "@mui/icons-material/Delete";
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
import DownloadIcon from "@mui/icons-material/Download";
|
import DownloadIcon from "@mui/icons-material/Download";
|
||||||
import FileUploadIcon from "@mui/icons-material/FileUpload";
|
import FileUploadIcon from "@mui/icons-material/FileUpload";
|
||||||
@ -16,6 +18,7 @@ import {
|
|||||||
import { filesize } from "filesize";
|
import { filesize } from "filesize";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { OTAAPI, OTAUpdate } from "../api/OTAApi";
|
import { OTAAPI, OTAUpdate } from "../api/OTAApi";
|
||||||
|
import { DeployOTAUpdateDialogProvider } from "../dialogs/DeployOTAUpdateDialogProvider";
|
||||||
import { UploadUpdateDialog } from "../dialogs/UploadUpdateDialog";
|
import { UploadUpdateDialog } from "../dialogs/UploadUpdateDialog";
|
||||||
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
||||||
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
|
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
|
||||||
@ -110,6 +113,10 @@ function _OTAList(p: {
|
|||||||
const loadingMessage = useLoadingMessage();
|
const loadingMessage = useLoadingMessage();
|
||||||
const snackbar = useSnackbar();
|
const snackbar = useSnackbar();
|
||||||
|
|
||||||
|
const [deployUpdate, setDeployUpdate] = React.useState<
|
||||||
|
OTAUpdate | undefined
|
||||||
|
>();
|
||||||
|
|
||||||
const deleteUpdate = async (update: OTAUpdate) => {
|
const deleteUpdate = async (update: OTAUpdate) => {
|
||||||
if (
|
if (
|
||||||
!(await confirm(
|
!(await confirm(
|
||||||
@ -135,6 +142,13 @@ function _OTAList(p: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{deployUpdate && (
|
||||||
|
<DeployOTAUpdateDialogProvider
|
||||||
|
update={deployUpdate!}
|
||||||
|
onClose={() => setDeployUpdate(undefined)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<TableContainer component={Paper}>
|
<TableContainer component={Paper}>
|
||||||
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
@ -152,6 +166,11 @@ function _OTAList(p: {
|
|||||||
<TableCell align="center">{row.version}</TableCell>
|
<TableCell align="center">{row.version}</TableCell>
|
||||||
<TableCell align="center">{filesize(row.file_size)}</TableCell>
|
<TableCell align="center">{filesize(row.file_size)}</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
|
<Tooltip title="Deploy the update to devices">
|
||||||
|
<IconButton onClick={() => setDeployUpdate(row)}>
|
||||||
|
<Icon path={mdiFolderUploadOutline} size={1} />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
<Tooltip title="Download a copy of the firmware">
|
<Tooltip title="Download a copy of the firmware">
|
||||||
<RouterLink to={OTAAPI.DownloadOTAUpdateURL(row)}>
|
<RouterLink to={OTAAPI.DownloadOTAUpdateURL(row)}>
|
||||||
<IconButton>
|
<IconButton>
|
||||||
@ -170,5 +189,6 @@ function _OTAList(p: {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user