mirror of
https://github.com/documenso/documenso.git
synced 2025-11-09 20:12:31 +10:00
feat: download original documents (#1742)
## Preview 
This commit is contained in:
@ -3,8 +3,8 @@ import { useState } from 'react';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { DocumentStatus } from '@prisma/client';
|
||||
import type { Document, Recipient, Team, User } from '@prisma/client';
|
||||
import { DocumentStatus } from '@prisma/client';
|
||||
import {
|
||||
Copy,
|
||||
Download,
|
||||
@ -15,8 +15,7 @@ import {
|
||||
Share,
|
||||
Trash2,
|
||||
} from 'lucide-react';
|
||||
import { Link } from 'react-router';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { Link, useNavigate } from 'react-router';
|
||||
|
||||
import { downloadPDF } from '@documenso/lib/client-only/download-pdf';
|
||||
import { useSession } from '@documenso/lib/client-only/providers/session';
|
||||
@ -99,6 +98,35 @@ export const DocumentPageViewDropdown = ({ document }: DocumentPageViewDropdownP
|
||||
}
|
||||
};
|
||||
|
||||
const onDownloadOriginalClick = async () => {
|
||||
try {
|
||||
const documentWithData = await trpcClient.document.getDocumentById.query(
|
||||
{
|
||||
documentId: document.id,
|
||||
},
|
||||
{
|
||||
context: {
|
||||
teamId: team?.id?.toString(),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const documentData = documentWithData?.documentData;
|
||||
|
||||
if (!documentData) {
|
||||
return;
|
||||
}
|
||||
|
||||
await downloadPDF({ documentData, fileName: document.title, version: 'original' });
|
||||
} catch (err) {
|
||||
toast({
|
||||
title: _(msg`Something went wrong`),
|
||||
description: _(msg`An error occurred while downloading your document.`),
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const nonSignedRecipients = document.recipients.filter((item) => item.signingStatus !== 'SIGNED');
|
||||
|
||||
return (
|
||||
@ -128,6 +156,11 @@ export const DocumentPageViewDropdown = ({ document }: DocumentPageViewDropdownP
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
<DropdownMenuItem onClick={onDownloadOriginalClick}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
<Trans>Download Original</Trans>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem asChild>
|
||||
<Link to={`${documentsPath}/${document.id}/logs`}>
|
||||
<ScrollTextIcon className="mr-2 h-4 w-4" />
|
||||
|
||||
@ -100,6 +100,32 @@ export const DocumentsTableActionDropdown = ({ row }: DocumentsTableActionDropdo
|
||||
}
|
||||
};
|
||||
|
||||
const onDownloadOriginalClick = async () => {
|
||||
try {
|
||||
const document = !recipient
|
||||
? await trpcClient.document.getDocumentById.query({
|
||||
documentId: row.id,
|
||||
})
|
||||
: await trpcClient.document.getDocumentByToken.query({
|
||||
token: recipient.token,
|
||||
});
|
||||
|
||||
const documentData = document?.documentData;
|
||||
|
||||
if (!documentData) {
|
||||
return;
|
||||
}
|
||||
|
||||
await downloadPDF({ documentData, fileName: row.title, version: 'original' });
|
||||
} catch (err) {
|
||||
toast({
|
||||
title: _(msg`Something went wrong`),
|
||||
description: _(msg`An error occurred while downloading your document.`),
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const nonSignedRecipients = row.recipients.filter((item) => item.signingStatus !== 'SIGNED');
|
||||
|
||||
return (
|
||||
@ -152,6 +178,11 @@ export const DocumentsTableActionDropdown = ({ row }: DocumentsTableActionDropdo
|
||||
<Trans>Download</Trans>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem onClick={onDownloadOriginalClick}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
<Trans>Download Original</Trans>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem onClick={() => setDuplicateDialogOpen(true)}>
|
||||
<Copy className="mr-2 h-4 w-4" />
|
||||
<Trans>Duplicate</Trans>
|
||||
|
||||
@ -3,22 +3,38 @@ import type { DocumentData } from '@prisma/client';
|
||||
import { getFile } from '../universal/upload/get-file';
|
||||
import { downloadFile } from './download-file';
|
||||
|
||||
type DocumentVersion = 'original' | 'signed';
|
||||
|
||||
type DownloadPDFProps = {
|
||||
documentData: DocumentData;
|
||||
fileName?: string;
|
||||
/**
|
||||
* Specifies which version of the document to download.
|
||||
* 'signed': Downloads the signed version (default).
|
||||
* 'original': Downloads the original version.
|
||||
*/
|
||||
version?: DocumentVersion;
|
||||
};
|
||||
|
||||
export const downloadPDF = async ({ documentData, fileName }: DownloadPDFProps) => {
|
||||
const bytes = await getFile(documentData);
|
||||
export const downloadPDF = async ({
|
||||
documentData,
|
||||
fileName,
|
||||
version = 'signed',
|
||||
}: DownloadPDFProps) => {
|
||||
const bytes = await getFile({
|
||||
type: documentData.type,
|
||||
data: version === 'signed' ? documentData.data : documentData.initialData,
|
||||
});
|
||||
|
||||
const blob = new Blob([bytes], {
|
||||
type: 'application/pdf',
|
||||
});
|
||||
|
||||
const baseTitle = (fileName ?? 'document').replace(/\.pdf$/, '');
|
||||
const suffix = version === 'signed' ? '_signed.pdf' : '.pdf';
|
||||
|
||||
downloadFile({
|
||||
filename: `${baseTitle}_signed.pdf`,
|
||||
filename: `${baseTitle}${suffix}`,
|
||||
data: blob,
|
||||
});
|
||||
};
|
||||
|
||||
@ -230,7 +230,7 @@
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar-track {
|
||||
/* .custom-scrollbar::-webkit-scrollbar-track {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
@ -242,7 +242,7 @@
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background: rgb(100 116 139 / 0.5);
|
||||
}
|
||||
} */
|
||||
|
||||
/* Custom Swagger Dark Theme */
|
||||
.swagger-dark-theme .swagger-ui {
|
||||
|
||||
Reference in New Issue
Block a user