IO-2433 Delete on cancel, improved styling.
This commit is contained in:
@@ -480,4 +480,5 @@
|
|||||||
.esignature-embed {
|
.esignature-embed {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
border-width: 0;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Button, Modal } from "antd";
|
import { EmbedUpdateDocumentV1 } from "@documenso/embed-react";
|
||||||
|
import { Modal } from "antd";
|
||||||
|
import axios from "axios";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||||
import { selectEsignature } from "../../redux/modals/modals.selectors";
|
import { selectEsignature } from "../../redux/modals/modals.selectors";
|
||||||
import { EmbedUpdateDocumentV1 } from "@documenso/embed-react";
|
|
||||||
import axios from "axios";
|
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
@@ -26,23 +26,42 @@ export function EsignatureModalContainer({ esignatureModal, toggleModalVisible,
|
|||||||
<Modal
|
<Modal
|
||||||
open={open}
|
open={open}
|
||||||
title={t("jobs.labels.esignature")}
|
title={t("jobs.labels.esignature")}
|
||||||
onOk={() => {
|
onOk={async () => {
|
||||||
toggleModalVisible();
|
try {
|
||||||
|
const distResult = await axios.post("/esign/distribute", {
|
||||||
|
documentId,
|
||||||
|
envelopeId,
|
||||||
|
jobid,
|
||||||
|
bodyshopid: bodyshop.id
|
||||||
|
});
|
||||||
|
console.log("Distribution result:", distResult);
|
||||||
|
toggleModalVisible();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error distributing document:", error);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
onCancel={() => {
|
onCancel={async () => {
|
||||||
toggleModalVisible();
|
try {
|
||||||
|
const cancelResult = await axios.post("/esign/delete", {
|
||||||
|
documentId,
|
||||||
|
envelopeId
|
||||||
|
});
|
||||||
|
console.log("Cancel result:", cancelResult);
|
||||||
|
toggleModalVisible();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error cancelling document:", error);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
cancelButtonProps={{ style: { display: "none" } }}
|
okButtonProps={{ title: "Distribute by Email" }}
|
||||||
width="90%"
|
width="90%"
|
||||||
destroyOnHidden
|
destroyOnHidden
|
||||||
>
|
>
|
||||||
<div style={{ height: "800px", width: "100%" }}>
|
<div style={{ height: "600px", width: "100%" }}>
|
||||||
{token ? (
|
{token ? (
|
||||||
<EmbedUpdateDocumentV1
|
<EmbedUpdateDocumentV1
|
||||||
presignToken={token}
|
presignToken={token}
|
||||||
host="https://stg-app.documenso.com"
|
host="https://stg-app.documenso.com"
|
||||||
documentId={documentId}
|
documentId={documentId}
|
||||||
externalId={jobid}
|
|
||||||
className="esignature-embed"
|
className="esignature-embed"
|
||||||
onDocumentUpdated={(data) => {
|
onDocumentUpdated={(data) => {
|
||||||
console.log("Document updated:", data.documentId);
|
console.log("Document updated:", data.documentId);
|
||||||
@@ -51,24 +70,6 @@ export function EsignatureModalContainer({ esignatureModal, toggleModalVisible,
|
|||||||
) : (
|
) : (
|
||||||
<div>No token...</div>
|
<div>No token...</div>
|
||||||
)}
|
)}
|
||||||
<Button
|
|
||||||
onClick={async () => {
|
|
||||||
// Add your button click handler logic here
|
|
||||||
try {
|
|
||||||
const distResult = await axios.post("/esign/distribute", {
|
|
||||||
documentId,
|
|
||||||
envelopeId,
|
|
||||||
jobid,
|
|
||||||
bodyshopid: bodyshop.id
|
|
||||||
});
|
|
||||||
console.log("Distribution result:", distResult);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error distributing document:", error);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Distribute Document
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -43,8 +43,25 @@ async function distributeDocument(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function newEsignDocument(req, res) {
|
async function deleteDocument(req, res) {
|
||||||
|
try {
|
||||||
|
const { documentId } = req.body;
|
||||||
|
//TODO: This needs to be hardened to prevent deleting other people's documents, completed ones, etc.
|
||||||
|
const deleteResult = await documenso.documents.delete({
|
||||||
|
documentId
|
||||||
|
});
|
||||||
|
res.json({ success: true, deleteResult });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting document:", error?.data);
|
||||||
|
logger.log(`esig-delete-error`, "ERROR", "esig", "api", {
|
||||||
|
message: error.message, stack: error.stack,
|
||||||
|
body: req.body
|
||||||
|
});
|
||||||
|
res.status(500).json({ error: "An error occurred while deleting the document." });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function newEsignDocument(req, res) {
|
||||||
try {
|
try {
|
||||||
const client = req.userGraphQLClient;
|
const client = req.userGraphQLClient;
|
||||||
const { bodyshop } = req.body
|
const { bodyshop } = req.body
|
||||||
@@ -58,7 +75,7 @@ async function newEsignDocument(req, res) {
|
|||||||
const createDocumentResponse = await documenso.documents.create({
|
const createDocumentResponse = await documenso.documents.create({
|
||||||
payload: {
|
payload: {
|
||||||
title: esigData?.title,
|
title: esigData?.title,
|
||||||
externalId: req.body.jobid,
|
externalId: `${req.body.jobid}|${req.user?.email}`, //Have to pass the uploaded by later on. Limited to 255 chars.
|
||||||
recipients: [
|
recipients: [
|
||||||
{
|
{
|
||||||
email: "patrick@imexsystems.ca",//jobData.ownr_ea,
|
email: "patrick@imexsystems.ca",//jobData.ownr_ea,
|
||||||
@@ -264,7 +281,8 @@ const fetchContextData = async ({ templateObject, jsrAuth, req, }) => {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
newEsignDocument,
|
newEsignDocument,
|
||||||
distributeDocument
|
distributeDocument,
|
||||||
|
deleteDocument
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -85,8 +85,14 @@ async function handleDocumentCompleted(payload = sampleComplete) {
|
|||||||
|
|
||||||
//Check if the bodyshop is on image proxy or not
|
//Check if the bodyshop is on image proxy or not
|
||||||
try {
|
try {
|
||||||
|
//Split the external id to get the uploaded user.
|
||||||
|
const [jobid, uploaded_by] = payload.externalId.split("|");
|
||||||
|
|
||||||
|
if (!jobid || !uploaded_by) {
|
||||||
|
throw new Error(`Invalid externalId format. Expected "jobid|uploaded_by", got "${payload.externalId}"`);
|
||||||
|
}
|
||||||
const { jobs_by_pk } = await client.request(QUERY_META_FOR_ESIG_COMPLETION, {
|
const { jobs_by_pk } = await client.request(QUERY_META_FOR_ESIG_COMPLETION, {
|
||||||
jobid: payload.externalId
|
jobid
|
||||||
});
|
});
|
||||||
const document = await documenso.document.documentDownload({
|
const document = await documenso.document.documentDownload({
|
||||||
documentId: payload.id,
|
documentId: payload.id,
|
||||||
@@ -97,25 +103,24 @@ async function handleDocumentCompleted(payload = sampleComplete) {
|
|||||||
const buffer = Buffer.from(arrayBuffer);
|
const buffer = Buffer.from(arrayBuffer);
|
||||||
|
|
||||||
|
|
||||||
|
let key = `${jobs_by_pk.bodyshop.id}/${jobs_by_pk.id}/${replaceAccents(document.filename).replace(/[^A-Z0-9]+/gi, "_")}-${new Date().getTime()}.pdf`;
|
||||||
|
|
||||||
if (jobs_by_pk?.bodyshop?.uselocalmediaserver) {
|
if (jobs_by_pk?.bodyshop?.uselocalmediaserver) {
|
||||||
//LMS not yet implemented.
|
//LMS not yet implemented.
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//S3 Upload
|
//S3 Upload
|
||||||
let key = `${jobs_by_pk.bodyshop.id}/${jobs_by_pk.id}/${replaceAccents(document.filename).replace(/[^A-Z0-9]+/gi, "_")}-${new Date().getTime()}.pdf`;
|
|
||||||
|
|
||||||
const uploadResult = await uploadFileBuffer({ key, buffer, contentType: "application/pdf" });
|
const uploadResult = await uploadFileBuffer({ key, buffer, contentType: "application/pdf" });
|
||||||
if (!uploadResult.success) {
|
if (!uploadResult.success) {
|
||||||
logger.log(`esig-webhook-s3-upload-error`, "ERROR", "redis", "api", {
|
logger.log(`esig-webhook-s3-upload-error`, "ERROR", "redis", "api", {
|
||||||
message: uploadResult.message,
|
message: uploadResult.message,
|
||||||
stack: uploadResult.stack,
|
stack: uploadResult.stack,
|
||||||
jobid: payload.externalId,
|
jobid: jobid,
|
||||||
documentId: payload.id
|
documentId: payload.id
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
logger.log(`esig-webhook-s3-upload-success`, "INFO", "redis", "api", {
|
logger.log(`esig-webhook-s3-upload-success`, "INFO", "redis", "api", {
|
||||||
jobid: payload.externalId,
|
jobid: jobid,
|
||||||
documentId: payload.id,
|
documentId: payload.id,
|
||||||
s3Key: key,
|
s3Key: key,
|
||||||
bucket: uploadResult.bucket
|
bucket: uploadResult.bucket
|
||||||
@@ -125,7 +130,7 @@ async function handleDocumentCompleted(payload = sampleComplete) {
|
|||||||
jobid: jobs_by_pk.id,
|
jobid: jobs_by_pk.id,
|
||||||
bodyshopid: jobs_by_pk.bodyshop.id,
|
bodyshopid: jobs_by_pk.bodyshop.id,
|
||||||
operation: `Esignature document with title ${payload.title} (ID: ${payload.documentMeta.id}) has been completed.`,
|
operation: `Esignature document with title ${payload.title} (ID: ${payload.documentMeta.id}) has been completed.`,
|
||||||
useremail: "patrick@imex.dev", //TODO: Figure out the hardcoded bypass.
|
useremail: uploaded_by,
|
||||||
type: 'esig-complete'
|
type: 'esig-complete'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -133,12 +138,12 @@ async function handleDocumentCompleted(payload = sampleComplete) {
|
|||||||
await client.request(INSERT_ESIGNATURE_DOCUMENT, {
|
await client.request(INSERT_ESIGNATURE_DOCUMENT, {
|
||||||
docInput: {
|
docInput: {
|
||||||
jobid: jobs_by_pk.id,
|
jobid: jobs_by_pk.id,
|
||||||
uploaded_by: "patrick@imex.dev", //TODO: Figure out the hard coded bypass.
|
uploaded_by: uploaded_by,
|
||||||
key,
|
key,
|
||||||
type: "application/pdf",
|
type: "application/pdf",
|
||||||
extension: "pdf",
|
extension: "pdf",
|
||||||
bodyshopid: jobs_by_pk.bodyshop.id,
|
bodyshopid: jobs_by_pk.bodyshop.id,
|
||||||
size: buffer.length, //Leftover from Cloudinary. We don't do any optimization on upload, so it will always be file.size.
|
size: buffer.length,
|
||||||
takenat: new Date().toISOString(),
|
takenat: new Date().toISOString(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ const router = express.Router();
|
|||||||
|
|
||||||
const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware");
|
const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware");
|
||||||
const withUserGraphQLClientMiddleware = require("../middleware/withUserGraphQLClientMiddleware");
|
const withUserGraphQLClientMiddleware = require("../middleware/withUserGraphQLClientMiddleware");
|
||||||
const { newEsignDocument, distributeDocument } = require("../esign/esign-new");
|
const { newEsignDocument, distributeDocument, deleteDocument } = require("../esign/esign-new");
|
||||||
const { esignWebhook } = require("../esign/webhook");
|
const { esignWebhook } = require("../esign/webhook");
|
||||||
|
|
||||||
//router.use(validateFirebaseIdTokenMiddleware);
|
//router.use(validateFirebaseIdTokenMiddleware);
|
||||||
|
|
||||||
router.post("/new", validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, newEsignDocument);
|
router.post("/new", validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, newEsignDocument);
|
||||||
router.post("/distribute", validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, distributeDocument);
|
router.post("/distribute", validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, distributeDocument);
|
||||||
|
router.post("/delete", validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, deleteDocument);
|
||||||
router.post("/webhook", esignWebhook);
|
router.post("/webhook", esignWebhook);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user