mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 08:42:12 +10:00
fix: update create envelope item endpoint to use formdata
This commit is contained in:
@ -207,7 +207,6 @@ export const DocumentSigningPageViewV2 = () => {
|
|||||||
<PDFViewerKonvaLazy
|
<PDFViewerKonvaLazy
|
||||||
renderer="signing"
|
renderer="signing"
|
||||||
key={currentEnvelopeItem.id}
|
key={currentEnvelopeItem.id}
|
||||||
documentDataId={currentEnvelopeItem.documentDataId}
|
|
||||||
customPageRenderer={EnvelopeSignerPageRenderer}
|
customPageRenderer={EnvelopeSignerPageRenderer}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@ -482,30 +482,46 @@ export const EnvelopeEditorRecipientForm = () => {
|
|||||||
|
|
||||||
const { data } = validatedFormValues;
|
const { data } = validatedFormValues;
|
||||||
|
|
||||||
|
// Weird edge case where the whole envelope is created via API
|
||||||
|
// with no signing order. If they come to this page it will show an error
|
||||||
|
// since they aren't equal and the recipient is no longer editable.
|
||||||
|
const envelopeRecipients = data.signers.map((recipient) => {
|
||||||
|
if (!canRecipientBeModified(recipient.id)) {
|
||||||
|
return {
|
||||||
|
...recipient,
|
||||||
|
signingOrder: recipient.signingOrder,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return recipient;
|
||||||
|
});
|
||||||
|
|
||||||
const hasSigningOrderChanged = envelope.documentMeta.signingOrder !== data.signingOrder;
|
const hasSigningOrderChanged = envelope.documentMeta.signingOrder !== data.signingOrder;
|
||||||
const hasAllowDictateNextSignerChanged =
|
const hasAllowDictateNextSignerChanged =
|
||||||
envelope.documentMeta.allowDictateNextSigner !== data.allowDictateNextSigner;
|
envelope.documentMeta.allowDictateNextSigner !== data.allowDictateNextSigner;
|
||||||
|
|
||||||
const hasSignersChanged =
|
const hasSignersChanged =
|
||||||
data.signers.length !== recipients.length ||
|
envelopeRecipients.length !== recipients.length ||
|
||||||
data.signers.some((signer) => {
|
envelopeRecipients.some((signer) => {
|
||||||
const recipient = recipients.find((recipient) => recipient.id === signer.id);
|
const recipient = recipients.find((recipient) => recipient.id === signer.id);
|
||||||
|
|
||||||
if (!recipient) {
|
if (!recipient) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const signerActionAuth = signer.actionAuth;
|
||||||
|
const recipientActionAuth = recipient.authOptions?.actionAuth || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
signer.email !== recipient.email ||
|
signer.email !== recipient.email ||
|
||||||
signer.name !== recipient.name ||
|
signer.name !== recipient.name ||
|
||||||
signer.role !== recipient.role ||
|
signer.role !== recipient.role ||
|
||||||
signer.signingOrder !== recipient.signingOrder ||
|
signer.signingOrder !== recipient.signingOrder ||
|
||||||
!isDeepEqual(signer.actionAuth, recipient.authOptions?.actionAuth)
|
!isDeepEqual(signerActionAuth, recipientActionAuth)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hasSignersChanged) {
|
if (hasSignersChanged) {
|
||||||
setRecipientsDebounced(validatedFormValues.data.signers);
|
setRecipientsDebounced(envelopeRecipients);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasSigningOrderChanged || hasAllowDictateNextSignerChanged) {
|
if (hasSigningOrderChanged || hasAllowDictateNextSignerChanged) {
|
||||||
|
|||||||
@ -18,9 +18,9 @@ import {
|
|||||||
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
|
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
|
||||||
import { APP_DOCUMENT_UPLOAD_SIZE_LIMIT } from '@documenso/lib/constants/app';
|
import { APP_DOCUMENT_UPLOAD_SIZE_LIMIT } from '@documenso/lib/constants/app';
|
||||||
import { nanoid } from '@documenso/lib/universal/id';
|
import { nanoid } from '@documenso/lib/universal/id';
|
||||||
import { putPdfFile } from '@documenso/lib/universal/upload/put-file';
|
|
||||||
import { canEnvelopeItemsBeModified } from '@documenso/lib/utils/envelope';
|
import { canEnvelopeItemsBeModified } from '@documenso/lib/utils/envelope';
|
||||||
import { trpc } from '@documenso/trpc/react';
|
import { trpc } from '@documenso/trpc/react';
|
||||||
|
import type { TCreateEnvelopeItemsPayload } from '@documenso/trpc/server/envelope-router/create-envelope-items.types';
|
||||||
import { Button } from '@documenso/ui/primitives/button';
|
import { Button } from '@documenso/ui/primitives/button';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@ -114,36 +114,19 @@ export const EnvelopeEditorUploadPage = () => {
|
|||||||
|
|
||||||
setLocalFiles((prev) => [...prev, ...newUploadingFiles]);
|
setLocalFiles((prev) => [...prev, ...newUploadingFiles]);
|
||||||
|
|
||||||
const result = await Promise.all(
|
const payload = {
|
||||||
files.map(async (file, index) => {
|
|
||||||
try {
|
|
||||||
const response = await putPdfFile(file);
|
|
||||||
|
|
||||||
// Mark as uploaded (remove from uploading state)
|
|
||||||
return {
|
|
||||||
title: file.name,
|
|
||||||
documentDataId: response.id,
|
|
||||||
};
|
|
||||||
} catch (_error) {
|
|
||||||
setLocalFiles((prev) =>
|
|
||||||
prev.map((uploadingFile) =>
|
|
||||||
uploadingFile.id === newUploadingFiles[index].id
|
|
||||||
? { ...uploadingFile, isError: true, isUploading: false }
|
|
||||||
: uploadingFile,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const envelopeItemsToCreate = result.filter(
|
|
||||||
(item): item is { title: string; documentDataId: string } => item !== undefined,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { createdEnvelopeItems } = await createEnvelopeItems({
|
|
||||||
envelopeId: envelope.id,
|
envelopeId: envelope.id,
|
||||||
data: envelopeItemsToCreate,
|
} satisfies TCreateEnvelopeItemsPayload;
|
||||||
}).catch((error) => {
|
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('payload', JSON.stringify(payload));
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
formData.append('files', file);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { createdEnvelopeItems } = await createEnvelopeItems(formData).catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
||||||
// Set error state on files in batch upload.
|
// Set error state on files in batch upload.
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import {
|
|||||||
RecipientRole,
|
RecipientRole,
|
||||||
} from '@documenso/prisma/client';
|
} from '@documenso/prisma/client';
|
||||||
import { seedUser } from '@documenso/prisma/seed/users';
|
import { seedUser } from '@documenso/prisma/seed/users';
|
||||||
import type { TCreateEnvelopeItemsRequest } from '@documenso/trpc/server/envelope-router/create-envelope-items.types';
|
import type { TCreateEnvelopeItemsPayload } from '@documenso/trpc/server/envelope-router/create-envelope-items.types';
|
||||||
import type {
|
import type {
|
||||||
TCreateEnvelopePayload,
|
TCreateEnvelopePayload,
|
||||||
TCreateEnvelopeResponse,
|
TCreateEnvelopeResponse,
|
||||||
@ -403,28 +403,20 @@ test.describe('API V2 Envelopes', () => {
|
|||||||
expect(unauthRequest.status()).toBe(404);
|
expect(unauthRequest.status()).toBe(404);
|
||||||
|
|
||||||
// Step 2: Create second envelope item via API
|
// Step 2: Create second envelope item via API
|
||||||
// Todo: Envelopes - Use API Route
|
const createEnvelopeItemsPayload: TCreateEnvelopeItemsPayload = {
|
||||||
const fieldMetaDocumentData = await prisma.documentData.create({
|
|
||||||
data: {
|
|
||||||
type: 'BYTES_64',
|
|
||||||
data: fieldMetaPdf.toString('base64'),
|
|
||||||
initialData: fieldMetaPdf.toString('base64'),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const createEnvelopeItemsRequest: TCreateEnvelopeItemsRequest = {
|
|
||||||
envelopeId: createdEnvelope.id,
|
envelopeId: createdEnvelope.id,
|
||||||
data: [
|
|
||||||
{
|
|
||||||
title: 'Field Meta Test',
|
|
||||||
documentDataId: fieldMetaDocumentData.id,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createEnvelopeItemFormData = new FormData();
|
||||||
|
createEnvelopeItemFormData.append('payload', JSON.stringify(createEnvelopeItemsPayload));
|
||||||
|
createEnvelopeItemFormData.append(
|
||||||
|
'files',
|
||||||
|
new File([fieldMetaPdf], 'field-meta.pdf', { type: 'application/pdf' }),
|
||||||
|
);
|
||||||
|
|
||||||
const createItemsRes = await request.post(`${baseUrl}/envelope/item/create-many`, {
|
const createItemsRes = await request.post(`${baseUrl}/envelope/item/create-many`, {
|
||||||
headers: { Authorization: `Bearer ${tokenA}` },
|
headers: { Authorization: `Bearer ${tokenA}` },
|
||||||
data: createEnvelopeItemsRequest,
|
multipart: createEnvelopeItemFormData,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(createItemsRes.ok()).toBeTruthy();
|
expect(createItemsRes.ok()).toBeTruthy();
|
||||||
|
|||||||
@ -23,7 +23,7 @@ type EnvelopeRenderOverrideSettings = {
|
|||||||
type EnvelopeRenderItem = TEnvelope['envelopeItems'][number];
|
type EnvelopeRenderItem = TEnvelope['envelopeItems'][number];
|
||||||
|
|
||||||
type EnvelopeRenderProviderValue = {
|
type EnvelopeRenderProviderValue = {
|
||||||
getPdfBuffer: (documentDataId: string) => FileData | null;
|
getPdfBuffer: (envelopeItemId: string) => FileData | null;
|
||||||
envelopeItems: EnvelopeRenderItem[];
|
envelopeItems: EnvelopeRenderItem[];
|
||||||
currentEnvelopeItem: EnvelopeRenderItem | null;
|
currentEnvelopeItem: EnvelopeRenderItem | null;
|
||||||
setCurrentEnvelopeItem: (envelopeItemId: string) => void;
|
setCurrentEnvelopeItem: (envelopeItemId: string) => void;
|
||||||
@ -103,14 +103,14 @@ export const EnvelopeRenderProvider = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const loadEnvelopeItemPdfFile = async (envelopeItem: EnvelopeRenderItem) => {
|
const loadEnvelopeItemPdfFile = async (envelopeItem: EnvelopeRenderItem) => {
|
||||||
if (files[envelopeItem.documentDataId]?.status === 'loading') {
|
if (files[envelopeItem.id]?.status === 'loading') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!files[envelopeItem.documentDataId]) {
|
if (!files[envelopeItem.id]) {
|
||||||
setFiles((prev) => ({
|
setFiles((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[envelopeItem.documentDataId]: {
|
[envelopeItem.id]: {
|
||||||
status: 'loading',
|
status: 'loading',
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
@ -129,7 +129,7 @@ export const EnvelopeRenderProvider = ({
|
|||||||
|
|
||||||
setFiles((prev) => ({
|
setFiles((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[envelopeItem.documentDataId]: {
|
[envelopeItem.id]: {
|
||||||
file: new Uint8Array(file),
|
file: new Uint8Array(file),
|
||||||
status: 'loaded',
|
status: 'loaded',
|
||||||
},
|
},
|
||||||
@ -139,7 +139,7 @@ export const EnvelopeRenderProvider = ({
|
|||||||
|
|
||||||
setFiles((prev) => ({
|
setFiles((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[envelopeItem.documentDataId]: {
|
[envelopeItem.id]: {
|
||||||
status: 'error',
|
status: 'error',
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
@ -147,8 +147,8 @@ export const EnvelopeRenderProvider = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getPdfBuffer = useCallback(
|
const getPdfBuffer = useCallback(
|
||||||
(documentDataId: string) => {
|
(envelopeItemId: string) => {
|
||||||
return files[documentDataId] || null;
|
return files[envelopeItemId] || null;
|
||||||
},
|
},
|
||||||
[files],
|
[files],
|
||||||
);
|
);
|
||||||
@ -168,7 +168,7 @@ export const EnvelopeRenderProvider = ({
|
|||||||
|
|
||||||
// Look for any missing pdf files and load them.
|
// Look for any missing pdf files and load them.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const missingFiles = envelope.envelopeItems.filter((item) => !files[item.documentDataId]);
|
const missingFiles = envelope.envelopeItems.filter((item) => !files[item.id]);
|
||||||
|
|
||||||
for (const item of missingFiles) {
|
for (const item of missingFiles) {
|
||||||
void loadEnvelopeItemPdfFile(item);
|
void loadEnvelopeItemPdfFile(item);
|
||||||
|
|||||||
@ -74,7 +74,6 @@ export const ZEnvelopeForSigningResponse = z.object({
|
|||||||
envelopeId: true,
|
envelopeId: true,
|
||||||
id: true,
|
id: true,
|
||||||
title: true,
|
title: true,
|
||||||
documentDataId: true,
|
|
||||||
order: true,
|
order: true,
|
||||||
}).array(),
|
}).array(),
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import { EnvelopeSchema } from '@documenso/prisma/generated/zod/modelSchema/Enve
|
|||||||
import { TeamSchema } from '@documenso/prisma/generated/zod/modelSchema/TeamSchema';
|
import { TeamSchema } from '@documenso/prisma/generated/zod/modelSchema/TeamSchema';
|
||||||
import TemplateDirectLinkSchema from '@documenso/prisma/generated/zod/modelSchema/TemplateDirectLinkSchema';
|
import TemplateDirectLinkSchema from '@documenso/prisma/generated/zod/modelSchema/TemplateDirectLinkSchema';
|
||||||
|
|
||||||
import { ZFieldSchema } from './field';
|
import { ZEnvelopeFieldSchema } from './field';
|
||||||
import { ZRecipientLiteSchema } from './recipient';
|
import { ZEnvelopeRecipientLiteSchema } from './recipient';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The full envelope response schema.
|
* The full envelope response schema.
|
||||||
@ -56,19 +56,12 @@ export const ZEnvelopeSchema = EnvelopeSchema.pick({
|
|||||||
emailId: true,
|
emailId: true,
|
||||||
emailReplyTo: true,
|
emailReplyTo: true,
|
||||||
}),
|
}),
|
||||||
recipients: ZRecipientLiteSchema.omit({
|
recipients: ZEnvelopeRecipientLiteSchema.array(),
|
||||||
documentId: true,
|
fields: ZEnvelopeFieldSchema.array(),
|
||||||
templateId: true,
|
|
||||||
}).array(),
|
|
||||||
fields: ZFieldSchema.omit({
|
|
||||||
documentId: true,
|
|
||||||
templateId: true,
|
|
||||||
}).array(),
|
|
||||||
envelopeItems: EnvelopeItemSchema.pick({
|
envelopeItems: EnvelopeItemSchema.pick({
|
||||||
envelopeId: true,
|
envelopeId: true,
|
||||||
id: true,
|
id: true,
|
||||||
title: true,
|
title: true,
|
||||||
documentDataId: true,
|
|
||||||
order: true,
|
order: true,
|
||||||
}).array(),
|
}).array(),
|
||||||
directLink: TemplateDirectLinkSchema.pick({
|
directLink: TemplateDirectLinkSchema.pick({
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
|||||||
import { getEnvelopeWhereInput } from '@documenso/lib/server-only/envelope/get-envelope-by-id';
|
import { getEnvelopeWhereInput } from '@documenso/lib/server-only/envelope/get-envelope-by-id';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import { prefixedId } from '@documenso/lib/universal/id';
|
import { prefixedId } from '@documenso/lib/universal/id';
|
||||||
|
import { putNormalizedPdfFileServerSide } from '@documenso/lib/universal/upload/put-file.server';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||||
import { canEnvelopeItemsBeModified } from '@documenso/lib/utils/envelope';
|
import { canEnvelopeItemsBeModified } from '@documenso/lib/utils/envelope';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
@ -13,7 +14,6 @@ import {
|
|||||||
} from './create-envelope-items.types';
|
} from './create-envelope-items.types';
|
||||||
|
|
||||||
export const createEnvelopeItemsRoute = authenticatedProcedure
|
export const createEnvelopeItemsRoute = authenticatedProcedure
|
||||||
// Todo: Envelopes - Pending direct uploads
|
|
||||||
.meta({
|
.meta({
|
||||||
openapi: {
|
openapi: {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -27,7 +27,8 @@ export const createEnvelopeItemsRoute = authenticatedProcedure
|
|||||||
.output(ZCreateEnvelopeItemsResponseSchema)
|
.output(ZCreateEnvelopeItemsResponseSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { user, teamId, metadata } = ctx;
|
const { user, teamId, metadata } = ctx;
|
||||||
const { envelopeId, data: items } = input;
|
const { payload, files } = input;
|
||||||
|
const { envelopeId } = payload;
|
||||||
|
|
||||||
ctx.logger.info({
|
ctx.logger.info({
|
||||||
input: {
|
input: {
|
||||||
@ -81,7 +82,7 @@ export const createEnvelopeItemsRoute = authenticatedProcedure
|
|||||||
const organisationClaim = envelope.team.organisation.organisationClaim;
|
const organisationClaim = envelope.team.organisation.organisationClaim;
|
||||||
|
|
||||||
const remainingEnvelopeItems =
|
const remainingEnvelopeItems =
|
||||||
organisationClaim.envelopeItemCount - envelope.envelopeItems.length - items.length;
|
organisationClaim.envelopeItemCount - envelope.envelopeItems.length - files.length;
|
||||||
|
|
||||||
if (remainingEnvelopeItems < 0) {
|
if (remainingEnvelopeItems < 0) {
|
||||||
throw new AppError('ENVELOPE_ITEM_LIMIT_EXCEEDED', {
|
throw new AppError('ENVELOPE_ITEM_LIMIT_EXCEEDED', {
|
||||||
@ -90,41 +91,24 @@ export const createEnvelopeItemsRoute = authenticatedProcedure
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const foundDocumentData = await prisma.documentData.findMany({
|
// For each file, stream to s3 and create the document data.
|
||||||
where: {
|
const envelopeItems = await Promise.all(
|
||||||
id: {
|
files.map(async (file) => {
|
||||||
in: items.map((item) => item.documentDataId),
|
const { id: documentDataId } = await putNormalizedPdfFileServerSide(file);
|
||||||
},
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
envelopeItem: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check that all the document data was found.
|
return {
|
||||||
if (foundDocumentData.length !== items.length) {
|
title: file.name,
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
documentDataId,
|
||||||
message: 'Document data not found',
|
};
|
||||||
});
|
}),
|
||||||
}
|
);
|
||||||
|
|
||||||
// Check that it doesn't already have an envelope item.
|
|
||||||
if (foundDocumentData.some((documentData) => documentData.envelopeItem?.id)) {
|
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
|
||||||
message: 'Document data not found',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentHighestOrderValue =
|
const currentHighestOrderValue =
|
||||||
envelope.envelopeItems[envelope.envelopeItems.length - 1]?.order ?? 1;
|
envelope.envelopeItems[envelope.envelopeItems.length - 1]?.order ?? 1;
|
||||||
|
|
||||||
const result = await prisma.$transaction(async (tx) => {
|
const result = await prisma.$transaction(async (tx) => {
|
||||||
const createdItems = await tx.envelopeItem.createManyAndReturn({
|
const createdItems = await tx.envelopeItem.createManyAndReturn({
|
||||||
data: items.map((item) => ({
|
data: envelopeItems.map((item) => ({
|
||||||
id: prefixedId('envelope_item'),
|
id: prefixedId('envelope_item'),
|
||||||
envelopeId,
|
envelopeId,
|
||||||
title: item.title,
|
title: item.title,
|
||||||
|
|||||||
@ -1,38 +1,29 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import { zfd } from 'zod-form-data';
|
||||||
|
|
||||||
import DocumentDataSchema from '@documenso/prisma/generated/zod/modelSchema/DocumentDataSchema';
|
|
||||||
import EnvelopeItemSchema from '@documenso/prisma/generated/zod/modelSchema/EnvelopeItemSchema';
|
import EnvelopeItemSchema from '@documenso/prisma/generated/zod/modelSchema/EnvelopeItemSchema';
|
||||||
|
|
||||||
import { ZDocumentTitleSchema } from '../document-router/schema';
|
import { zodFormData } from '../../utils/zod-form-data';
|
||||||
|
|
||||||
export const ZCreateEnvelopeItemsRequestSchema = z.object({
|
export const ZCreateEnvelopeItemsPayloadSchema = z.object({
|
||||||
envelopeId: z.string(),
|
envelopeId: z.string(),
|
||||||
data: z
|
// data: z.object() // Currently not used.
|
||||||
.object({
|
});
|
||||||
title: ZDocumentTitleSchema,
|
|
||||||
documentDataId: z.string(),
|
export const ZCreateEnvelopeItemsRequestSchema = zodFormData({
|
||||||
})
|
payload: zfd.json(ZCreateEnvelopeItemsPayloadSchema),
|
||||||
.array(),
|
files: zfd.repeatableOfType(zfd.file()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ZCreateEnvelopeItemsResponseSchema = z.object({
|
export const ZCreateEnvelopeItemsResponseSchema = z.object({
|
||||||
createdEnvelopeItems: EnvelopeItemSchema.pick({
|
createdEnvelopeItems: EnvelopeItemSchema.pick({
|
||||||
id: true,
|
id: true,
|
||||||
title: true,
|
title: true,
|
||||||
documentDataId: true,
|
|
||||||
envelopeId: true,
|
envelopeId: true,
|
||||||
order: true,
|
order: true,
|
||||||
})
|
}).array(),
|
||||||
.extend({
|
|
||||||
documentData: DocumentDataSchema.pick({
|
|
||||||
type: true,
|
|
||||||
id: true,
|
|
||||||
data: true,
|
|
||||||
initialData: true,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.array(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export type TCreateEnvelopeItemsPayload = z.infer<typeof ZCreateEnvelopeItemsPayloadSchema>;
|
||||||
export type TCreateEnvelopeItemsRequest = z.infer<typeof ZCreateEnvelopeItemsRequestSchema>;
|
export type TCreateEnvelopeItemsRequest = z.infer<typeof ZCreateEnvelopeItemsRequestSchema>;
|
||||||
export type TCreateEnvelopeItemsResponse = z.infer<typeof ZCreateEnvelopeItemsResponseSchema>;
|
export type TCreateEnvelopeItemsResponse = z.infer<typeof ZCreateEnvelopeItemsResponseSchema>;
|
||||||
|
|||||||
@ -78,7 +78,7 @@ export const PdfViewerKonva = ({
|
|||||||
const [pdfError, setPdfError] = useState(false);
|
const [pdfError, setPdfError] = useState(false);
|
||||||
|
|
||||||
const envelopeItemFile = useMemo(() => {
|
const envelopeItemFile = useMemo(() => {
|
||||||
const data = getPdfBuffer(currentEnvelopeItem?.documentDataId || '');
|
const data = getPdfBuffer(currentEnvelopeItem?.id || '');
|
||||||
|
|
||||||
if (!data || data.status !== 'loaded') {
|
if (!data || data.status !== 'loaded') {
|
||||||
return null;
|
return null;
|
||||||
@ -87,7 +87,7 @@ export const PdfViewerKonva = ({
|
|||||||
return {
|
return {
|
||||||
data: new Uint8Array(data.file),
|
data: new Uint8Array(data.file),
|
||||||
};
|
};
|
||||||
}, [currentEnvelopeItem?.documentDataId, getPdfBuffer]);
|
}, [currentEnvelopeItem?.id, getPdfBuffer]);
|
||||||
|
|
||||||
const onDocumentLoaded = useCallback(
|
const onDocumentLoaded = useCallback(
|
||||||
(doc: PDFDocumentProxy) => {
|
(doc: PDFDocumentProxy) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user