Added CDN thumb generation.
This commit is contained in:
@@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import Resizer from "react-image-file-resizer";
|
import Resizer from "react-image-file-resizer";
|
||||||
import { INSERT_NEW_DOCUMENT } from "../../graphql/documents.queries";
|
import { INSERT_NEW_DOCUMENT } from "../../graphql/documents.queries";
|
||||||
import "./jobs-documents.styles.scss";
|
import "./jobs-documents.styles.scss";
|
||||||
|
import { generateCdnThumb } from "../../utils/DocHelpers";
|
||||||
|
|
||||||
function getBase64(file) {
|
function getBase64(file) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -16,7 +17,7 @@ function getBase64(file) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function JobsDocumentsComponent({ shopId, jobId, loading, data }) {
|
function JobsDocumentsComponent({ shopId, jobId, loading, data, currentUser }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [insertNewDocument] = useMutation(INSERT_NEW_DOCUMENT);
|
const [insertNewDocument] = useMutation(INSERT_NEW_DOCUMENT);
|
||||||
|
|
||||||
@@ -29,98 +30,108 @@ function JobsDocumentsComponent({ shopId, jobId, loading, data }) {
|
|||||||
data.reduce((acc, value) => {
|
data.reduce((acc, value) => {
|
||||||
acc.push({
|
acc.push({
|
||||||
uid: value.id,
|
uid: value.id,
|
||||||
url: value.url,
|
url: value.thumb_url,
|
||||||
name: value.name,
|
name: value.name,
|
||||||
status: "done",
|
status: "done"
|
||||||
thumUrl:
|
|
||||||
"https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
|
||||||
});
|
});
|
||||||
return acc;
|
return acc;
|
||||||
}, [])
|
}, [])
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleUpload = ev => {
|
const uploadToS3 = (
|
||||||
const { onError, onSuccess, onProgress } = ev;
|
fileName,
|
||||||
|
fileType,
|
||||||
|
file,
|
||||||
|
onError,
|
||||||
|
onSuccess,
|
||||||
|
onProgress
|
||||||
|
) => {
|
||||||
|
axios
|
||||||
|
.post("/sign_s3", {
|
||||||
|
fileName,
|
||||||
|
fileType
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
var returnData = response.data.data.returnData;
|
||||||
|
var signedRequest = returnData.signedRequest;
|
||||||
|
var url = returnData.url;
|
||||||
|
setState({ ...state, url: url });
|
||||||
|
// Put the fileType in the headers for the upload
|
||||||
|
var options = {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": fileType
|
||||||
|
},
|
||||||
|
onUploadProgress: e => {
|
||||||
|
onProgress({ percent: (e.loaded / e.total) * 100 });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Resizer.imageFileResizer(
|
|
||||||
ev.file,
|
|
||||||
3000,
|
|
||||||
3000,
|
|
||||||
"JPEG",
|
|
||||||
75,
|
|
||||||
0,
|
|
||||||
uri => {
|
|
||||||
let file = new File([uri], ev.file.name, {});
|
|
||||||
file.uid = ev.file.uid;
|
|
||||||
// Split the filename to get the name and type
|
|
||||||
let fileName = file.name;
|
|
||||||
let fileType = file.type;
|
|
||||||
let key = `${shopId}/${jobId}/${fileName}`;
|
|
||||||
//URL is using the proxy set in pacakges.json.
|
|
||||||
axios
|
axios
|
||||||
.post("/sign_s3", {
|
.put(signedRequest, file, options)
|
||||||
fileName: key,
|
|
||||||
fileType
|
|
||||||
})
|
|
||||||
.then(response => {
|
.then(response => {
|
||||||
var returnData = response.data.data.returnData;
|
onSuccess(response.body);
|
||||||
var signedRequest = returnData.signedRequest;
|
insertNewDocument({
|
||||||
var url = returnData.url;
|
variables: {
|
||||||
setState({ ...state, url: url });
|
docInput: [
|
||||||
// Put the fileType in the headers for the upload
|
{
|
||||||
var options = {
|
jobid: jobId,
|
||||||
headers: {
|
uploaded_by: currentUser.email,
|
||||||
"Content-Type": fileType
|
url,
|
||||||
},
|
thumb_url: generateCdnThumb(fileName),
|
||||||
onUploadProgress: e => {
|
key: fileName
|
||||||
onProgress({ percent: (e.loaded / e.total) * 100 });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
axios
|
|
||||||
.put(signedRequest, file, options)
|
|
||||||
.then(response => {
|
|
||||||
onSuccess(response.body);
|
|
||||||
insertNewDocument({
|
|
||||||
variables: {
|
|
||||||
docInput: [
|
|
||||||
{
|
|
||||||
jobid: jobId,
|
|
||||||
uploaded_by: "patrick@bodyshop.app",
|
|
||||||
url,
|
|
||||||
thumb_url: url
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}).then(r => {
|
]
|
||||||
console.log(r);
|
}
|
||||||
notification["success"]({
|
}).then(r => {
|
||||||
message: t("documents.successes.insert")
|
console.log(r);
|
||||||
});
|
notification["success"]({
|
||||||
});
|
message: t("documents.successes.insert")
|
||||||
|
|
||||||
setState({ ...state, success: true });
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log("Error uploading to S3", error);
|
|
||||||
onError(error);
|
|
||||||
notification["error"]({
|
|
||||||
message: t("documents.errors.insert") + JSON.stringify(error)
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
setState({ ...state, success: true });
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log("Outside Error here.", error);
|
console.log("Error uploading to S3", error);
|
||||||
|
onError(error);
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message:
|
message: t("documents.errors.insert") + JSON.stringify(error)
|
||||||
t("documents.errors.getpresignurl") + JSON.stringify(error)
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
})
|
||||||
"blob"
|
.catch(error => {
|
||||||
);
|
console.log("Outside Error here.", error);
|
||||||
|
notification["error"]({
|
||||||
|
message: t("documents.errors.getpresignurl") + JSON.stringify(error)
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleUpload = ev => {
|
||||||
|
const { onError, onSuccess, onProgress } = ev;
|
||||||
|
//If PDF, upload directly.
|
||||||
|
//If JPEG, resize and upload.
|
||||||
|
let key = `${shopId}/${jobId}/${ev.file.name}`;
|
||||||
|
if (ev.file.type === "application/pdf") {
|
||||||
|
console.log("It's a PDF.");
|
||||||
|
uploadToS3(key, ev.file.type, ev.file, onError, onSuccess, onProgress);
|
||||||
|
} else {
|
||||||
|
Resizer.imageFileResizer(
|
||||||
|
ev.file,
|
||||||
|
3000,
|
||||||
|
3000,
|
||||||
|
"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);
|
||||||
|
},
|
||||||
|
"blob"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
const handleCancel = () => setState({ ...state, previewVisible: false });
|
const handleCancel = () => setState({ ...state, previewVisible: false });
|
||||||
|
|
||||||
const handlePreview = async file => {
|
const handlePreview = async file => {
|
||||||
@@ -136,38 +147,32 @@ function JobsDocumentsComponent({ shopId, jobId, loading, data }) {
|
|||||||
};
|
};
|
||||||
const handleChange = props => {
|
const handleChange = props => {
|
||||||
const { fileList } = props;
|
const { fileList } = props;
|
||||||
console.log("New fileList", fileList);
|
|
||||||
setFileList(fileList);
|
setFileList(fileList);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { previewVisible, previewImage } = state;
|
const { previewVisible, previewImage } = state;
|
||||||
// const uploadButton = (
|
|
||||||
// <div>
|
|
||||||
// <Icon type='plus' />
|
|
||||||
// <div className='ant-upload-text'>{t("documents.labels.upload")}</div>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
"process.env.REACT_APP_S3_BUCKET",
|
|
||||||
process.env.REACT_APP_S3_BUCKET
|
|
||||||
);
|
|
||||||
const imageRequest = JSON.stringify({
|
|
||||||
bucket: process.env.REACT_APP_S3_BUCKET,
|
|
||||||
key:
|
|
||||||
"52b7357c-0edd-4c95-85c3-dfdbcdfad9ac/f11e92a4-8a7d-4ec0-86ac-2f46b631e438/thumb-1920-459857.jpg",
|
|
||||||
edits: {
|
|
||||||
resize: {
|
|
||||||
height: 100,
|
|
||||||
width: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const CloudFrontUrl = "https://d18fc493a0fm4o.cloudfront.net";
|
|
||||||
const url = `${CloudFrontUrl}/${btoa(imageRequest)}`;
|
|
||||||
console.log("url", url);
|
|
||||||
return (
|
return (
|
||||||
<div className='clearfix'>
|
<div className='clearfix'>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
const imageRequest = JSON.stringify({
|
||||||
|
bucket: process.env.REACT_APP_S3_BUCKET,
|
||||||
|
key:
|
||||||
|
"52b7357c-0edd-4c95-85c3-dfdbcdfad9ac/c8ca5761-681a-4bb3-ab76-34c447357be3/Invoice_353284489.pdf",
|
||||||
|
edits: {
|
||||||
|
resize: {
|
||||||
|
height: 100,
|
||||||
|
width: 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const CloudFrontUrl = "https://d18fc493a0fm4o.cloudfront.net";
|
||||||
|
const url = `${CloudFrontUrl}/${btoa(imageRequest)}`;
|
||||||
|
console.log("url", url);
|
||||||
|
}}>
|
||||||
|
H
|
||||||
|
</button>
|
||||||
<Upload.Dragger
|
<Upload.Dragger
|
||||||
customRequest={handleUpload}
|
customRequest={handleUpload}
|
||||||
accept='.pdf,.jpg,.jpeg'
|
accept='.pdf,.jpg,.jpeg'
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { GET_DOCUMENTS_BY_JOB } from "../../graphql/documents.queries";
|
|||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||||
import JobDocuments from "./jobs-documents.component";
|
import JobDocuments from "./jobs-documents.component";
|
||||||
|
import { GET_CURRENT_USER } from "../../graphql/local.queries";
|
||||||
|
|
||||||
export default function JobsDocumentsContainer({ jobId }) {
|
export default function JobsDocumentsContainer({ jobId }) {
|
||||||
const { loading, error, data } = useQuery(GET_DOCUMENTS_BY_JOB, {
|
const { loading, error, data } = useQuery(GET_DOCUMENTS_BY_JOB, {
|
||||||
@@ -16,15 +17,22 @@ export default function JobsDocumentsContainer({ jobId }) {
|
|||||||
fetchPolicy: "network-only"
|
fetchPolicy: "network-only"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (loading || shopData.loading) return <LoadingSpinner />;
|
const user = useQuery(GET_CURRENT_USER);
|
||||||
if (error) return <AlertComponent type='error' message={error.message} />;
|
|
||||||
if (shopData.error)
|
if (loading || shopData.loading || user.loading) return <LoadingSpinner />;
|
||||||
return <AlertComponent type='error' message={shopData.error.message} />;
|
if (error || shopData.error || user.error)
|
||||||
|
return (
|
||||||
|
<AlertComponent
|
||||||
|
type='error'
|
||||||
|
message={error.message || shopData.error.message || user.error.message}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<JobDocuments
|
<JobDocuments
|
||||||
data={data.documents}
|
data={data.documents}
|
||||||
jobId={jobId}
|
jobId={jobId}
|
||||||
|
currentUser={user.data.currentUser}
|
||||||
shopId={
|
shopId={
|
||||||
shopData.data?.bodyshops[0]?.id
|
shopData.data?.bodyshops[0]?.id
|
||||||
? shopData.data?.bodyshops[0]?.id
|
? shopData.data?.bodyshops[0]?.id
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import JobNotesContainer from "../../components/jobs-notes/jobs-notes.container"
|
|||||||
|
|
||||||
function JobsDetailPage({ jobId, hash, data, match, history }) {
|
function JobsDetailPage({ jobId, hash, data, match, history }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
console.log("hash", hash);
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
|
|||||||
13
client/src/utils/DocHelpers.js
Normal file
13
client/src/utils/DocHelpers.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export const generateCdnThumb = key => {
|
||||||
|
const imageRequest = JSON.stringify({
|
||||||
|
bucket: process.env.REACT_APP_S3_BUCKET,
|
||||||
|
key: key,
|
||||||
|
edits: {
|
||||||
|
resize: {
|
||||||
|
height: 100,
|
||||||
|
width: 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return `${process.env.REACT_APP_S3_CDN}/${btoa(imageRequest)}`;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user