CEC-377 Create multi-file updates (#71)
* Replace Deploy Package with Deploy Manifest page Stub new controls for package files * Add Release notes and ECU FIles to Create Manifest * Add Release notes and ECU FIles to Create Manifest * Oops * Replace multi release notes with single url * Implement multiple file uploads and progress * Update snapshots * Unused import * Move file to end of form Update progress layout
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
|
||||
import api from "../../services/manifests";
|
||||
import { uploadFile, getCancelToken } from "../../services/uploadFile";
|
||||
|
||||
const ManifestsContext = React.createContext();
|
||||
|
||||
export const ManifestsProvider = ({ children }) => {
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [uploadProgress, setUploadProgress] = useState(0);
|
||||
const [uploadStatus, setUploadStatus] = useState(null);
|
||||
const [cancelUploadToken, setCancelUploadToken] = useState(null);
|
||||
const [uploadFileIndex, setUploadFileIndex] = useState(0);
|
||||
const [uploadedFiles, setUploadedFiles] = useState([]);
|
||||
const [manifests, setManifests] = useState([]);
|
||||
const [totalManifests, setTotalManifests] = useState(0);
|
||||
|
||||
@@ -48,14 +54,153 @@ export const ManifestsProvider = ({ children }) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
const validateManifest = (data, accessToken) => {
|
||||
const fileKeys = {};
|
||||
|
||||
if (!accessToken || accessToken.length === 0) {
|
||||
throw new Error("Access token required");
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
throw new Error("Missing manifest data");
|
||||
}
|
||||
|
||||
if (!data.name || data.name.length === 0) {
|
||||
throw new Error("Package name required");
|
||||
}
|
||||
|
||||
if (!data.version || data.version.length === 0) {
|
||||
throw new Error("Package version required");
|
||||
}
|
||||
|
||||
if (!data.description || data.description.length === 0) {
|
||||
throw new Error("Package description required");
|
||||
}
|
||||
|
||||
if (!data.releasenotes || data.releasenotes.length === 0) {
|
||||
throw new Error("Package release notes link required");
|
||||
}
|
||||
|
||||
if (!data.files || data.files.length === 0) {
|
||||
throw new Error("Package files required");
|
||||
}
|
||||
|
||||
data.files.forEach((file) => validateFile(file, fileKeys));
|
||||
};
|
||||
|
||||
const validateFile = (file, keys) => {
|
||||
if (!file) {
|
||||
throw new Error("File data required");
|
||||
}
|
||||
|
||||
if (!file.filename || file.filename.length === 0) {
|
||||
throw new Error("Filename required");
|
||||
}
|
||||
|
||||
if (!file.name || file.name.length === 0) {
|
||||
throw new Error(`${file.filename} ECU name required`);
|
||||
}
|
||||
|
||||
if (!file.update_version || file.update_version.length === 0) {
|
||||
throw new Error(`${file.filename} version required`);
|
||||
}
|
||||
|
||||
if (!file.part_number || file.part_number.length === 0) {
|
||||
throw new Error(`${file.filename} part number required`);
|
||||
}
|
||||
|
||||
const key = `${file.name}, ${file.update_version}, ${file.filename}`;
|
||||
if (!keys[key]) {
|
||||
keys[key] = true;
|
||||
} else {
|
||||
throw new Error(`${key} already exists`);
|
||||
}
|
||||
};
|
||||
|
||||
const createManifest = async (data, token) => {
|
||||
let result;
|
||||
|
||||
try {
|
||||
setBusy(true);
|
||||
validateManifest(data, token);
|
||||
setUploadedFiles(data.files);
|
||||
|
||||
result = await api.createManifest(data, token);
|
||||
if (result.error)
|
||||
throw new Error(`Create manifest error. ${result.message}`);
|
||||
|
||||
for (let i = 0, len = data.files.length; i < len; i++) {
|
||||
setUploadFileIndex(i);
|
||||
const resp = await uploadECUFile(result.id, data.files[i], token);
|
||||
if (resp.error)
|
||||
throw new Error(`Upload manifest file error. ${resp.error}`);
|
||||
}
|
||||
} finally {
|
||||
setBusy(false);
|
||||
setUploadFileIndex(0);
|
||||
setUploadedFiles([]);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const cancelUpload = () => {
|
||||
if (cancelUploadToken) cancelUploadToken.cancel();
|
||||
setBusy(false);
|
||||
setUploadStatus("Upload cancelled");
|
||||
setCancelUploadToken(null);
|
||||
setUploadProgress(0);
|
||||
};
|
||||
|
||||
const uploadECUFile = async (manifest_id, data, accessToken) => {
|
||||
try {
|
||||
Object.assign(data, { manifest_id });
|
||||
|
||||
const filename = data.file.name;
|
||||
const cancel = getCancelToken();
|
||||
|
||||
setBusy(true);
|
||||
setUploadProgress(0);
|
||||
setUploadStatus(`Uploading ${filename}`);
|
||||
setCancelUploadToken(cancel);
|
||||
|
||||
const result = await uploadFile(
|
||||
data,
|
||||
accessToken,
|
||||
setUploadProgress,
|
||||
cancel.token
|
||||
);
|
||||
if (result.message) {
|
||||
throw new Error(`${result.error}. ${result.message}`);
|
||||
}
|
||||
setUploadStatus(`Uploaded ${filename}`);
|
||||
setCancelUploadToken(null);
|
||||
setUploadProgress(100);
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
setBusy(false);
|
||||
setUploadStatus(`Error occured: ${e.message}`);
|
||||
setUploadProgress(-1);
|
||||
|
||||
return { error: e.message };
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ManifestsContext.Provider
|
||||
value={{
|
||||
busy,
|
||||
uploadProgress,
|
||||
uploadStatus,
|
||||
uploadFileIndex,
|
||||
uploadedFiles,
|
||||
manifests,
|
||||
totalManifests,
|
||||
getManifests,
|
||||
deleteManifest,
|
||||
createManifest,
|
||||
cancelUpload,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user