234 lines
7.1 KiB
JavaScript
234 lines
7.1 KiB
JavaScript
import {notification} from "antd";
|
|
import axios from "axios";
|
|
import i18n from "i18next";
|
|
import {logImEXEvent} from "../../firebase/firebase.utils";
|
|
import {INSERT_NEW_DOCUMENT} from "../../graphql/documents.queries";
|
|
import {axiosAuthInterceptorId} from "../../utils/CleanAxios";
|
|
import client from "../../utils/GraphQLClient";
|
|
import exifr from "exifr";
|
|
import {store} from "../../redux/store";
|
|
|
|
//Context: currentUserEmail, bodyshop, jobid, invoiceid
|
|
|
|
//Required to prevent headers from getting set and rejected from Cloudinary.
|
|
var cleanAxios = axios.create();
|
|
cleanAxios.interceptors.request.eject(axiosAuthInterceptorId);
|
|
|
|
export const handleUpload = (ev, context) => {
|
|
logImEXEvent("document_upload", {filetype: ev.file.type});
|
|
|
|
const {onError, onSuccess, onProgress} = ev;
|
|
const {bodyshop, jobId} = context;
|
|
|
|
const fileName = ev.file.name || ev.filename;
|
|
|
|
let key = `${bodyshop.id}/${jobId}/${replaceAccents(fileName).replace(
|
|
/[^A-Z0-9]+/gi,
|
|
"_"
|
|
)}-${new Date().getTime()}`;
|
|
let extension = fileName.split(".").pop();
|
|
uploadToCloudinary(
|
|
key,
|
|
extension,
|
|
ev.file.type,
|
|
ev.file,
|
|
onError,
|
|
onSuccess,
|
|
onProgress,
|
|
context
|
|
);
|
|
};
|
|
|
|
export const uploadToCloudinary = async (
|
|
key,
|
|
extension,
|
|
fileType,
|
|
file,
|
|
onError,
|
|
onSuccess,
|
|
onProgress,
|
|
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 public_id = key;
|
|
let tags = `${bodyshop.imexshopid},${
|
|
tagsArray ? tagsArray.map((tag) => `${tag},`) : ""
|
|
}`;
|
|
// let eager = process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS;
|
|
|
|
//Get the signed url.
|
|
|
|
const upload_preset = fileType.startsWith("video")
|
|
? "incoming_upload_video"
|
|
: "incoming_upload";
|
|
|
|
const signedURLResponse = await axios.post("/media/sign", {
|
|
public_id: public_id,
|
|
tags: tags,
|
|
timestamp: timestamp,
|
|
upload_preset: upload_preset,
|
|
});
|
|
|
|
if (signedURLResponse.status !== 200) {
|
|
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("upload_preset", upload_preset);
|
|
|
|
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);
|
|
|
|
const cloudinaryUploadResponse = await cleanAxios.post(
|
|
`${process.env.REACT_APP_CLOUDINARY_ENDPOINT_API}/${DetermineFileType(
|
|
fileType
|
|
)}/upload`,
|
|
formData,
|
|
{
|
|
...options,
|
|
}
|
|
);
|
|
|
|
if (cloudinaryUploadResponse.status !== 200) {
|
|
if (!!onError) {
|
|
onError(cloudinaryUploadResponse.statusText);
|
|
}
|
|
|
|
try {
|
|
axios.post("/newlog", {
|
|
message: "client-cloudinary-upload-error",
|
|
type: "error",
|
|
user: store.getState().user.email,
|
|
object: cloudinaryUploadResponse,
|
|
});
|
|
} catch (error) {
|
|
}
|
|
|
|
notification["error"]({
|
|
message: i18n.t("documents.errors.insert", {
|
|
message: cloudinaryUploadResponse.statusText,
|
|
}),
|
|
});
|
|
return;
|
|
}
|
|
|
|
//Insert the document with the matching key.
|
|
let takenat;
|
|
if (fileType.includes("image")) {
|
|
try {
|
|
const exif = await exifr.parse(file);
|
|
|
|
takenat = exif && exif.DateTimeOriginal;
|
|
} catch (error) {
|
|
console.log("Unable to parse image file for EXIF Data");
|
|
}
|
|
}
|
|
const documentInsert = await client.mutate({
|
|
mutation: INSERT_NEW_DOCUMENT,
|
|
variables: {
|
|
docInput: [
|
|
{
|
|
...(jobId ? {jobid: jobId} : {}),
|
|
...(billId ? {billid: billId} : {}),
|
|
uploaded_by: uploaded_by,
|
|
key: key,
|
|
type: fileType,
|
|
extension: cloudinaryUploadResponse.data.format || extension,
|
|
bodyshopid: bodyshop.id,
|
|
size: cloudinaryUploadResponse.data.bytes || file.size,
|
|
takenat,
|
|
},
|
|
],
|
|
},
|
|
});
|
|
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.open({
|
|
type: "success",
|
|
key: "docuploadsuccess",
|
|
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(documentInsert.errors),
|
|
}),
|
|
});
|
|
|
|
}
|
|
};
|
|
|
|
//Also needs to be updated in media JS and mobile app.
|
|
export function DetermineFileType(filetype) {
|
|
if (!filetype) return "auto";
|
|
else if (filetype.startsWith("image")) return "image";
|
|
else if (filetype.startsWith("video")) return "video";
|
|
else if (filetype.startsWith("application/pdf")) return "image";
|
|
else if (filetype.startsWith("application")) return "raw";
|
|
|
|
return "auto";
|
|
}
|
|
|
|
function replaceAccents(str) {
|
|
// Verifies if the String has accents and replace them
|
|
if (str.search(/[\xC0-\xFF]/g) > -1) {
|
|
str = str
|
|
.replace(/[\xC0-\xC5]/g, "A")
|
|
.replace(/[\xC6]/g, "AE")
|
|
.replace(/[\xC7]/g, "C")
|
|
.replace(/[\xC8-\xCB]/g, "E")
|
|
.replace(/[\xCC-\xCF]/g, "I")
|
|
.replace(/[\xD0]/g, "D")
|
|
.replace(/[\xD1]/g, "N")
|
|
.replace(/[\xD2-\xD6\xD8]/g, "O")
|
|
.replace(/[\xD9-\xDC]/g, "U")
|
|
.replace(/[\xDD]/g, "Y")
|
|
.replace(/[\xDE]/g, "P")
|
|
.replace(/[\xE0-\xE5]/g, "a")
|
|
.replace(/[\xE6]/g, "ae")
|
|
.replace(/[\xE7]/g, "c")
|
|
.replace(/[\xE8-\xEB]/g, "e")
|
|
.replace(/[\xEC-\xEF]/g, "i")
|
|
.replace(/[\xF1]/g, "n")
|
|
.replace(/[\xF2-\xF6\xF8]/g, "o")
|
|
.replace(/[\xF9-\xFC]/g, "u")
|
|
.replace(/[\xFE]/g, "p")
|
|
.replace(/[\xFD\xFF]/g, "y");
|
|
}
|
|
|
|
return str;
|
|
}
|