CEC-4499: add bulk update configs support (#357)

* add taskRunner util

* add bulk update config flow
This commit is contained in:
Tristan Timblin
2023-06-14 13:53:32 -04:00
committed by GitHub
parent a68c00b4ad
commit de1a5dcd2d
11 changed files with 621 additions and 7 deletions

View File

@@ -7,19 +7,31 @@ import { Link } from "react-router-dom";
import { Permissions } from "../../../utils/roles";
import { useStatusContext } from "../../Contexts/StatusContext";
import { useUserContext } from "../../Contexts/UserContext";
import { VehicleProvider } from "../../Contexts/VehicleContext";
import { VehicleProvider, VehicleContext } from "../../Contexts/VehicleContext";
import CarSelectionTable from "../../Controls/CarSelectionTable";
import OptionsDropdown from "../../Controls/OptionsDropdown";
import { RoleWrap } from "../../Controls/RoleWrap";
import SearchField from "../../Controls/SearchField";
import DropDownButton from "../../Controls/DropDownButton";
import TransformModal from "../../TransformModal";
import useStyles from "../../useStyles";
import TaskRunner from "../../../utils/taskRunner";
const MainForm = () => {
const classes = useStyles();
const [search, setSearch] = useState("");
const [online, setOnline] = useState(false);
const [onlineHMI, setOnlineHMI] = useState(false);
const { setTitle, setSitePath } = useStatusContext();
const [selectedVins, setSelectedVins] = useState([]);
const [config, setConfig] = useState({
force: {
label: "Force push",
type: "boolean",
value: false
},
})
const [showUpdateConfigModal, setShowUpdateConfigModal] = useState(false);
const { setTitle, setSitePath, setMessage } = useStatusContext();
const {
token: {
idToken: { jwtToken: token },
@@ -36,6 +48,45 @@ const MainForm = () => {
setOnline(event.target.checked);
};
const handleSelectAll = (cars) => {
setSelectedVins(cars);
};
const handleSelect = (event, key) => {
setSelectedVins((selectedVins) => {
if (event.target.checked) {
return [...selectedVins, key];
}
return selectedVins.filter(vin => vin !== key);
});
};
const handleUploadConfig = (fn) => {
const taskRunner = new TaskRunner(5);
const request = (vin, i) => {
const messagePrefix = `${i+1}/${selectedVins.length} "${vin}":`;
return async () => {
const result = await fn(vin, config.force.value, token)
.then(() => {
setMessage(`${messagePrefix} updated.`);
})
.catch((error) => {
setMessage(`${messagePrefix} ${error.message}`);
});
return result;
}
}
selectedVins.forEach((vin, i) => taskRunner.push(request(vin, i)))
}
const actions = [
{
name: "Update Configs",
disabled: selectedVins.length === 0,
trigger: () => setShowUpdateConfigModal(true),
},
];
const handleOnlineHMI = (event) => {
setOnlineHMI(event.target.checked);
};
@@ -49,7 +100,7 @@ const MainForm = () => {
return (
<div className={clsx(classes.paper, classes.tableSize)}>
<Grid container className={classes.root} spacing={2}>
<Grid item md={4} className={classes.textJustifyAlign}>
<Grid item md={4} className={clsx(classes.textJustifyAlign, classes.actionsBar)}>
<RoleWrap
groups={groups}
providers={providers}
@@ -59,11 +110,12 @@ const MainForm = () => {
<AddCircleIcon fontSize="large" />
</Link>
</RoleWrap>
<DropDownButton actions={actions} payload={[selectedVins]} />
</Grid>
<Grid item md={4} className={classes.textCenterAlign}>
<SearchField classes={classes} onSearch={handleSearch} />
</Grid>
<Grid item md={2} className={classes.textJustifyAlign}>
<Grid item md={2} className={clsx(classes.textJustifyAlign, classes.actionsBar)}>
<OptionsDropdown listId="filter-menu">
<MenuItem>
<FormControlLabel
@@ -86,13 +138,29 @@ const MainForm = () => {
<CarSelectionTable
classes={classes}
token={token}
multiSelect={false}
multiSelect
search={{
search,
online: online ? true : null,
online_hmi: onlineHMI ? true : null,
}}
selected={selectedVins}
onSelect={handleSelect}
onSelectAll={handleSelectAll}
/>
<VehicleContext.Consumer>
{(context) => (
<TransformModal
open={showUpdateConfigModal}
close={() => setShowUpdateConfigModal(false)}
title="Update Configs"
body={`You are updating the config for the following VINs: ${selectedVins.join(", ")}.`}
data={config}
setData={setConfig}
submit={() => handleUploadConfig(context.uploadConfig)}
/>
)}
</VehicleContext.Consumer>
</div>
);
};