WIP Code Cleanup for document upload. BOD-420

This commit is contained in:
Patrick Fic
2020-09-30 07:58:37 -07:00
parent 456ec10942
commit c68835153f
4 changed files with 204 additions and 183 deletions

View File

@@ -1,20 +1,47 @@
import { UploadOutlined } from "@ant-design/icons";
import { Button, Upload } from "antd";
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
import { handleUpload } from "./documents-upload.utility";
export default function DocumentsUploadComponent({ handleUpload, UploadRef }) {
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
bodyshop: selectBodyshop,
});
export function DocumentsUploadComponent({
currentUser,
bodyshop,
jobId,
tagsArray,
billId,
callbackAfterUpload,
}) {
return (
<div>
<Upload
multiple={true}
customRequest={handleUpload}
accept="audio/*,video/*,image/*"
ref={UploadRef}
>
<Button>
<UploadOutlined /> Click to Upload
</Button>
</Upload>
</div>
<Upload
multiple={true}
customRequest={(ev) =>
handleUpload(ev, {
bodyshop: bodyshop,
uploaded_by: currentUser.email,
jobId: jobId,
billId: billId,
tagsArray: tagsArray,
callback: callbackAfterUpload,
})
}
accept="audio/*,video/*,image/*"
showUploadList={false}
>
<Button type="primary">
<UploadOutlined />
</Button>
</Upload>
);
}
export default connect(mapStateToProps, null)(DocumentsUploadComponent);

View File

@@ -1,41 +0,0 @@
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
import DocumentsUploadComponent from "./documents-upload.component";
import { handleUpload } from "./documents-upload.utility";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
bodyshop: selectBodyshop,
});
export function DocumentsUploadContainer({
jobId,
tagsArray,
billId,
currentUser,
bodyshop,
callbackAfterUpload,
onChange,
}) {
return (
<DocumentsUploadComponent
handleUpload={(ev) =>
handleUpload(ev, {
bodyshop: bodyshop,
uploaded_by: currentUser.email,
jobId: jobId,
billId: billId,
tagsArray: tagsArray,
callback: callbackAfterUpload,
})
}
/>
);
}
export default connect(mapStateToProps, null)(DocumentsUploadContainer);

View File

