diff --git a/apps/web/src/app/(dashboard)/templates/data-table-templates.tsx b/apps/web/src/app/(dashboard)/templates/data-table-templates.tsx
index 309695c88..e878d8df2 100644
--- a/apps/web/src/app/(dashboard)/templates/data-table-templates.tsx
+++ b/apps/web/src/app/(dashboard)/templates/data-table-templates.tsx
@@ -1,30 +1,31 @@
'use client';
-import { useState, useTransition } from 'react';
+import { useTransition } from 'react';
import Link from 'next/link';
-import { useRouter } from 'next/navigation';
-import { AlertTriangle, Loader, Plus } from 'lucide-react';
+import { AlertTriangle, Loader } from 'lucide-react';
import { useLimits } from '@documenso/ee/server-only/limits/provider/client';
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
-import type { Template } from '@documenso/prisma/client';
-import { trpc } from '@documenso/trpc/react';
+import type { Recipient, Template } from '@documenso/prisma/client';
import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert';
-import { Button } from '@documenso/ui/primitives/button';
import { DataTable } from '@documenso/ui/primitives/data-table';
import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination';
-import { useToast } from '@documenso/ui/primitives/use-toast';
import { LocaleDate } from '~/components/formatter/locale-date';
import { TemplateType } from '~/components/formatter/template-type';
import { DataTableActionDropdown } from './data-table-action-dropdown';
import { DataTableTitle } from './data-table-title';
+import { UseTemplateDialog } from './use-template-dialog';
+
+type TemplateWithRecipient = Template & {
+ Recipient: Recipient[];
+};
type TemplatesDataTableProps = {
- templates: Template[];
+ templates: TemplateWithRecipient[];
perPage: number;
page: number;
totalPages: number;
@@ -47,14 +48,6 @@ export const TemplatesDataTable = ({
const { remaining } = useLimits();
- const router = useRouter();
-
- const { toast } = useToast();
- const [loadingStates, setLoadingStates] = useState<{ [key: string]: boolean }>({});
-
- const { mutateAsync: createDocumentFromTemplate } =
- trpc.template.createDocumentFromTemplate.useMutation();
-
const onPaginationChange = (page: number, perPage: number) => {
startTransition(() => {
updateSearchParams({
@@ -64,28 +57,6 @@ export const TemplatesDataTable = ({
});
};
- const onUseButtonClick = async (templateId: number) => {
- try {
- const { id } = await createDocumentFromTemplate({
- templateId,
- });
-
- toast({
- title: 'Document created',
- description: 'Your document has been created from the template successfully.',
- duration: 5000,
- });
-
- router.push(`${documentRootPath}/${id}`);
- } catch (err) {
- toast({
- title: 'Error',
- description: 'An error occurred while creating document from template.',
- variant: 'destructive',
- });
- }
- };
-
return (
{remaining.documents === 0 && (
@@ -121,22 +92,13 @@ export const TemplatesDataTable = ({
header: 'Actions',
accessorKey: 'actions',
cell: ({ row }) => {
- const isRowLoading = loadingStates[row.original.id];
-
return (
-
+
;
+
+export type UseTemplateDialogProps = {
+ templateId: number;
+ recipients: Recipient[];
+ documentRootPath: string;
+};
+
+export function UseTemplateDialog({
+ recipients,
+ documentRootPath,
+ templateId,
+}: UseTemplateDialogProps) {
+ const router = useRouter();
+ const { toast } = useToast();
+
+ const {
+ control,
+ handleSubmit,
+ formState: { errors, isSubmitting },
+ } = useForm({
+ resolver: zodResolver(ZAddRecipientsForNewDocumentSchema),
+ defaultValues: {
+ recipients:
+ recipients.length > 0
+ ? recipients.map((recipient) => ({
+ nativeId: recipient.id,
+ formId: String(recipient.id),
+ name: recipient.name,
+ email: recipient.email,
+ role: recipient.role,
+ }))
+ : [
+ {
+ name: '',
+ email: '',
+ role: RecipientRole.SIGNER,
+ },
+ ],
+ },
+ });
+
+ const { mutateAsync: createDocumentFromTemplate, isLoading: isCreatingDocumentFromTemplate } =
+ trpc.template.createDocumentFromTemplate.useMutation();
+
+ const onSubmit = async (data: TAddRecipientsForNewDocumentSchema) => {
+ try {
+ const { id } = await createDocumentFromTemplate({
+ templateId,
+ recipients: data.recipients,
+ });
+
+ toast({
+ title: 'Document created',
+ description: 'Your document has been created from the template successfully.',
+ duration: 5000,
+ });
+
+ router.push(`${documentRootPath}/${id}`);
+ } catch (err) {
+ toast({
+ title: 'Error',
+ description: 'An error occurred while creating document from template.',
+ variant: 'destructive',
+ });
+ }
+ };
+
+ const onCreateDocumentFromTemplate = handleSubmit(onSubmit);
+
+ const { fields: formRecipients } = useFieldArray({
+ control,
+ name: 'recipients',
+ });
+
+ return (
+
+ );
+}
diff --git a/packages/lib/server-only/template/find-templates.ts b/packages/lib/server-only/template/find-templates.ts
index d453d28a0..69b43f9b9 100644
--- a/packages/lib/server-only/template/find-templates.ts
+++ b/packages/lib/server-only/template/find-templates.ts
@@ -38,6 +38,7 @@ export const findTemplates = async ({
include: {
templateDocumentData: true,
Field: true,
+ Recipient: true,
},
skip: Math.max(page - 1, 0) * perPage,
orderBy: {
diff --git a/packages/trpc/server/template-router/router.ts b/packages/trpc/server/template-router/router.ts
index 7417e7d00..3f5346554 100644
--- a/packages/trpc/server/template-router/router.ts
+++ b/packages/trpc/server/template-router/router.ts
@@ -52,6 +52,7 @@ export const templateRouter = router({
return await createDocumentFromTemplate({
templateId,
userId: ctx.user.id,
+ recipients: input.recipients,
});
} catch (err) {
throw new TRPCError({
diff --git a/packages/trpc/server/template-router/schema.ts b/packages/trpc/server/template-router/schema.ts
index 3d87d4b4f..561bad109 100644
--- a/packages/trpc/server/template-router/schema.ts
+++ b/packages/trpc/server/template-router/schema.ts
@@ -1,5 +1,7 @@
import { z } from 'zod';
+import { RecipientRole } from '@documenso/prisma/client';
+
export const ZCreateTemplateMutationSchema = z.object({
title: z.string().min(1).trim(),
teamId: z.number().optional(),
@@ -8,6 +10,15 @@ export const ZCreateTemplateMutationSchema = z.object({
export const ZCreateDocumentFromTemplateMutationSchema = z.object({
templateId: z.number(),
+ recipients: z
+ .array(
+ z.object({
+ email: z.string().email(),
+ name: z.string(),
+ role: z.nativeEnum(RecipientRole),
+ }),
+ )
+ .optional(),
});
export const ZDuplicateTemplateMutationSchema = z.object({
diff --git a/packages/ui/primitives/document-flow/add-signers.tsx b/packages/ui/primitives/document-flow/add-signers.tsx
index b1341c6ca..06e0a2af2 100644
--- a/packages/ui/primitives/document-flow/add-signers.tsx
+++ b/packages/ui/primitives/document-flow/add-signers.tsx
@@ -32,7 +32,7 @@ import {
import { ShowFieldItem } from './show-field-item';
import type { DocumentFlowStep } from './types';
-const ROLE_ICONS: Record = {
+export const ROLE_ICONS: Record = {
SIGNER: ,
APPROVER: ,
CC: ,