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 DownloadIcon from "@mui/icons-material/Download";
|
||||
import FileUploadIcon from "@mui/icons-material/FileUpload";
|
||||
@ -16,6 +18,7 @@ import {
|
||||
import { filesize } from "filesize";
|
||||
import React from "react";
|
||||
import { OTAAPI, OTAUpdate } from "../api/OTAApi";
|
||||
import { DeployOTAUpdateDialogProvider } from "../dialogs/DeployOTAUpdateDialogProvider";
|
||||
import { UploadUpdateDialog } from "../dialogs/UploadUpdateDialog";
|
||||
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
||||
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
|
||||
@ -110,6 +113,10 @@ function _OTAList(p: {
|
||||
const loadingMessage = useLoadingMessage();
|
||||
const snackbar = useSnackbar();
|
||||
|
||||
const [deployUpdate, setDeployUpdate] = React.useState<
|
||||
OTAUpdate | undefined
|
||||
>();
|
||||
|
||||
const deleteUpdate = async (update: OTAUpdate) => {
|
||||
if (
|
||||
!(await confirm(
|
||||
@ -135,40 +142,53 @@ function _OTAList(p: {
|
||||
};
|
||||
|
||||
return (
|
||||
<TableContainer component={Paper}>
|
||||
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell align="center">Platform</TableCell>
|
||||
<TableCell align="center">Version</TableCell>
|
||||
<TableCell align="center">File size</TableCell>
|
||||
<TableCell align="center"></TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{p.list.map((row, num) => (
|
||||
<TableRow hover key={num}>
|
||||
<TableCell align="center">{row.platform}</TableCell>
|
||||
<TableCell align="center">{row.version}</TableCell>
|
||||
<TableCell align="center">{filesize(row.file_size)}</TableCell>
|
||||
<TableCell align="center">
|
||||
<Tooltip title="Download a copy of the firmware">
|
||||
<RouterLink to={OTAAPI.DownloadOTAUpdateURL(row)}>
|
||||
<IconButton>
|
||||
<DownloadIcon />
|
||||
</IconButton>
|
||||
</RouterLink>
|
||||
</Tooltip>
|
||||
<Tooltip title="Delete firmware update">
|
||||
<IconButton onClick={() => deleteUpdate(row)}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
<>
|
||||
{deployUpdate && (
|
||||
<DeployOTAUpdateDialogProvider
|
||||
update={deployUpdate!}
|
||||
onClose={() => setDeployUpdate(undefined)}
|
||||
/>
|
||||
)}
|
||||
<TableContainer component={Paper}>
|
||||
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell align="center">Platform</TableCell>
|
||||
<TableCell align="center">Version</TableCell>
|
||||
<TableCell align="center">File size</TableCell>
|
||||
<TableCell align="center"></TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{p.list.map((row, num) => (
|
||||
<TableRow hover key={num}>
|
||||
<TableCell align="center">{row.platform}</TableCell>
|
||||
<TableCell align="center">{row.version}</TableCell>
|
||||
<TableCell align="center">{filesize(row.file_size)}</TableCell>
|
||||
<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">
|
||||
<RouterLink to={OTAAPI.DownloadOTAUpdateURL(row)}>
|
||||
<IconButton>
|
||||
<DownloadIcon />
|
||||
</IconButton>
|
||||
</RouterLink>
|
||||
</Tooltip>
|
||||
<Tooltip title="Delete firmware update">
|
||||
<IconButton onClick={() => deleteUpdate(row)}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user