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 { UploadOutlined } from "@ant-design/icons";
import { Button, Upload } from "antd"; import { Button, Upload } from "antd";
import React from "react"; 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 ( return (
<div> <Upload
<Upload multiple={true}
multiple={true} customRequest={(ev) =>
customRequest={handleUpload} handleUpload(ev, {
accept="audio/*,video/*,image/*" bodyshop: bodyshop,
ref={UploadRef} uploaded_by: currentUser.email,
> jobId: jobId,
<Button> billId: billId,
<UploadOutlined /> Click to Upload tagsArray: tagsArray,
</Button> callback: callbackAfterUpload,
</Upload> })
</div> }
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); cleanAxios.interceptors.request.eject(axiosAuthInterceptorId);
export const handleUpload = (ev, context) => { export const handleUpload = (ev, context) => {
console.log("ev", ev); console.log("Handling Upload", ev);
logImEXEvent("document_upload", { filetype: ev.file.type }); logImEXEvent("document_upload", { filetype: ev.file.type });
@@ -22,43 +22,53 @@ export const handleUpload = (ev, context) => {
//If JPEG, resize and upload. //If JPEG, resize and upload.
//TODO If this is just an invoice job? Where to put it? //TODO If this is just an invoice job? Where to put it?
let key = `${bodyshop.id}/${jobId}/${ev.file.name}`; let key = `${bodyshop.id}/${jobId}/${ev.file.name}`;
if (ev.file.type.includes("image")) { uploadToCloudinary(
Resizer.imageFileResizer( key,
ev.file, ev.file.type,
2500, ev.file,
2500, onError,
"JPEG", onSuccess,
75, onProgress,
0, context
(uri) => { );
let file = new File([uri], ev.file.name, {});
file.uid = ev.file.uid; // if (ev.file.type.includes("image")) {
uploadToS3( // Resizer.imageFileResizer(
key, // ev.file,
file.type, // 2500,
file, // 2500,
onError, // "JPEG",
onSuccess, // 75,
onProgress, // 0,
context // (uri) => {
); // let file = new File([uri], ev.file.name, {});
}, // file.uid = ev.file.uid;
"blob" // uploadToCloudinary(
); // key,
} else { // file.type,
uploadToS3( // file,
key, // onError,
ev.file.type, // onSuccess,
ev.file, // onProgress,
onError, // context
onSuccess, // );
onProgress, // },
context // "blob"
); // );
} // } else {
// uploadToCloudinary(
// key,
// ev.file.type,
// ev.file,
// onError,
// onSuccess,
// onProgress,
// context
// );
// }
}; };
export const uploadToS3 = ( export const uploadToCloudinary = async (
fileName, fileName,
fileType, fileType,
file, file,
@@ -69,92 +79,115 @@ export const uploadToS3 = (
) => { ) => {
const { bodyshop, jobId, billId, uploaded_by, callback, tagsArray } = context; const { bodyshop, jobId, billId, uploaded_by, callback, tagsArray } = context;
//Set variables for getting the signed URL.
let timestamp = Math.floor(Date.now() / 1000); let timestamp = Math.floor(Date.now() / 1000);
let public_id = fileName; let public_id = fileName;
let tags = `${bodyshop.textid},${ let tags = `${bodyshop.textid},${
tagsArray ? tagsArray.map((tag) => `${tag},`) : "" tagsArray ? tagsArray.map((tag) => `${tag},`) : ""
}`; }`;
let eager = process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS; 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 //Get the signed url.
.post(`${process.env.REACT_APP_CLOUDINARY_ENDPOINT}/upload`, formData, {
...options, const signedURLResponse = await axios.post("/media/sign", {
}) eager: eager,
.then((response) => { public_id: public_id,
console.log("Upload Response", response); tags: tags,
client timestamp: timestamp,
.mutate({ });
mutation: INSERT_NEW_DOCUMENT,
variables: { if (signedURLResponse.status !== 200) {
docInput: [ console.log("Error Getting Signed URL", signedURLResponse.statusText);
{ if (!!onError) onError(signedURLResponse.statusText);
jobid: jobId, notification["error"]({
uploaded_by: uploaded_by, message: i18n.t("documents.errors.getpresignurl", {
key: fileName, message: signedURLResponse.statusText,
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),
}),
});
}); });
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 React, { useEffect, useState } from "react";
import Gallery from "react-grid-gallery"; 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 JobsDocumentsDownloadButton from "./jobs-document-gallery.download.component";
import JobsDocumentsDeleteButton from "./jobs-documents-gallery.delete.component"; import JobsDocumentsDeleteButton from "./jobs-documents-gallery.delete.component";
@@ -35,18 +36,19 @@ function JobsDocumentsComponent({
return ( return (
<div className="clearfix"> <div className="clearfix">
<DocumentsUploadContainer <Space>
jobId={jobId} <DocumentsUploadComponent
billId={billId} jobId={jobId}
callbackAfterUpload={billsCallback || refetch} billId={billId}
tagsArray={["test"]} callbackAfterUpload={billsCallback || refetch}
/> tagsArray={["test"]}
/>
<JobsDocumentsDownloadButton galleryImages={galleryImages} /> <JobsDocumentsDownloadButton galleryImages={galleryImages} />
<JobsDocumentsDeleteButton <JobsDocumentsDeleteButton
galleryImages={galleryImages} galleryImages={galleryImages}
deletionCallback={billsCallback || refetch} deletionCallback={billsCallback || refetch}
/> />
</Space>
<Gallery <Gallery
images={galleryImages} images={galleryImages}