234 lines
7.2 KiB
JavaScript
234 lines
7.2 KiB
JavaScript
import { Button, FormControlLabel, Grid, Switch, Typography } from "@material-ui/core";
|
|
import SendIcon from "@material-ui/icons/Send";
|
|
import React, { useEffect, useState } from "react";
|
|
import { Redirect, useParams } from "react-router";
|
|
|
|
import { logger } from "../../../services/monitoring";
|
|
import { LocalDateTimeString } from "../../../utils/dates";
|
|
import { Permissions } from "../../../utils/roles";
|
|
import { CarUpdatesProvider, SELECT_VERSION, useCarUpdatesContext } from "../../Contexts/CarUpdatesContext";
|
|
import { FleetProvider } from "../../Contexts/FleetContext";
|
|
import { ManifestsProvider, useManifestsContext } from "../../Contexts/ManifestsContext";
|
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
|
import { useUserContext } from "../../Contexts/UserContext";
|
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
|
import CarSelectionTable from "../../Controls/CarSelectionTable";
|
|
import { DropDownList } from "../../Controls/DropDownList";
|
|
import FleetSelectionTable from "../../Controls/FleetSelectionTable";
|
|
import { RoleWrap } from "../../Controls/RoleWrap";
|
|
import SearchField from "../../Controls/SearchField";
|
|
import useStyles from "../../useStyles";
|
|
|
|
const CAR_UPDATE = false;
|
|
const FLEET_UPDATE = true;
|
|
|
|
const MainForm = () => {
|
|
const [updateType, setUpdateType] = useState(CAR_UPDATE);
|
|
const {manifest_id} = useParams();
|
|
const {getManifests, manifests, busy} = useManifestsContext();
|
|
const {deployCarUpdates, deployFleetUpdates, getSUMSVersions, versions, updateSUMSVersion} = useCarUpdatesContext();
|
|
const {
|
|
groups,
|
|
providers,
|
|
token: {
|
|
idToken: {jwtToken: token},
|
|
},
|
|
} = useUserContext();
|
|
const {setMessage, setTitle, setSitePath} = useStatusContext();
|
|
const [manifestName, setManifestName] = useState("");
|
|
const [version, setVersion] = useState("");
|
|
const [sumsVersion, setSUMSersion] = useState("");
|
|
const [createDate, setCreateDate] = useState("");
|
|
const [selected, setSelected] = useState([]);
|
|
const [search, setSearch] = useState("");
|
|
const [softwareVersion, setSoftwareVersion] = useState(SELECT_VERSION);
|
|
const [redirect, setRedirect] = useState("");
|
|
const classes = useStyles();
|
|
|
|
const handleChange = (_) => {
|
|
setSelected([]);
|
|
setUpdateType(updateType === CAR_UPDATE ? FLEET_UPDATE : CAR_UPDATE);
|
|
}
|
|
|
|
const handleSearch = (query) => {
|
|
setSelected([]);
|
|
setSearch(query);
|
|
};
|
|
|
|
const handleSelectAll = (cars) => {
|
|
setSelected(cars);
|
|
};
|
|
|
|
const handleSelect = (event, key) => {
|
|
try {
|
|
let newSelected;
|
|
if (event.target.checked) {
|
|
newSelected = [...selected];
|
|
newSelected.push(key);
|
|
} else {
|
|
newSelected = selected.filter((vinOrName) => vinOrName !== key);
|
|
}
|
|
setSelected(newSelected);
|
|
} catch (e) {
|
|
logger.warn(e.stack);
|
|
}
|
|
};
|
|
|
|
const onSubmit = async (event) => {
|
|
try {
|
|
event.preventDefault();
|
|
const data = {
|
|
manifest_id: parseInt(manifest_id),
|
|
}
|
|
if (sumsVersion.length === 0) {
|
|
await updateSUMSVersion(manifest_id, softwareVersion, token);
|
|
}
|
|
|
|
if (updateType === CAR_UPDATE) {
|
|
data.vins = selected;
|
|
await deployCarUpdates(data, token);
|
|
} else {
|
|
data.fleet_names = selected;
|
|
await deployFleetUpdates(data, token);
|
|
}
|
|
setMessage(
|
|
`Deployed ${manifestName} ${version} to ${selected.length} cars`
|
|
);
|
|
setRedirect(`/package-status/${manifest_id}`);
|
|
} catch (e) {
|
|
setMessage(e.message);
|
|
logger.warn(e.stack);
|
|
}
|
|
};
|
|
|
|
const getData = async () => {
|
|
try {
|
|
await getManifests({id: parseInt(manifest_id)}, token);
|
|
await getSUMSVersions(token);
|
|
} catch (e) {
|
|
setMessage(e.message);
|
|
logger.warn(e.stack);
|
|
}
|
|
};
|
|
|
|
const changeVersion = (e) => {
|
|
setSoftwareVersion(e.target.value);
|
|
}
|
|
|
|
useEffect(() => {
|
|
getData();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [token]);
|
|
|
|
useEffect(() => {
|
|
const title = `Deploy ${manifestName} ${version}`;
|
|
setTitle(title);
|
|
setSitePath([
|
|
{
|
|
label: "Deployments",
|
|
link: "/packages",
|
|
},
|
|
{
|
|
label: title,
|
|
},
|
|
]);
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [manifestName, version]);
|
|
|
|
useEffect(() => {
|
|
if (!manifests || manifests.length === 0) return;
|
|
const data = manifests[0];
|
|
|
|
setManifestName(data.name);
|
|
setVersion(data.version);
|
|
setSUMSersion(data.sums || "");
|
|
setCreateDate(LocalDateTimeString(data.created));
|
|
}, [manifests]);
|
|
|
|
if (redirect.length > 0) {
|
|
return <Redirect to={redirect}/>;
|
|
}
|
|
|
|
return (
|
|
<div className={classes.paper}>
|
|
<form className={classes.form} noValidate action="{onSubmit}">
|
|
<Typography variant="body2">Created {createDate}.</Typography>
|
|
<Grid container className={classes.root} spacing={2}>
|
|
<Grid item md={2}>
|
|
<div
|
|
className={classes.labelInline}
|
|
>{`${selected.length} Selected`}</div>
|
|
</Grid>
|
|
<Grid item md={2} className={classes.textCenterAlign}>
|
|
<RoleWrap
|
|
groups={groups}
|
|
providers={providers}
|
|
rolesPerProvider={Permissions.FiskerRead}
|
|
>
|
|
<FormControlLabel control={<Switch
|
|
checked={updateType === CAR_UPDATE}
|
|
onChange={handleChange}
|
|
inputProps={{'aria-label': 'controlled'}}
|
|
/>} label="Car(default) or Fleet"/>
|
|
</RoleWrap>
|
|
</Grid>
|
|
<Grid item md={4} className={classes.textCenterAlign}>
|
|
<SearchField classes={classes} onSearch={handleSearch}/>
|
|
</Grid>
|
|
<Grid item md={4} container justifyContent="flex-end">
|
|
{sumsVersion.length === 0 &&
|
|
<DropDownList
|
|
label="Software Version"
|
|
labelField="version"
|
|
valueField="version"
|
|
value={softwareVersion}
|
|
data={versions}
|
|
classes={classes}
|
|
onChange={changeVersion} />
|
|
}
|
|
<Button
|
|
type="submit"
|
|
disabled={busy || selected.length === 0 || (sumsVersion.length === 0 && softwareVersion === SELECT_VERSION)}
|
|
color="primary"
|
|
onClick={onSubmit}
|
|
>
|
|
<SendIcon />
|
|
</Button>
|
|
</Grid>
|
|
</Grid>
|
|
{updateType === CAR_UPDATE ?
|
|
<VehicleProvider>
|
|
<CarSelectionTable
|
|
classes={classes}
|
|
token={token}
|
|
multiSelect={true}
|
|
search={{search}}
|
|
selected={selected}
|
|
onSelect={handleSelect}
|
|
onSelectAll={handleSelectAll}
|
|
/></VehicleProvider> :
|
|
<FleetProvider>
|
|
<FleetSelectionTable
|
|
classes={classes}
|
|
token={token}
|
|
multiSelect={true}
|
|
search={{search}}
|
|
selected={selected}
|
|
onSelect={handleSelect}
|
|
onSelectAll={handleSelectAll}/>
|
|
</FleetProvider>
|
|
}
|
|
</form>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const ManifestDeployForm = () => (
|
|
<ManifestsProvider>
|
|
<CarUpdatesProvider>
|
|
<MainForm/>
|
|
</CarUpdatesProvider>
|
|
</ManifestsProvider>
|
|
);
|
|
|
|
export default ManifestDeployForm; |