From c68835153fcb598e6c2a771fa10f0070300cf35e Mon Sep 17 00:00:00 2001
From: Patrick Fic <>
Date: Wed, 30 Sep 2020 07:58:37 -0700
Subject: [PATCH] WIP Code Cleanup for document upload. BOD-420
---
.../documents-upload.component.jsx | 53 +++-
.../documents-upload.container.jsx | 41 ---
.../documents-upload.utility.js | 265 ++++++++++--------
.../jobs-documents-gallery.component.jsx | 28 +-
4 files changed, 204 insertions(+), 183 deletions(-)
delete mode 100644 client/src/components/documents-upload/documents-upload.container.jsx
diff --git a/client/src/components/documents-upload/documents-upload.component.jsx b/client/src/components/documents-upload/documents-upload.component.jsx
index 287866f00..412918683 100644
--- a/client/src/components/documents-upload/documents-upload.component.jsx
+++ b/client/src/components/documents-upload/documents-upload.component.jsx
@@ -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 (
-
-
-
-
-
+
+ handleUpload(ev, {
+ bodyshop: bodyshop,
+ uploaded_by: currentUser.email,
+ jobId: jobId,
+ billId: billId,
+ tagsArray: tagsArray,
+ callback: callbackAfterUpload,
+ })
+ }
+ accept="audio/*,video/*,image/*"
+ showUploadList={false}
+ >
+
+
);
}
+export default connect(mapStateToProps, null)(DocumentsUploadComponent);
diff --git a/client/src/components/documents-upload/documents-upload.container.jsx b/client/src/components/documents-upload/documents-upload.container.jsx
deleted file mode 100644
index 1cfd6bfae..000000000
--- a/client/src/components/documents-upload/documents-upload.container.jsx
+++ /dev/null
@@ -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 (
-
- handleUpload(ev, {
- bodyshop: bodyshop,
- uploaded_by: currentUser.email,
- jobId: jobId,
- billId: billId,
- tagsArray: tagsArray,
- callback: callbackAfterUpload,
- })
- }
- />
- );
-}
-
-export default connect(mapStateToProps, null)(DocumentsUploadContainer);
diff --git a/client/src/components/documents-upload/documents-upload.utility.js b/client/src/components/documents-upload/documents-upload.utility.js
index c04b44841..c5e43831b 100644
--- a/client/src/components/documents-upload/documents-upload.utility.js
+++ b/client/src/components/documents-upload/documents-upload.utility.js
@@ -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);
+ // }
};
diff --git a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx
index e14ca8d42..edc7190bb 100644
--- a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx
+++ b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx
@@ -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 (
-
-
-
-
+
+
+
+
+