mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 08:42:12 +10:00
feat: add support for attachments in template management
- Enhanced TemplateEditForm to include attachments in the template data. - Updated createDocumentFromTemplate to handle attachment creation. - Modified updateTemplate to manage attachment updates and deletions. - Integrated attachments into ZTemplateSchema and ZAddTemplateSettingsFormSchema for validation. - Improved getTemplateById to fetch attachments alongside other template data.
This commit is contained in:
@ -136,6 +136,7 @@ export const TemplateEditForm = ({
|
||||
visibility: data.visibility,
|
||||
globalAccessAuth: data.globalAccessAuth ?? null,
|
||||
globalActionAuth: data.globalActionAuth ?? null,
|
||||
attachments: data.attachments ?? [],
|
||||
},
|
||||
meta: {
|
||||
...data.meta,
|
||||
@ -165,6 +166,14 @@ export const TemplateEditForm = ({
|
||||
await Promise.all([
|
||||
updateTemplateSettings({
|
||||
templateId: template.id,
|
||||
data: {
|
||||
attachments: template.attachments?.map((attachment) => ({
|
||||
id: attachment.id,
|
||||
label: attachment.label,
|
||||
url: attachment.url,
|
||||
formId: attachment.id,
|
||||
})),
|
||||
},
|
||||
meta: {
|
||||
signingOrder: data.signingOrder,
|
||||
allowDictateNextSigner: data.allowDictateNextSigner,
|
||||
|
||||
@ -296,6 +296,7 @@ export const createDocumentFromTemplate = async ({
|
||||
fields: true,
|
||||
},
|
||||
},
|
||||
attachments: true,
|
||||
templateDocumentData: true,
|
||||
templateMeta: true,
|
||||
team: {
|
||||
@ -385,6 +386,15 @@ export const createDocumentFromTemplate = async ({
|
||||
}),
|
||||
visibility: template.visibility || template.team?.teamGlobalSettings?.documentVisibility,
|
||||
useLegacyFieldInsertion: template.useLegacyFieldInsertion ?? false,
|
||||
attachments: {
|
||||
create: template.attachments.map((attachment) => ({
|
||||
type: attachment.type,
|
||||
label: attachment.label,
|
||||
url: attachment.url,
|
||||
createdAt: attachment.createdAt,
|
||||
updatedAt: attachment.updatedAt,
|
||||
})),
|
||||
},
|
||||
documentMeta: {
|
||||
create: {
|
||||
subject: override?.subject || template.templateMeta?.subject,
|
||||
|
||||
@ -34,6 +34,7 @@ export const getTemplateById = async ({ id, userId, teamId }: GetTemplateByIdOpt
|
||||
templateMeta: true,
|
||||
recipients: true,
|
||||
fields: true,
|
||||
attachments: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { DocumentVisibility, Template, TemplateMeta } from '@prisma/client';
|
||||
import type { Attachment, DocumentVisibility, Template, TemplateMeta } from '@prisma/client';
|
||||
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@ -21,6 +21,7 @@ export type UpdateTemplateOptions = {
|
||||
publicDescription?: string;
|
||||
type?: Template['type'];
|
||||
useLegacyFieldInsertion?: boolean;
|
||||
attachments?: Pick<Attachment, 'id' | 'label' | 'url'>[];
|
||||
};
|
||||
meta?: Partial<Omit<TemplateMeta, 'id' | 'templateId'>>;
|
||||
};
|
||||
@ -53,6 +54,7 @@ export const updateTemplate = async ({
|
||||
},
|
||||
include: {
|
||||
templateMeta: true,
|
||||
attachments: true,
|
||||
},
|
||||
});
|
||||
|
||||
@ -104,6 +106,29 @@ export const updateTemplate = async ({
|
||||
publicDescription: data?.publicDescription,
|
||||
publicTitle: data?.publicTitle,
|
||||
useLegacyFieldInsertion: data?.useLegacyFieldInsertion,
|
||||
attachments: {
|
||||
deleteMany: {
|
||||
templateId,
|
||||
id: {
|
||||
notIn: data?.attachments?.map((attachment) => attachment.id),
|
||||
},
|
||||
},
|
||||
upsert: data?.attachments?.map((attachment) => ({
|
||||
where: {
|
||||
id: attachment.id,
|
||||
templateId,
|
||||
},
|
||||
update: {
|
||||
label: attachment.label,
|
||||
url: attachment.url,
|
||||
},
|
||||
create: {
|
||||
id: attachment.id,
|
||||
label: attachment.label,
|
||||
url: attachment.url,
|
||||
},
|
||||
})),
|
||||
},
|
||||
authOptions,
|
||||
templateMeta: {
|
||||
upsert: {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { AttachmentSchema } from '@documenso/prisma/generated/zod/modelSchema/AttachmentSchema';
|
||||
import { DocumentDataSchema } from '@documenso/prisma/generated/zod/modelSchema/DocumentDataSchema';
|
||||
import TeamSchema from '@documenso/prisma/generated/zod/modelSchema/TeamSchema';
|
||||
import { TemplateDirectLinkSchema } from '@documenso/prisma/generated/zod/modelSchema/TemplateDirectLinkSchema';
|
||||
@ -62,6 +63,14 @@ export const ZTemplateSchema = TemplateSchema.pick({
|
||||
}),
|
||||
recipients: ZRecipientLiteSchema.array(),
|
||||
fields: ZFieldSchema.array(),
|
||||
attachments: AttachmentSchema.pick({
|
||||
id: true,
|
||||
label: true,
|
||||
url: true,
|
||||
type: true,
|
||||
})
|
||||
.array()
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export type TTemplate = z.infer<typeof ZTemplateSchema>;
|
||||
|
||||
@ -312,6 +312,8 @@ enum DocumentVisibility {
|
||||
ADMIN
|
||||
}
|
||||
|
||||
// Only "LINK" is supported for now.
|
||||
// All other attachment types are not yet supported.
|
||||
enum AttachmentType {
|
||||
FILE
|
||||
VIDEO
|
||||
|
||||
@ -14,6 +14,7 @@ import {
|
||||
ZTemplateManySchema,
|
||||
ZTemplateSchema,
|
||||
} from '@documenso/lib/types/template';
|
||||
import AttachmentSchema from '@documenso/prisma/generated/zod/modelSchema/AttachmentSchema';
|
||||
import { TemplateDirectLinkSchema } from '@documenso/prisma/generated/zod/modelSchema/TemplateDirectLinkSchema';
|
||||
|
||||
import {
|
||||
@ -154,6 +155,16 @@ export const ZUpdateTemplateRequestSchema = z.object({
|
||||
.optional(),
|
||||
type: z.nativeEnum(TemplateType).optional(),
|
||||
useLegacyFieldInsertion: z.boolean().optional(),
|
||||
attachments: AttachmentSchema.pick({
|
||||
id: true,
|
||||
label: true,
|
||||
url: true,
|
||||
})
|
||||
.extend({
|
||||
formId: z.string().min(1),
|
||||
})
|
||||
.array()
|
||||
.optional(),
|
||||
})
|
||||
.optional(),
|
||||
meta: z
|
||||
|
||||
@ -124,6 +124,11 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
emailSettings: ZDocumentEmailSettingsSchema.parse(template?.templateMeta?.emailSettings),
|
||||
signatureTypes: extractTeamSignatureSettings(template?.templateMeta),
|
||||
},
|
||||
attachments: template.attachments?.map((attachment) => ({
|
||||
...attachment,
|
||||
id: String(attachment.id),
|
||||
formId: String(attachment.id),
|
||||
})),
|
||||
},
|
||||
});
|
||||
|
||||
@ -138,12 +143,20 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
|
||||
const onAddAttachment = () => {
|
||||
appendAttachment({
|
||||
id: nanoid(12),
|
||||
formId: nanoid(12),
|
||||
label: '',
|
||||
link: '',
|
||||
url: '',
|
||||
});
|
||||
};
|
||||
|
||||
const onRemoveAttachment = (index: number) => {
|
||||
removeAttachment(index);
|
||||
|
||||
const updatedAttachments = attachments.filter((_, idx) => idx !== index);
|
||||
form.setValue('attachments', updatedAttachments);
|
||||
};
|
||||
|
||||
const { stepIndex, currentStep, totalSteps, previousStep } = useStep();
|
||||
|
||||
const distributionMethod = form.watch('meta.distributionMethod');
|
||||
@ -622,7 +635,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
<div className="flex-1">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`attachments.${index}.link`}
|
||||
name={`attachments.${index}.url`}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="flex flex-row items-center">
|
||||
@ -641,7 +654,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
|
||||
<div className="flex-none pt-8">
|
||||
<button
|
||||
onClick={() => removeAttachment(index)}
|
||||
onClick={() => onRemoveAttachment(index)}
|
||||
className="hover:bg-muted rounded-md"
|
||||
>
|
||||
<Trash className="h-4 w-4" />
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
} from '@documenso/lib/types/document-auth';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import { isValidRedirectUrl } from '@documenso/lib/utils/is-valid-redirect-url';
|
||||
import { AttachmentSchema } from '@documenso/prisma/generated/zod/modelSchema/AttachmentSchema';
|
||||
import {
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
ZDocumentMetaTimezoneSchema,
|
||||
@ -55,13 +56,16 @@ export const ZAddTemplateSettingsFormSchema = z.object({
|
||||
message: msg`At least one signature type must be enabled`.id,
|
||||
}),
|
||||
}),
|
||||
attachments: z.array(
|
||||
z.object({
|
||||
attachments: AttachmentSchema.pick({
|
||||
id: true,
|
||||
label: true,
|
||||
url: true,
|
||||
})
|
||||
.extend({
|
||||
formId: z.string().min(1),
|
||||
label: z.string(),
|
||||
link: z.string(),
|
||||
}),
|
||||
),
|
||||
})
|
||||
.array()
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export type TAddTemplateSettingsFormSchema = z.infer<typeof ZAddTemplateSettingsFormSchema>;
|
||||
|
||||
Reference in New Issue
Block a user