@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<29bf3465293095c44e826394c602cde1>>
|
* @generated SignedSource<<25880ab79f8b6ae18f3ead4431a90329>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import { ConcreteRequest } from 'relay-runtime';
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
import { FragmentRefs } from "relay-runtime";
|
import { FragmentRefs } from "relay-runtime";
|
||||||
export type DocumentOrderField = "CREATED_AT" | "TITLE";
|
export type DocumentOrderField = "CREATED_AT" | "DOCUMENT_TYPE" | "TITLE";
|
||||||
export type OrderDirection = "ASC" | "DESC";
|
export type OrderDirection = "ASC" | "DESC";
|
||||||
export type DocumentOrder = {
|
export type DocumentOrder = {
|
||||||
direction: OrderDirection;
|
direction: OrderDirection;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<b61f74ae791f86da55afd868c68c85e4>>
|
* @generated SignedSource<<9ea096db73885458f35ae718a00ded47>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import { ConcreteRequest } from 'relay-runtime';
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
import { FragmentRefs } from "relay-runtime";
|
import { FragmentRefs } from "relay-runtime";
|
||||||
export type DocumentOrderField = "CREATED_AT" | "TITLE";
|
export type DocumentOrderField = "CREATED_AT" | "DOCUMENT_TYPE" | "TITLE";
|
||||||
export type OrderDirection = "ASC" | "DESC";
|
export type OrderDirection = "ASC" | "DESC";
|
||||||
export type DocumentOrder = {
|
export type DocumentOrder = {
|
||||||
direction: OrderDirection;
|
direction: OrderDirection;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
|
Button,
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogFooter,
|
DialogFooter,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
|
IconArrowInbox,
|
||||||
Markdown,
|
Markdown,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
@@ -11,9 +13,11 @@ import { useTranslate } from "@probo/i18n";
|
|||||||
import { useState, type ReactNode } from "react";
|
import { useState, type ReactNode } from "react";
|
||||||
import { useFragment } from "react-relay";
|
import { useFragment } from "react-relay";
|
||||||
import type { DocumentVersionHistoryDialogFragment$key } from "./__generated__/DocumentVersionHistoryDialogFragment.graphql";
|
import type { DocumentVersionHistoryDialogFragment$key } from "./__generated__/DocumentVersionHistoryDialogFragment.graphql";
|
||||||
|
import type { DocumentVersionHistoryDialogExportPDFMutation } from "./__generated__/DocumentVersionHistoryDialogExportPDFMutation.graphql";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import type { NodeOf } from "/types";
|
import type { NodeOf } from "/types";
|
||||||
import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql";
|
import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql";
|
||||||
|
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||||
|
|
||||||
const historyFragment = graphql`
|
const historyFragment = graphql`
|
||||||
fragment DocumentVersionHistoryDialogFragment on DocumentVersion {
|
fragment DocumentVersionHistoryDialogFragment on DocumentVersion {
|
||||||
@@ -30,6 +34,16 @@ const historyFragment = graphql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const exportPDFMutation = graphql`
|
||||||
|
mutation DocumentVersionHistoryDialogExportPDFMutation(
|
||||||
|
$documentVersionId: ID!
|
||||||
|
) {
|
||||||
|
exportDocumentVersionPDF(input: { documentVersionId: $documentVersionId }) {
|
||||||
|
data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
document: DocumentDetailPageDocumentFragment$data;
|
document: DocumentDetailPageDocumentFragment$data;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
@@ -41,6 +55,46 @@ export function DocumentVersionHistoryDialog(props: Props) {
|
|||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
const versions = props.document.versions.edges.map((edge) => edge.node);
|
const versions = props.document.versions.edges.map((edge) => edge.node);
|
||||||
const [selectedVersion, setSelectedVersion] = useState<Version>(versions[0]);
|
const [selectedVersion, setSelectedVersion] = useState<Version>(versions[0]);
|
||||||
|
const [exportPDF, isExporting] =
|
||||||
|
useMutationWithToasts<DocumentVersionHistoryDialogExportPDFMutation>(
|
||||||
|
exportPDFMutation,
|
||||||
|
{
|
||||||
|
errorMessage: __("Failed to export PDF"),
|
||||||
|
successMessage: __("PDF exported successfully"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDownloadPDF = () => {
|
||||||
|
exportPDF({
|
||||||
|
variables: { documentVersionId: selectedVersion.id },
|
||||||
|
onCompleted: (data) => {
|
||||||
|
if (data.exportDocumentVersionPDF.data) {
|
||||||
|
// Handle data URI format (data:application/pdf;base64,...)
|
||||||
|
const dataUri = data.exportDocumentVersionPDF.data;
|
||||||
|
|
||||||
|
// Extract base64 part from data URI
|
||||||
|
const base64Data = dataUri.split(",")[1];
|
||||||
|
|
||||||
|
// Convert base64 to blob and download
|
||||||
|
const binaryString = atob(base64Data);
|
||||||
|
const bytes = new Uint8Array(binaryString.length);
|
||||||
|
for (let i = 0; i < binaryString.length; i++) {
|
||||||
|
bytes[i] = binaryString.charCodeAt(i);
|
||||||
|
}
|
||||||
|
const blob = new Blob([bytes], { type: "application/pdf" });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = url;
|
||||||
|
link.download = `${props.document.title}-v${selectedVersion.version}.pdf`;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog trigger={props.children}>
|
<Dialog trigger={props.children}>
|
||||||
<DialogContent className="flex" scrollableChildren>
|
<DialogContent className="flex" scrollableChildren>
|
||||||
@@ -59,6 +113,16 @@ export function DocumentVersionHistoryDialog(props: Props) {
|
|||||||
))}
|
))}
|
||||||
</aside>
|
</aside>
|
||||||
<main className="flex-1 px-12 py-8">
|
<main className="flex-1 px-12 py-8">
|
||||||
|
<div className="mb-4">
|
||||||
|
<Button
|
||||||
|
onClick={handleDownloadPDF}
|
||||||
|
icon={IconArrowInbox}
|
||||||
|
variant="secondary"
|
||||||
|
disabled={isExporting}
|
||||||
|
>
|
||||||
|
{isExporting ? __("Exporting...") : __("Download PDF")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
<Markdown content={selectedVersion.content} />
|
<Markdown content={selectedVersion.content} />
|
||||||
</main>
|
</main>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<06126b60bc37d8fbbb9a475af6d5d29d>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type DocumentVersionHistoryDialogExportPDFMutation$variables = {
|
||||||
|
documentVersionId: string;
|
||||||
|
};
|
||||||
|
export type DocumentVersionHistoryDialogExportPDFMutation$data = {
|
||||||
|
readonly exportDocumentVersionPDF: {
|
||||||
|
readonly data: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type DocumentVersionHistoryDialogExportPDFMutation = {
|
||||||
|
response: DocumentVersionHistoryDialogExportPDFMutation$data;
|
||||||
|
variables: DocumentVersionHistoryDialogExportPDFMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "documentVersionId"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "documentVersionId",
|
||||||
|
"variableName": "documentVersionId"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kind": "ObjectValue",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "ExportDocumentVersionPDFPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "exportDocumentVersionPDF",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "data",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "DocumentVersionHistoryDialogExportPDFMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "DocumentVersionHistoryDialogExportPDFMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "45204e42c1018e00dcceaae84eb9a5f7",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "DocumentVersionHistoryDialogExportPDFMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation DocumentVersionHistoryDialogExportPDFMutation(\n $documentVersionId: ID!\n) {\n exportDocumentVersionPDF(input: {documentVersionId: $documentVersionId}) {\n data\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "587bcc8bb6cf72e64a5eca18769ac432";
|
||||||
|
|
||||||
|
export default node;
|
||||||
Reference in New Issue
Block a user