139 lines
3.4 KiB
JavaScript
139 lines
3.4 KiB
JavaScript
import Typography from "@material-ui/core/Typography";
|
|
import { CheckCircle, Error, RadioButtonUnchecked } from "@material-ui/icons";
|
|
import clsx from "clsx";
|
|
import React, { useEffect, useState } from "react";
|
|
|
|
import CircularProgress from "../CircularProgress";
|
|
import s from "./Statuses";
|
|
|
|
const AwaitStatus = -1;
|
|
const ErrorStatus = -100;
|
|
const CompleteStatus = 100;
|
|
|
|
const PHASES = [
|
|
{
|
|
label: "Pending",
|
|
events: [s.Pending, s.Sent],
|
|
progress: () => CompleteStatus,
|
|
},
|
|
{
|
|
label: "Received",
|
|
events: [s.ManifestAccepted, s.ManifestReceived, s.ManifestRejected],
|
|
progress: (msg) => {
|
|
if (msg === s.ManifestRejected) return ErrorStatus;
|
|
return CompleteStatus;
|
|
},
|
|
},
|
|
{
|
|
label: "Precondition",
|
|
events: [s.PreconditionAwait, s.PreconditionSuceeded],
|
|
progress: () => CompleteStatus,
|
|
},
|
|
{
|
|
label: "Download",
|
|
events: [
|
|
s.Downloading,
|
|
s.DownloadStarted,
|
|
s.DownloadCompleted,
|
|
s.DownloadFailed,
|
|
s.PackageDownloadStarted,
|
|
],
|
|
progress: (msg, progress) => {
|
|
if (msg === s.DownloadFailed) return ErrorStatus;
|
|
return progress;
|
|
},
|
|
},
|
|
{
|
|
label: "Approved",
|
|
events: [s.PackageDownloadCompleted, s.InstallApprovalAwait],
|
|
progress: () => AwaitStatus,
|
|
},
|
|
{
|
|
label: "Install",
|
|
events: [
|
|
s.InstallApprovalReceived,
|
|
s.InstallStarted,
|
|
s.Installing,
|
|
s.InstallSucceeded,
|
|
s.InstallFailed,
|
|
s.RequirementsFailed,
|
|
s.InstallScheduled,
|
|
],
|
|
progress: (msg, progress) => {
|
|
if (msg === s.InstallFailed || msg === s.RequirementsFailed) return ErrorStatus;
|
|
if (msg === s.PackageInstallCompleted) return CompleteStatus;
|
|
return progress;
|
|
},
|
|
},
|
|
{
|
|
label: "Updated",
|
|
events: [s.ManifestSucceeded],
|
|
progress: (_msg, _progress) => CompleteStatus,
|
|
},
|
|
];
|
|
|
|
const Progress = ({ value, classes }) => {
|
|
if (value === 100)
|
|
return (
|
|
<CheckCircle
|
|
className={clsx(classes.progressIcon, classes.progressSuccess)}
|
|
/>
|
|
);
|
|
if (value >= 0) return <CircularProgress value={value} />;
|
|
if (value < -1)
|
|
return (
|
|
<Error className={clsx(classes.progressIcon, classes.progressError)} />
|
|
);
|
|
|
|
return <RadioButtonUnchecked className={classes.progressIcon} />;
|
|
};
|
|
|
|
const getProgress = (index, phase, progress) => {
|
|
if (index === phase) return progress;
|
|
if (index < phase) return CompleteStatus;
|
|
return -1;
|
|
};
|
|
|
|
const CarUpdateStatus = ({ status, classes }) => {
|
|
const [phase, setPhase] = useState(0);
|
|
const [progress, setProgress] = useState(-1);
|
|
|
|
useEffect(() => {
|
|
if (!status) return;
|
|
|
|
for (let i = 0, len = PHASES.length; i < len; i++) {
|
|
const PHASE = PHASES[i];
|
|
if (PHASE.events.indexOf(status.msg) > -1) {
|
|
setPhase(i);
|
|
setProgress(PHASE.progress(status.msg, status.progress));
|
|
break;
|
|
}
|
|
}
|
|
}, [status]);
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
width: "100%",
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
flexWrap: "wrap",
|
|
}}
|
|
>
|
|
{PHASES.map((item, index) => {
|
|
return (
|
|
<div key={index} className={classes.textCenterAlign}>
|
|
<Progress
|
|
value={getProgress(index, phase, progress)}
|
|
classes={classes}
|
|
/>
|
|
<Typography>{item.label}</Typography>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CarUpdateStatus;
|