mirror of
https://github.com/documenso/documenso.git
synced 2026-07-25 01:15:49 +10:00
fix: remove legacy envelope uploads (#2303)
This commit is contained in:
@@ -1,136 +0,0 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
import { msg } from '@lingui/core/macro';
|
|
||||||
import { useLingui } from '@lingui/react';
|
|
||||||
import { Trans } from '@lingui/react/macro';
|
|
||||||
import { FilePlus, Loader } from 'lucide-react';
|
|
||||||
import { useNavigate } from 'react-router';
|
|
||||||
|
|
||||||
import { useSession } from '@documenso/lib/client-only/providers/session';
|
|
||||||
import { formatTemplatesPath } from '@documenso/lib/utils/teams';
|
|
||||||
import { trpc } from '@documenso/trpc/react';
|
|
||||||
import type { TCreateTemplatePayloadSchema } from '@documenso/trpc/server/template-router/schema';
|
|
||||||
import { Button } from '@documenso/ui/primitives/button';
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogClose,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogFooter,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from '@documenso/ui/primitives/dialog';
|
|
||||||
import { DocumentDropzone } from '@documenso/ui/primitives/document-dropzone';
|
|
||||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
|
||||||
|
|
||||||
import { useCurrentTeam } from '~/providers/team';
|
|
||||||
|
|
||||||
type TemplateCreateDialogProps = {
|
|
||||||
folderId?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TemplateCreateDialog = ({ folderId }: TemplateCreateDialogProps) => {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const { user } = useSession();
|
|
||||||
const { toast } = useToast();
|
|
||||||
const { _ } = useLingui();
|
|
||||||
|
|
||||||
const team = useCurrentTeam();
|
|
||||||
|
|
||||||
const { mutateAsync: createTemplate } = trpc.template.createTemplate.useMutation();
|
|
||||||
|
|
||||||
const [showTemplateCreateDialog, setShowTemplateCreateDialog] = useState(false);
|
|
||||||
const [isUploadingFile, setIsUploadingFile] = useState(false);
|
|
||||||
|
|
||||||
const onFileDrop = async (files: File[]) => {
|
|
||||||
const file = files[0];
|
|
||||||
|
|
||||||
if (isUploadingFile) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsUploadingFile(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const payload = {
|
|
||||||
title: file.name,
|
|
||||||
folderId: folderId,
|
|
||||||
} satisfies TCreateTemplatePayloadSchema;
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
formData.append('payload', JSON.stringify(payload));
|
|
||||||
formData.append('file', file);
|
|
||||||
|
|
||||||
const { envelopeId: id } = await createTemplate(formData);
|
|
||||||
|
|
||||||
toast({
|
|
||||||
title: _(msg`Template document uploaded`),
|
|
||||||
description: _(
|
|
||||||
msg`Your document has been uploaded successfully. You will be redirected to the template page.`,
|
|
||||||
),
|
|
||||||
duration: 5000,
|
|
||||||
});
|
|
||||||
|
|
||||||
setShowTemplateCreateDialog(false);
|
|
||||||
|
|
||||||
await navigate(`${formatTemplatesPath(team.url)}/${id}/edit`);
|
|
||||||
} catch {
|
|
||||||
toast({
|
|
||||||
title: _(msg`Something went wrong`),
|
|
||||||
description: _(msg`Please try again later.`),
|
|
||||||
variant: 'destructive',
|
|
||||||
});
|
|
||||||
|
|
||||||
setIsUploadingFile(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
open={showTemplateCreateDialog}
|
|
||||||
onOpenChange={(value) => !isUploadingFile && setShowTemplateCreateDialog(value)}
|
|
||||||
>
|
|
||||||
<DialogTrigger asChild>
|
|
||||||
<Button className="cursor-pointer" disabled={!user.emailVerified}>
|
|
||||||
<FilePlus className="-ml-1 mr-2 h-4 w-4" />
|
|
||||||
<Trans>Template (Legacy)</Trans>
|
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
|
|
||||||
<DialogContent className="w-full max-w-xl">
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>
|
|
||||||
<Trans>New Template</Trans>
|
|
||||||
</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
<Trans>
|
|
||||||
Templates allow you to quickly generate documents with pre-filled recipients and
|
|
||||||
fields.
|
|
||||||
</Trans>
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
|
|
||||||
<div className="relative">
|
|
||||||
<DocumentDropzone className="h-[40vh]" onDrop={onFileDrop} type="template" />
|
|
||||||
|
|
||||||
{isUploadingFile && (
|
|
||||||
<div className="bg-background/50 absolute inset-0 flex items-center justify-center rounded-lg">
|
|
||||||
<Loader className="text-muted-foreground h-12 w-12 animate-spin" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<DialogFooter>
|
|
||||||
<DialogClose asChild>
|
|
||||||
<Button type="button" variant="secondary" disabled={isUploadingFile}>
|
|
||||||
<Trans>Close</Trans>
|
|
||||||
</Button>
|
|
||||||
</DialogClose>
|
|
||||||
</DialogFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -14,9 +14,10 @@ import { useSession } from '@documenso/lib/client-only/providers/session';
|
|||||||
import { APP_DOCUMENT_UPLOAD_SIZE_LIMIT } from '@documenso/lib/constants/app';
|
import { APP_DOCUMENT_UPLOAD_SIZE_LIMIT } from '@documenso/lib/constants/app';
|
||||||
import { DEFAULT_DOCUMENT_TIME_ZONE, TIME_ZONES } from '@documenso/lib/constants/time-zones';
|
import { DEFAULT_DOCUMENT_TIME_ZONE, TIME_ZONES } from '@documenso/lib/constants/time-zones';
|
||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
import { formatDocumentsPath, formatTemplatesPath } from '@documenso/lib/utils/teams';
|
||||||
import { trpc } from '@documenso/trpc/react';
|
import { trpc } from '@documenso/trpc/react';
|
||||||
import type { TCreateDocumentPayloadSchema } from '@documenso/trpc/server/document-router/create-document.types';
|
import type { TCreateDocumentPayloadSchema } from '@documenso/trpc/server/document-router/create-document.types';
|
||||||
|
import type { TCreateTemplatePayloadSchema } from '@documenso/trpc/server/template-router/schema';
|
||||||
import { cn } from '@documenso/ui/lib/utils';
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
import { DocumentUploadButton as DocumentUploadButtonPrimitive } from '@documenso/ui/primitives/document-upload-button';
|
import { DocumentUploadButton as DocumentUploadButtonPrimitive } from '@documenso/ui/primitives/document-upload-button';
|
||||||
import {
|
import {
|
||||||
@@ -31,9 +32,13 @@ import { useCurrentTeam } from '~/providers/team';
|
|||||||
|
|
||||||
export type DocumentUploadButtonLegacyProps = {
|
export type DocumentUploadButtonLegacyProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
type: EnvelopeType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLegacyProps) => {
|
export const DocumentUploadButtonLegacy = ({
|
||||||
|
className,
|
||||||
|
type,
|
||||||
|
}: DocumentUploadButtonLegacyProps) => {
|
||||||
const { _ } = useLingui();
|
const { _ } = useLingui();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { user } = useSession();
|
const { user } = useSession();
|
||||||
@@ -54,8 +59,18 @@ export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLe
|
|||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const { mutateAsync: createDocument } = trpc.document.create.useMutation();
|
const { mutateAsync: createDocument } = trpc.document.create.useMutation();
|
||||||
|
const { mutateAsync: createTemplate } = trpc.template.createTemplate.useMutation();
|
||||||
|
|
||||||
const disabledMessage = useMemo(() => {
|
const disabledMessage = useMemo(() => {
|
||||||
|
if (!user.emailVerified) {
|
||||||
|
return msg`Verify your email to upload documents.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No errors for templates.
|
||||||
|
if (type === EnvelopeType.TEMPLATE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (organisation.subscription && remaining.documents === 0) {
|
if (organisation.subscription && remaining.documents === 0) {
|
||||||
return msg`Document upload disabled due to unpaid invoices`;
|
return msg`Document upload disabled due to unpaid invoices`;
|
||||||
}
|
}
|
||||||
@@ -64,11 +79,8 @@ export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLe
|
|||||||
return msg`You have reached your document limit.`;
|
return msg`You have reached your document limit.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.emailVerified) {
|
|
||||||
return msg`Verify your email to upload documents.`;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [remaining.documents, user.emailVerified, team]);
|
}, [remaining.documents, user.emailVerified, team, type]);
|
||||||
|
|
||||||
const onFileDrop = async (file: File) => {
|
const onFileDrop = async (file: File) => {
|
||||||
try {
|
try {
|
||||||
@@ -80,30 +92,48 @@ export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLe
|
|||||||
meta: {
|
meta: {
|
||||||
timezone: userTimezone,
|
timezone: userTimezone,
|
||||||
},
|
},
|
||||||
} satisfies TCreateDocumentPayloadSchema;
|
} satisfies TCreateDocumentPayloadSchema | TCreateTemplatePayloadSchema;
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
formData.append('payload', JSON.stringify(payload));
|
formData.append('payload', JSON.stringify(payload));
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
|
|
||||||
const { envelopeId: id } = await createDocument(formData);
|
// Handle legacy document creation.
|
||||||
|
if (type === EnvelopeType.DOCUMENT) {
|
||||||
|
const { envelopeId: id } = await createDocument(formData);
|
||||||
|
|
||||||
void refreshLimits();
|
void refreshLimits();
|
||||||
|
|
||||||
await navigate(`${formatDocumentsPath(team.url)}/${id}/edit`);
|
await navigate(`${formatDocumentsPath(team.url)}/${id}/edit`);
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: _(msg`Document uploaded`),
|
title: _(msg`Document uploaded`),
|
||||||
description: _(msg`Your document has been uploaded successfully.`),
|
description: _(msg`Your document has been uploaded successfully.`),
|
||||||
duration: 5000,
|
duration: 5000,
|
||||||
});
|
});
|
||||||
|
|
||||||
analytics.capture('App: Document Uploaded', {
|
analytics.capture('App: Document Uploaded', {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
documentId: id,
|
documentId: id,
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle legacy template creation.
|
||||||
|
if (type === EnvelopeType.TEMPLATE) {
|
||||||
|
const { envelopeId: id } = await createTemplate(formData);
|
||||||
|
|
||||||
|
await navigate(`${formatTemplatesPath(team.url)}/${id}/edit`);
|
||||||
|
|
||||||
|
toast({
|
||||||
|
title: _(msg`Template document uploaded`),
|
||||||
|
description: _(
|
||||||
|
msg`Your document has been uploaded successfully. You will be redirected to the template page.`,
|
||||||
|
),
|
||||||
|
duration: 5000,
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const error = AppError.parseError(err);
|
const error = AppError.parseError(err);
|
||||||
|
|
||||||
@@ -149,17 +179,18 @@ export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLe
|
|||||||
<div>
|
<div>
|
||||||
<DocumentUploadButtonPrimitive
|
<DocumentUploadButtonPrimitive
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
disabled={remaining.documents === 0 || !user.emailVerified}
|
disabled={disabledMessage !== undefined}
|
||||||
disabledMessage={disabledMessage}
|
disabledMessage={disabledMessage}
|
||||||
onDrop={async (files) => onFileDrop(files[0])}
|
onDrop={async (files) => onFileDrop(files[0])}
|
||||||
onDropRejected={onFileDropRejected}
|
onDropRejected={onFileDropRejected}
|
||||||
type={EnvelopeType.DOCUMENT}
|
type={type}
|
||||||
internalVersion="1"
|
internalVersion="1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
||||||
{team?.id === undefined &&
|
{team?.id === undefined &&
|
||||||
|
type === EnvelopeType.DOCUMENT &&
|
||||||
remaining.documents > 0 &&
|
remaining.documents > 0 &&
|
||||||
Number.isFinite(remaining.documents) && (
|
Number.isFinite(remaining.documents) && (
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import { FolderCreateDialog } from '~/components/dialogs/folder-create-dialog';
|
|||||||
import { FolderDeleteDialog } from '~/components/dialogs/folder-delete-dialog';
|
import { FolderDeleteDialog } from '~/components/dialogs/folder-delete-dialog';
|
||||||
import { FolderMoveDialog } from '~/components/dialogs/folder-move-dialog';
|
import { FolderMoveDialog } from '~/components/dialogs/folder-move-dialog';
|
||||||
import { FolderUpdateDialog } from '~/components/dialogs/folder-update-dialog';
|
import { FolderUpdateDialog } from '~/components/dialogs/folder-update-dialog';
|
||||||
import { TemplateCreateDialog } from '~/components/dialogs/template-create-dialog';
|
|
||||||
import { DocumentUploadButtonLegacy } from '~/components/general/document/document-upload-button-legacy';
|
import { DocumentUploadButtonLegacy } from '~/components/general/document/document-upload-button-legacy';
|
||||||
import { FolderCard, FolderCardEmpty } from '~/components/general/folder/folder-card';
|
import { FolderCard, FolderCardEmpty } from '~/components/general/folder/folder-card';
|
||||||
import { useCurrentTeam } from '~/providers/team';
|
import { useCurrentTeam } from '~/providers/team';
|
||||||
@@ -70,7 +69,7 @@ export const FolderGrid = ({ type, parentId }: FolderGridProps) => {
|
|||||||
<div>
|
<div>
|
||||||
<div className="mb-4 flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
<div className="mb-4 flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
||||||
<div
|
<div
|
||||||
className="text-muted-foreground hover:text-muted-foreground/80 flex flex-1 items-center text-sm font-medium"
|
className="flex flex-1 items-center text-sm font-medium text-muted-foreground hover:text-muted-foreground/80"
|
||||||
data-testid="folder-grid-breadcrumbs"
|
data-testid="folder-grid-breadcrumbs"
|
||||||
>
|
>
|
||||||
<Link to={formatRootPath()} className="flex items-center">
|
<Link to={formatRootPath()} className="flex items-center">
|
||||||
@@ -100,10 +99,9 @@ export const FolderGrid = ({ type, parentId }: FolderGridProps) => {
|
|||||||
<div className="flex gap-4 sm:flex-row sm:justify-end">
|
<div className="flex gap-4 sm:flex-row sm:justify-end">
|
||||||
<EnvelopeUploadButton type={type} folderId={parentId || undefined} />
|
<EnvelopeUploadButton type={type} folderId={parentId || undefined} />
|
||||||
|
|
||||||
{type === FolderType.DOCUMENT ? (
|
{/* If you delete this, delete the component as well. */}
|
||||||
<DocumentUploadButtonLegacy /> // If you delete this, delete the component as well.
|
{organisation.organisationClaim.flags.allowLegacyEnvelopes && (
|
||||||
) : (
|
<DocumentUploadButtonLegacy type={type} />
|
||||||
<TemplateCreateDialog folderId={parentId ?? undefined} /> // If you delete this, delete the component as well.
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<FolderCreateDialog type={type} />
|
<FolderCreateDialog type={type} />
|
||||||
@@ -113,7 +111,7 @@ export const FolderGrid = ({ type, parentId }: FolderGridProps) => {
|
|||||||
{isPending ? (
|
{isPending ? (
|
||||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
|
||||||
{Array.from({ length: 4 }).map((_, index) => (
|
{Array.from({ length: 4 }).map((_, index) => (
|
||||||
<div key={index} className="border-border bg-card h-full rounded-lg border px-4 py-5">
|
<div key={index} className="h-full rounded-lg border border-border bg-card px-4 py-5">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Skeleton className="h-8 w-8 rounded" />
|
<Skeleton className="h-8 w-8 rounded" />
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
@@ -194,7 +192,7 @@ export const FolderGrid = ({ type, parentId }: FolderGridProps) => {
|
|||||||
{foldersData.folders.length > 12 && (
|
{foldersData.folders.length > 12 && (
|
||||||
<div className="mt-2 flex items-center justify-center">
|
<div className="mt-2 flex items-center justify-center">
|
||||||
<Link
|
<Link
|
||||||
className="text-muted-foreground hover:text-foreground text-sm font-medium"
|
className="text-sm font-medium text-muted-foreground hover:text-foreground"
|
||||||
to={formatViewAllFoldersPath()}
|
to={formatViewAllFoldersPath()}
|
||||||
>
|
>
|
||||||
View all folders
|
View all folders
|
||||||
|
|||||||
@@ -364,6 +364,25 @@ test('[TEAMS]: can create a template subfolder inside a template folder', async
|
|||||||
test('[TEAMS]: can create a template inside a template folder', async ({ page }) => {
|
test('[TEAMS]: can create a template inside a template folder', async ({ page }) => {
|
||||||
const { team, teamOwner } = await seedTeamDocuments();
|
const { team, teamOwner } = await seedTeamDocuments();
|
||||||
|
|
||||||
|
const organisationClaim = await prisma.organisationClaim.findFirstOrThrow({
|
||||||
|
where: {
|
||||||
|
organisation: {
|
||||||
|
id: team.organisationId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.organisationClaim.update({
|
||||||
|
where: {
|
||||||
|
id: organisationClaim.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
flags: {
|
||||||
|
allowLegacyEnvelopes: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const folder = await seedBlankFolder(teamOwner, team.id, {
|
const folder = await seedBlankFolder(teamOwner, team.id, {
|
||||||
createFolderOptions: {
|
createFolderOptions: {
|
||||||
name: 'Team Client Templates',
|
name: 'Team Client Templates',
|
||||||
@@ -380,16 +399,15 @@ test('[TEAMS]: can create a template inside a template folder', async ({ page })
|
|||||||
|
|
||||||
await expect(page.getByText('Team Client Templates')).toBeVisible();
|
await expect(page.getByText('Team Client Templates')).toBeVisible();
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Template (Legacy)' }).click();
|
// Upload document.
|
||||||
|
const [fileChooser] = await Promise.all([
|
||||||
|
page.waitForEvent('filechooser'),
|
||||||
|
page.getByRole('button', { name: 'Template (Legacy)' }).click(),
|
||||||
|
]);
|
||||||
|
|
||||||
await page.getByText('Upload Template Document').click();
|
await fileChooser.setFiles(
|
||||||
|
path.join(__dirname, '../../../assets/documenso-supporter-pledge.pdf'),
|
||||||
await page.locator('input[type="file"]').nth(0).waitFor({ state: 'attached' });
|
);
|
||||||
|
|
||||||
await page
|
|
||||||
.locator('input[type="file"]')
|
|
||||||
.nth(0)
|
|
||||||
.setInputFiles(path.join(__dirname, '../../../assets/documenso-supporter-pledge.pdf'));
|
|
||||||
|
|
||||||
await page.waitForTimeout(3000);
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const ZClaimFlagsSchema = z.object({
|
|||||||
|
|
||||||
authenticationPortal: z.boolean().optional(),
|
authenticationPortal: z.boolean().optional(),
|
||||||
|
|
||||||
allowEnvelopes: z.boolean().optional(),
|
allowLegacyEnvelopes: z.boolean().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TClaimFlags = z.infer<typeof ZClaimFlagsSchema>;
|
export type TClaimFlags = z.infer<typeof ZClaimFlagsSchema>;
|
||||||
@@ -84,9 +84,9 @@ export const SUBSCRIPTION_CLAIM_FEATURE_FLAGS: Record<
|
|||||||
key: 'authenticationPortal',
|
key: 'authenticationPortal',
|
||||||
label: 'Authentication portal',
|
label: 'Authentication portal',
|
||||||
},
|
},
|
||||||
allowEnvelopes: {
|
allowLegacyEnvelopes: {
|
||||||
key: 'allowEnvelopes',
|
key: 'allowLegacyEnvelopes',
|
||||||
label: 'Allow envelopes',
|
label: 'Allow Legacy Envelopes',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,18 @@ export const seedUser = async ({
|
|||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
teams: true,
|
teams: true,
|
||||||
|
organisationClaim: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.organisationClaim.update({
|
||||||
|
where: {
|
||||||
|
id: organisation.organisationClaim.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
flags: {
|
||||||
|
allowLegacyEnvelopes: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const EnvelopePdfViewer = lazy(async () => import('./pdf-viewer-konva'));
|
|||||||
|
|
||||||
export const PDFViewerKonvaLazy = (props: PDFViewerProps) => {
|
export const PDFViewerKonvaLazy = (props: PDFViewerProps) => {
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<div>Loading client component...</div>}>
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
<EnvelopePdfViewer {...props} />
|
<EnvelopePdfViewer {...props} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user