fix: refactor prisma relations (#1581)

This commit is contained in:
David Nguyen
2025-01-13 13:41:53 +11:00
committed by GitHub
parent 48b55758e3
commit 7d0a9c6439
143 changed files with 687 additions and 790 deletions

View File

@ -59,7 +59,7 @@ export default async function AdminDocumentDetailsPage({ params }: AdminDocument
<Trans>Admin Actions</Trans>
</h2>
<AdminActions className="mt-2" document={document} recipients={document.Recipient} />
<AdminActions className="mt-2" document={document} recipients={document.recipients} />
<hr className="my-4" />
<h2 className="text-lg font-semibold">
@ -68,7 +68,7 @@ export default async function AdminDocumentDetailsPage({ params }: AdminDocument
<div className="mt-4">
<Accordion type="multiple" className="space-y-4">
{document.Recipient.map((recipient) => (
{document.recipients.map((recipient) => (
<AccordionItem
key={recipient.id}
value={recipient.id.toString()}

View File

@ -39,9 +39,9 @@ type TAdminUpdateRecipientFormSchema = z.infer<typeof ZAdminUpdateRecipientFormS
export type RecipientItemProps = {
recipient: Recipient & {
Field: Array<
fields: Array<
Field & {
Signature: Signature | null;
signature: Signature | null;
}
>;
};
@ -89,13 +89,13 @@ export const RecipientItem = ({ recipient }: RecipientItemProps) => {
accessorKey: 'signature',
cell: ({ row }) => (
<div>
{row.original.Signature?.typedSignature && (
<span>{row.original.Signature.typedSignature}</span>
{row.original.signature?.typedSignature && (
<span>{row.original.signature.typedSignature}</span>
)}
{row.original.Signature?.signatureImageAsBase64 && (
{row.original.signature?.signatureImageAsBase64 && (
<img
src={row.original.Signature.signatureImageAsBase64}
src={row.original.signature.signatureImageAsBase64}
alt="Signature"
className="h-12 w-full dark:invert"
/>
@ -103,7 +103,7 @@ export const RecipientItem = ({ recipient }: RecipientItemProps) => {
</div>
),
},
] satisfies DataTableColumnDef<(typeof recipient)['Field'][number]>[];
] satisfies DataTableColumnDef<(typeof recipient)['fields'][number]>[];
}, []);
const onUpdateRecipientFormSubmit = async ({ name, email }: TAdminUpdateRecipientFormSchema) => {
@ -190,7 +190,7 @@ export const RecipientItem = ({ recipient }: RecipientItemProps) => {
<Trans>Fields</Trans>
</h2>
<DataTable columns={columns} data={recipient.Field} />
<DataTable columns={columns} data={recipient.fields} />
</div>
);
};

View File

@ -86,14 +86,14 @@ export const AdminDocumentResults = () => {
header: _(msg`Owner`),
accessorKey: 'owner',
cell: ({ row }) => {
const avatarFallbackText = row.original.User.name
? extractInitials(row.original.User.name)
: row.original.User.email.slice(0, 1).toUpperCase();
const avatarFallbackText = row.original.user.name
? extractInitials(row.original.user.name)
: row.original.user.email.slice(0, 1).toUpperCase();
return (
<Tooltip delayDuration={200}>
<TooltipTrigger>
<Link href={`/admin/users/${row.original.User.id}`}>
<Link href={`/admin/users/${row.original.user.id}`}>
<Avatar className="dark:border-border h-12 w-12 border-2 border-solid border-white">
<AvatarFallback className="text-xs text-gray-400">
{avatarFallbackText}
@ -110,8 +110,8 @@ export const AdminDocumentResults = () => {
</Avatar>
<div className="text-muted-foreground flex flex-col text-sm">
<span>{row.original.User.name}</span>
<span>{row.original.User.email}</span>
<span>{row.original.user.name}</span>
<span>{row.original.user.email}</span>
</div>
</TooltipContent>
</Tooltip>

View File

@ -22,8 +22,8 @@ type UserData = {
name: string | null;
email: string;
roles: Role[];
Subscription?: SubscriptionLite[] | null;
Document: DocumentLite[];
subscriptions?: SubscriptionLite[] | null;
documents: DocumentLite[];
};
type SubscriptionLite = Pick<
@ -81,7 +81,7 @@ export const UsersDataTable = ({
header: _(msg`Subscription`),
accessorKey: 'subscription',
cell: ({ row }) => {
const foundIndividualSubscription = (row.original.Subscription ?? []).find((sub) =>
const foundIndividualSubscription = (row.original.subscriptions ?? []).find((sub) =>
individualPriceIds.includes(sub.priceId),
);
@ -92,7 +92,7 @@ export const UsersDataTable = ({
header: _(msg`Documents`),
accessorKey: 'documents',
cell: ({ row }) => {
return <div>{row.original.Document.length}</div>;
return <div>{row.original.documents?.length}</div>;
},
},
{

View File

@ -18,8 +18,8 @@ import { useToast } from '@documenso/ui/primitives/use-toast';
export type DocumentPageViewButtonProps = {
document: Document & {
User: Pick<User, 'id' | 'name' | 'email'>;
Recipient: Recipient[];
user: Pick<User, 'id' | 'name' | 'email'>;
recipients: Recipient[];
team: Pick<Team, 'id' | 'url'> | null;
};
team?: Pick<Team, 'id' | 'url'>;
@ -34,7 +34,7 @@ export const DocumentPageViewButton = ({ document }: DocumentPageViewButtonProps
return null;
}
const recipient = document.Recipient.find((recipient) => recipient.email === session.user.email);
const recipient = document.recipients.find((recipient) => recipient.email === session.user.email);
const isRecipient = !!recipient;
const isPending = document.status === DocumentStatus.PENDING;

View File

@ -41,8 +41,8 @@ import { DuplicateDocumentDialog } from '../duplicate-document-dialog';
export type DocumentPageViewDropdownProps = {
document: Document & {
User: Pick<User, 'id' | 'name' | 'email'>;
Recipient: Recipient[];
user: Pick<User, 'id' | 'name' | 'email'>;
recipients: Recipient[];
team: Pick<Team, 'id' | 'url'> | null;
};
team?: Pick<Team, 'id' | 'url'> & { teamEmail: TeamEmail | null };
@ -60,9 +60,9 @@ export const DocumentPageViewDropdown = ({ document, team }: DocumentPageViewDro
return null;
}
const recipient = document.Recipient.find((recipient) => recipient.email === session.user.email);
const recipient = document.recipients.find((recipient) => recipient.email === session.user.email);
const isOwner = document.User.id === session.user.id;
const isOwner = document.user.id === session.user.id;
const isDraft = document.status === DocumentStatus.DRAFT;
const isPending = document.status === DocumentStatus.PENDING;
const isDeleted = document.deletedAt !== null;
@ -94,7 +94,7 @@ export const DocumentPageViewDropdown = ({ document, team }: DocumentPageViewDro
}
};
const nonSignedRecipients = document.Recipient.filter((item) => item.signingStatus !== 'SIGNED');
const nonSignedRecipients = document.recipients.filter((item) => item.signingStatus !== 'SIGNED');
return (
<DropdownMenu>
@ -149,7 +149,7 @@ export const DocumentPageViewDropdown = ({ document, team }: DocumentPageViewDro
{canManageDocument && (
<DocumentRecipientLinkCopyDialog
recipients={document.Recipient}
recipients={document.recipients}
trigger={
<DropdownMenuItem
disabled={!isPending || isDeleted}

View File

@ -12,8 +12,8 @@ import type { Document, Recipient, User } from '@documenso/prisma/client';
export type DocumentPageViewInformationProps = {
userId: number;
document: Document & {
User: Pick<User, 'id' | 'name' | 'email'>;
Recipient: Recipient[];
user: Pick<User, 'id' | 'name' | 'email'>;
recipients: Recipient[];
};
};
@ -29,7 +29,8 @@ export const DocumentPageViewInformation = ({
return [
{
description: msg`Uploaded by`,
value: userId === document.userId ? _(msg`You`) : document.User.name ?? document.User.email,
value:
userId === document.userId ? _(msg`You`) : (document.user.name ?? document.user.email),
},
{
description: msg`Created`,

View File

@ -28,7 +28,7 @@ import { useToast } from '@documenso/ui/primitives/use-toast';
export type DocumentPageViewRecipientsProps = {
document: Document & {
Recipient: Recipient[];
recipients: Recipient[];
};
documentRootPath: string;
};
@ -40,7 +40,7 @@ export const DocumentPageViewRecipients = ({
const { _ } = useLingui();
const { toast } = useToast();
const recipients = document.Recipient;
const recipients = document.recipients;
return (
<section className="dark:bg-background border-border bg-widget flex flex-col rounded-xl border">

View File

@ -71,7 +71,7 @@ export const DocumentPageView = async ({ params, team }: DocumentPageViewProps)
const documentVisibility = document?.visibility;
const currentTeamMemberRole = team?.currentTeamMember?.role;
const isRecipient = document?.Recipient.find((recipient) => recipient.email === user.email);
const isRecipient = document?.recipients.find((recipient) => recipient.email === user.email);
let canAccessDocument = true;
if (team && !isRecipient && document?.userId !== user.id) {
@ -131,7 +131,7 @@ export const DocumentPageView = async ({ params, team }: DocumentPageViewProps)
const documentWithRecipients = {
...document,
Recipient: recipients,
recipients,
};
return (

View File

@ -71,7 +71,7 @@ export const EditDocumentForm = ({
},
);
const { Recipient: recipients, Field: fields } = document;
const { recipients, fields } = document;
const { mutateAsync: updateDocument } = trpc.document.setSettingsForDocument.useMutation({
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
@ -105,7 +105,7 @@ export const EditDocumentForm = ({
{
documentId: initialDocument.id,
},
(oldData) => ({ ...(oldData || initialDocument), Field: newFields }),
(oldData) => ({ ...(oldData || initialDocument), fields: newFields }),
);
},
});
@ -117,7 +117,7 @@ export const EditDocumentForm = ({
{
documentId: initialDocument.id,
},
(oldData) => ({ ...(oldData || initialDocument), Recipient: newRecipients }),
(oldData) => ({ ...(oldData || initialDocument), recipients: newRecipients }),
);
},
});

View File

@ -52,7 +52,7 @@ export const DocumentEditPageView = async ({ params, team }: DocumentEditPageVie
const documentVisibility = document?.visibility;
const currentTeamMemberRole = team?.currentTeamMember?.role;
const isRecipient = document?.Recipient.find((recipient) => recipient.email === user.email);
const isRecipient = document?.recipients.find((recipient) => recipient.email === user.email);
let canAccessDocument = true;
if (!isRecipient && document?.userId !== user.id) {
@ -78,7 +78,7 @@ export const DocumentEditPageView = async ({ params, team }: DocumentEditPageVie
redirect(`${documentRootPath}/${documentId}`);
}
const { documentMeta, Recipient: recipients } = document;
const { documentMeta, recipients } = document;
if (documentMeta?.password) {
const key = DOCUMENSO_ENCRYPTION_KEY;

View File

@ -77,9 +77,9 @@ export const DocumentLogsPageView = async ({ params, team }: DocumentLogsPageVie
},
{
description: msg`Created by`,
value: document.User.name
? `${document.User.name} (${document.User.email})`
: document.User.email,
value: document.user.name
? `${document.user.name} (${document.user.email})`
: document.user.email,
},
{
description: msg`Date created`,

View File

@ -19,8 +19,8 @@ import { useToast } from '@documenso/ui/primitives/use-toast';
export type DataTableActionButtonProps = {
row: Document & {
User: Pick<User, 'id' | 'name' | 'email'>;
Recipient: Recipient[];
user: Pick<User, 'id' | 'name' | 'email'>;
recipients: Recipient[];
team: Pick<Team, 'id' | 'url'> | null;
};
team?: Pick<Team, 'id' | 'url'>;
@ -35,9 +35,9 @@ export const DataTableActionButton = ({ row, team }: DataTableActionButtonProps)
return null;
}
const recipient = row.Recipient.find((recipient) => recipient.email === session.user.email);
const recipient = row.recipients.find((recipient) => recipient.email === session.user.email);
const isOwner = row.User.id === session.user.id;
const isOwner = row.user.id === session.user.id;
const isRecipient = !!recipient;
const isDraft = row.status === DocumentStatus.DRAFT;
const isPending = row.status === DocumentStatus.PENDING;

View File

@ -46,8 +46,8 @@ import { MoveDocumentDialog } from './move-document-dialog';
export type DataTableActionDropdownProps = {
row: Document & {
User: Pick<User, 'id' | 'name' | 'email'>;
Recipient: Recipient[];
user: Pick<User, 'id' | 'name' | 'email'>;
recipients: Recipient[];
team: Pick<Team, 'id' | 'url'> | null;
};
team?: Pick<Team, 'id' | 'url'> & { teamEmail?: string };
@ -66,9 +66,9 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
return null;
}
const recipient = row.Recipient.find((recipient) => recipient.email === session.user.email);
const recipient = row.recipients.find((recipient) => recipient.email === session.user.email);
const isOwner = row.User.id === session.user.id;
const isOwner = row.user.id === session.user.id;
// const isRecipient = !!recipient;
const isDraft = row.status === DocumentStatus.DRAFT;
const isPending = row.status === DocumentStatus.PENDING;
@ -109,7 +109,7 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
}
};
const nonSignedRecipients = row.Recipient.filter((item) => item.signingStatus !== 'SIGNED');
const nonSignedRecipients = row.recipients.filter((item) => item.signingStatus !== 'SIGNED');
return (
<DropdownMenu>
@ -194,7 +194,7 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
{canManageDocument && (
<DocumentRecipientLinkCopyDialog
recipients={row.Recipient}
recipients={row.recipients}
trigger={
<DropdownMenuItem disabled={!isPending} asChild onSelect={(e) => e.preventDefault()}>
<div>

View File

@ -10,9 +10,9 @@ import type { Document, Recipient, Team, User } from '@documenso/prisma/client';
export type DataTableTitleProps = {
row: Document & {
User: Pick<User, 'id' | 'name' | 'email'>;
user: Pick<User, 'id' | 'name' | 'email'>;
team: Pick<Team, 'url'> | null;
Recipient: Recipient[];
recipients: Recipient[];
};
teamUrl?: string;
};
@ -24,9 +24,9 @@ export const DataTableTitle = ({ row, teamUrl }: DataTableTitleProps) => {
return null;
}
const recipient = row.Recipient.find((recipient) => recipient.email === session.user.email);
const recipient = row.recipients.find((recipient) => recipient.email === session.user.email);
const isOwner = row.User.id === session.user.id;
const isOwner = row.user.id === session.user.id;
const isRecipient = !!recipient;
const isCurrentTeamDocument = teamUrl && row.team?.url === teamUrl;

View File

@ -57,14 +57,14 @@ export const DocumentsDataTable = ({
{
id: 'sender',
header: _(msg`Sender`),
cell: ({ row }) => row.original.User.name ?? row.original.User.email,
cell: ({ row }) => row.original.user.name ?? row.original.user.email,
},
{
header: _(msg`Recipient`),
accessorKey: 'recipient',
cell: ({ row }) => (
<StackAvatarsWithTooltip
recipients={row.original.Recipient}
recipients={row.original.recipients}
documentStatus={row.original.status}
/>
),

View File

@ -69,7 +69,7 @@ export const EditTemplateForm = ({
},
);
const { Recipient: recipients, Field: fields, templateDocumentData } = template;
const { recipients, fields, templateDocumentData } = template;
const documentFlow: Record<EditTemplateStep, DocumentFlowStep> = {
settings: {

View File

@ -11,7 +11,7 @@ import { Button } from '@documenso/ui/primitives/button';
import { TemplateDirectLinkDialog } from '../template-direct-link-dialog';
export type TemplateDirectLinkDialogWrapperProps = {
template: Template & { directLink?: TemplateDirectLink | null; Recipient: Recipient[] };
template: Template & { directLink?: TemplateDirectLink | null; recipients: Recipient[] };
};
export const TemplateDirectLinkDialogWrapper = ({

View File

@ -116,7 +116,7 @@ export const TemplatePageViewDocumentsTable = ({
accessorKey: 'recipient',
cell: ({ row }) => (
<StackAvatarsWithTooltip
recipients={row.original.Recipient}
recipients={row.original.recipients}
documentStatus={row.original.status}
/>
),

View File

@ -12,7 +12,7 @@ import type { Template, User } from '@documenso/prisma/client';
export type TemplatePageViewInformationProps = {
userId: number;
template: Template & {
User: Pick<User, 'id' | 'name' | 'email'>;
user: Pick<User, 'id' | 'name' | 'email'>;
};
};
@ -28,7 +28,8 @@ export const TemplatePageViewInformation = ({
return [
{
description: msg`Uploaded by`,
value: userId === template.userId ? _(msg`You`) : template.User.name ?? template.User.email,
value:
userId === template.userId ? _(msg`You`) : (template.user.name ?? template.user.email),
},
{
description: msg`Created`,

View File

@ -123,7 +123,7 @@ export const TemplatePageViewRecentActivity = ({
{match(document.source)
.with(DocumentSource.DOCUMENT, DocumentSource.TEMPLATE, () => (
<Trans>
Document created by <span className="font-bold">{document.User.name}</span>
Document created by <span className="font-bold">{document.user.name}</span>
</Trans>
))
.with(DocumentSource.TEMPLATE_DIRECT_LINK, () => (

View File

@ -10,7 +10,7 @@ import { AvatarWithText } from '@documenso/ui/primitives/avatar';
export type TemplatePageViewRecipientsProps = {
template: Template & {
Recipient: Recipient[];
recipients: Recipient[];
};
templateRootPath: string;
};
@ -21,7 +21,7 @@ export const TemplatePageViewRecipients = ({
}: TemplatePageViewRecipientsProps) => {
const { _ } = useLingui();
const recipients = template.Recipient;
const recipients = template.recipients;
return (
<section className="dark:bg-background border-border bg-widget flex flex-col rounded-xl border">

View File

@ -54,10 +54,10 @@ export const TemplatePageView = async ({ params, team }: TemplatePageViewProps)
redirect(templateRootPath);
}
const { templateDocumentData, Field, Recipient: recipients, templateMeta } = template;
const { templateDocumentData, fields, recipients, templateMeta } = template;
// Remap to fit the DocumentReadOnlyFields component.
const readOnlyFields = Field.map((field) => {
const readOnlyFields = fields.map((field) => {
const recipient = recipients.find((recipient) => recipient.id === field.recipientId) || {
name: '',
email: '',
@ -66,8 +66,8 @@ export const TemplatePageView = async ({ params, team }: TemplatePageViewProps)
return {
...field,
Recipient: recipient,
Signature: null,
recipient,
signature: null,
};
});
@ -165,7 +165,7 @@ export const TemplatePageView = async ({ params, team }: TemplatePageViewProps)
<UseTemplateDialog
templateId={template.id}
templateSigningOrder={template.templateMeta?.signingOrder}
recipients={template.Recipient}
recipients={template.recipients}
documentRootPath={documentRootPath}
trigger={
<Button className="w-full">

View File

@ -25,7 +25,7 @@ import { TemplateDirectLinkDialog } from './template-direct-link-dialog';
export type DataTableActionDropdownProps = {
row: Template & {
directLink?: Pick<TemplateDirectLink, 'token' | 'enabled'> | null;
Recipient: Recipient[];
recipients: Recipient[];
};
templateRootPath: string;
teamId?: number;

View File

@ -146,7 +146,7 @@ export const TemplatesDataTable = ({
templateId={row.original.id}
templateSigningOrder={row.original.templateMeta?.signingOrder}
documentDistributionMethod={row.original.templateMeta?.distributionMethod}
recipients={row.original.Recipient}
recipients={row.original.recipients}
documentRootPath={documentRootPath}
/>

View File

@ -46,12 +46,10 @@ import {
import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { useOptionalCurrentTeam } from '~/providers/team';
type TemplateDirectLinkDialogProps = {
template: Template & {
directLink?: Pick<TemplateDirectLink, 'token' | 'enabled'> | null;
Recipient: Recipient[];
recipients: Recipient[];
};
open: boolean;
onOpenChange: (_open: boolean) => void;
@ -68,8 +66,6 @@ export const TemplateDirectLinkDialog = ({
const { quota, remaining } = useLimits();
const { _ } = useLingui();
const team = useOptionalCurrentTeam();
const [, copy] = useCopyToClipboard();
const router = useRouter();
@ -81,8 +77,8 @@ export const TemplateDirectLinkDialog = ({
);
const validDirectTemplateRecipients = useMemo(
() => template.Recipient.filter((recipient) => recipient.role !== RecipientRole.CC),
[template.Recipient],
() => template.recipients.filter((recipient) => recipient.role !== RecipientRole.CC),
[template.recipients],
);
const {
@ -326,7 +322,7 @@ export const TemplateDirectLinkDialog = ({
</div>
{/* Prevent creating placeholder direct template recipient if the email already exists. */}
{!template.Recipient.some(
{!template.recipients.some(
(recipient) => recipient.email === DIRECT_TEMPLATE_RECIPIENT_EMAIL,
) && (
<DialogFooter className="mx-auto">