@@ -12,7 +12,7 @@ var cleanAxios = axios.create();
cleanAxios.interceptors.request.eject(axiosAuthInterceptorId);
export const handleUpload = (ev, context) => {
console.log("ev", ev);
console.log("Handling Upload", ev);
logImEXEvent("document_upload", { filetype: ev.file.type });
@@ -22,43 +22,53 @@ export const handleUpload = (ev, context) => {
//If JPEG, resize and upload.
//TODO If this is just an invoice job? Where to put it?
let key = `${bodyshop.id}/${jobId}/${ev.file.name}`;
if (ev.file.type.includes("image")) {
Resizer.imageFileResizer(
ev.file,
2500,
2500,
"JPEG",
75,
0,
(uri) => {
let file = new File([uri], ev.file.name, {});
file.uid = ev.file.uid;
uploadToS3(
key,
file.type,
file,
onError,
onSuccess,
onProgress,
context
);
},
"blob"
);
} else {
uploadToS3(
key,
ev.file.type,
ev.file,
onError,
onSuccess,
onProgress,
context
);
}
uploadToCloudinary(
key,
ev.file.type,
ev.file,
onError,
onSuccess,
onProgress,
context
);
// if (ev.file.type.includes("image")) {
// Resizer.imageFileResizer(
// ev.file,
// 2500,
// 2500,
// "JPEG",
// 75,
// 0,
// (uri) => {
// let file = new File([uri], ev.file.name, {});
// file.uid = ev.file.uid;
// uploadToCloudinary(
// key,
// file.type,
// file,
// onError,
// onSuccess,
// onProgress,
// context
// );
// },
// "blob"
// );
// } else {
// uploadToCloudinary(
// key,
// ev.file.type,
// ev.file,
// onError,
// onSuccess,
// onProgress,
// context
// );
// }
};
export const uploadToS3 = (
export const uploadToCloudinary = async (
fileName,
fileType,
file,
@@ -69,92 +79,115 @@ export const uploadToS3 = (
) => {
const { bodyshop, jobId, billId, uploaded_by, callback, tagsArray } = context;
//Set variables for getting the signed URL.
let timestamp = Math.floor(Date.now() / 1000);
let public_id = fileName;
let tags = `${bodyshop.textid},${
tagsArray ? tagsArray.map((tag) => `${tag},`) : ""
}`;
let eager = process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS;
axios
.post("/media/sign", {
eager: eager,
public_id: public_id,
tags: tags,
timestamp: timestamp,
})
.then((response) => {
var signature = response.data;
var options = {
headers: { "X-Requested-With": "XMLHttpRequest" },
onUploadProgress: (e) => {
if (!!onProgress) onProgress({ percent: (e.loaded / e.total) * 100 });
},
};
const formData = new FormData();
formData.append("file", file);
formData.append("eager", eager);
formData.append("api_key", process.env.REACT_APP_CLOUDINARY_API_KEY);
formData.append("public_id", public_id);
formData.append("tags", tags);
formData.append("timestamp", timestamp);
formData.append("signature", signature);
cleanAxios
.post(`${process.env.REACT_APP_CLOUDINARY_ENDPOINT}/upload`, formData, {
...options,
})
.then((response) => {
console.log("Upload Response", response);
client
.mutate({
mutation: INSERT_NEW_DOCUMENT,
variables: {
docInput: [
{
jobid: jobId,
uploaded_by: uploaded_by,
key: fileName,
billid: billId,
type: fileType,
},
],
},
})
.then((r) => {
if (!!onSuccess)
onSuccess({
uid: r.data.insert_documents.returning[0].id,
name: r.data.insert_documents.returning[0].name,
status: "done",
key: r.data.insert_documents.returning[0].key,
});
notification["success"]({
message: i18n.t("documents.successes.insert"),
});
if (callback) {
callback();
}
// if (onChange) {
// //Used in a form.
// onChange(UploadRef.current.state.fileList);
// }
});
})
.catch((error) => {
if (!!onError) onError(error);
notification["error"]({
message: i18n.t("documents.errors.insert", {
message: JSON.stringify(error),
}),
});
});
})
.catch((error) => {
console.log("error", error);
notification["error"]({
message: i18n.t("documents.errors.getpresignurl", {
message: JSON.stringify(error),
}),
});
//Get the signed url.
const signedURLResponse = await axios.post("/media/sign", {
eager: eager,
public_id: public_id,
tags: tags,
timestamp: timestamp,
});
if (signedURLResponse.status !== 200) {
console.log("Error Getting Signed URL", signedURLResponse.statusText);
if (!!onError) onError(signedURLResponse.statusText);
notification["error"]({
message: i18n.t("documents.errors.getpresignurl", {
message: signedURLResponse.statusText,
}),
});
return;
}
//Build request to end to cloudinary.
var signature = signedURLResponse.data;
var options = {
headers: { "X-Requested-With": "XMLHttpRequest" },
onUploadProgress: (e) => {
if (!!onProgress) onProgress({ percent: (e.loaded / e.total) * 100 });
},
};
const formData = new FormData();
formData.append("file", file);
formData.append("eager", eager);
formData.append("api_key", process.env.REACT_APP_CLOUDINARY_API_KEY);
formData.append("public_id", public_id);
formData.append("tags", tags);
formData.append("timestamp", timestamp);
formData.append("signature", signature);
//Upload request to Cloudinary
const cloudinaryUploadResponse = await cleanAxios.post(
`${process.env.REACT_APP_CLOUDINARY_ENDPOINT}/upload`,
formData,
{
...options,
}
);
console.log("Upload Response", cloudinaryUploadResponse.data);
if (cloudinaryUploadResponse.status !== 200) {
console.log(
"Error uploading to cloudinary.",
cloudinaryUploadResponse.statusText
);
if (!!onError) onError(cloudinaryUploadResponse.statusText);
notification["error"]({
message: i18n.t("documents.errors.insert", {
message: cloudinaryUploadResponse.statusText,
}),
});
return;
}
//Insert the document with the matching key.
const documentInsert = await client.mutate({
mutation: INSERT_NEW_DOCUMENT,
variables: {
docInput: [
{
jobid: jobId,
uploaded_by: uploaded_by,
key: fileName,
billid: billId,
type: fileType,
},
],
},
});
if (!documentInsert.errors) {
if (!!onSuccess)
onSuccess({
uid: documentInsert.data.insert_documents.returning[0].id,
name: documentInsert.data.insert_documents.returning[0].name,
status: "done",
key: documentInsert.data.insert_documents.returning[0].key,
});
notification["success"]({
message: i18n.t("documents.successes.insert"),
});
if (callback) {
callback();
}
} else {
if (!!onError) onError(JSON.stringify(documentInsert.errors));
notification["error"]({
message: i18n.t("documents.errors.insert", {
message: JSON.stringify(JSON.stringify(documentInsert.errors)),
}),
});
return;
}
// if (onChange) {
// //Used in a form.
// onChange(UploadRef.current.state.fileList);
// }
};

View File

@@ -1,6 +1,7 @@
import { Space } from "antd";
import React, { useEffect, useState } from "react";
import Gallery from "react-grid-gallery";
import DocumentsUploadContainer from "../documents-upload/documents-upload.container";
import DocumentsUploadComponent from "../documents-upload/documents-upload.component";
import JobsDocumentsDownloadButton from "./jobs-document-gallery.download.component";
import JobsDocumentsDeleteButton from "./jobs-documents-gallery.delete.component";
@@ -35,18 +36,19 @@ function JobsDocumentsComponent({
return (
<div className="clearfix">
<DocumentsUploadContainer
jobId={jobId}
billId={billId}
callbackAfterUpload={billsCallback || refetch}
tagsArray={["test"]}
/>
<JobsDocumentsDownloadButton galleryImages={galleryImages} />
<JobsDocumentsDeleteButton
galleryImages={galleryImages}
deletionCallback={billsCallback || refetch}
/>
<Space>
<DocumentsUploadComponent
jobId={jobId}
billId={billId}
callbackAfterUpload={billsCallback || refetch}
tagsArray={["test"]}
/>
<JobsDocumentsDownloadButton galleryImages={galleryImages} />
<JobsDocumentsDeleteButton
galleryImages={galleryImages}
deletionCallback={billsCallback || refetch}
/>
</Space>
<Gallery
images={galleryImages}