mirror of
https://github.com/documenso/documenso.git
synced 2026-07-12 22:15:01 +10:00
fix: remove lazy pdf loader
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@documenso/ui/primitives/dialog';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
import { useOptionalCurrentTeam } from '~/providers/team';
|
||||
@@ -97,7 +97,7 @@ export const DocumentDuplicateDialog = ({
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-2 [&>div]:h-[50vh] [&>div]:overflow-y-scroll">
|
||||
<LazyPDFViewer key={document?.id} documentData={documentData} />
|
||||
<PDFViewer key={document?.id} documentData={documentData} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
|
||||
import { Input } from '@documenso/ui/primitives/input';
|
||||
import { Label } from '@documenso/ui/primitives/label';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
import { SignaturePad } from '@documenso/ui/primitives/signature-pad';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
@@ -338,7 +338,7 @@ export const EmbedDirectTemplateClientPage = ({
|
||||
<div className="relative flex w-full flex-col gap-x-6 gap-y-12 md:flex-row">
|
||||
{/* Viewer */}
|
||||
<div className="flex-1">
|
||||
<LazyPDFViewer
|
||||
<PDFViewer
|
||||
documentData={documentData}
|
||||
onDocumentLoad={() => setHasDocumentLoaded(true)}
|
||||
/>
|
||||
|
||||
@@ -24,7 +24,7 @@ import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
|
||||
import { Input } from '@documenso/ui/primitives/input';
|
||||
import { Label } from '@documenso/ui/primitives/label';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
import { RadioGroup, RadioGroupItem } from '@documenso/ui/primitives/radio-group';
|
||||
import { SignaturePad } from '@documenso/ui/primitives/signature-pad';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
@@ -278,7 +278,7 @@ export const EmbedSignDocumentClientPage = ({
|
||||
<div className="embed--DocumentContainer relative flex w-full flex-col gap-x-6 gap-y-12 md:flex-row">
|
||||
{/* Viewer */}
|
||||
<div className="embed--DocumentViewer flex-1">
|
||||
<LazyPDFViewer
|
||||
<PDFViewer
|
||||
documentData={documentData}
|
||||
onDocumentLoad={() => setHasDocumentLoaded(true)}
|
||||
/>
|
||||
|
||||
@@ -12,7 +12,7 @@ import { trpc } from '@documenso/trpc/react';
|
||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
import { DocumentFlowFormContainer } from '@documenso/ui/primitives/document-flow/document-flow-root';
|
||||
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
import { Stepper } from '@documenso/ui/primitives/stepper';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
@@ -136,7 +136,7 @@ export const DirectTemplatePageView = ({
|
||||
gradient
|
||||
>
|
||||
<CardContent className="p-2">
|
||||
<LazyPDFViewer
|
||||
<PDFViewer
|
||||
key={template.id}
|
||||
documentData={template.templateDocumentData}
|
||||
onDocumentLoad={() => setIsDocumentPdfLoaded(true)}
|
||||
|
||||
@@ -21,7 +21,7 @@ import type { FieldWithSignatureAndFieldMeta } from '@documenso/prisma/types/fie
|
||||
import type { RecipientWithFields } from '@documenso/prisma/types/recipient-with-fields';
|
||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
|
||||
import { DocumentSigningAutoSign } from '~/components/general/document-signing/document-signing-auto-sign';
|
||||
import { DocumentSigningCheckboxField } from '~/components/general/document-signing/document-signing-checkbox-field';
|
||||
@@ -140,12 +140,7 @@ export const DocumentSigningPageView = ({
|
||||
gradient
|
||||
>
|
||||
<CardContent className="p-2">
|
||||
<LazyPDFViewer
|
||||
key={documentData.id}
|
||||
documentData={documentData}
|
||||
document={document}
|
||||
password={documentMeta?.password}
|
||||
/>
|
||||
<PDFViewer key={documentData.id} documentData={documentData} document={document} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import { AddSubjectFormPartial } from '@documenso/ui/primitives/document-flow/ad
|
||||
import type { TAddSubjectFormSchema } from '@documenso/ui/primitives/document-flow/add-subject.types';
|
||||
import { DocumentFlowFormContainer } from '@documenso/ui/primitives/document-flow/document-flow-root';
|
||||
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
import { Stepper } from '@documenso/ui/primitives/stepper';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
@@ -132,9 +132,6 @@ export const DocumentEditForm = ({
|
||||
},
|
||||
});
|
||||
|
||||
const { mutateAsync: setPasswordForDocument } =
|
||||
trpc.document.setPasswordForDocument.useMutation();
|
||||
|
||||
const documentFlow: Record<EditDocumentStep, DocumentFlowStep> = {
|
||||
settings: {
|
||||
title: msg`General`,
|
||||
@@ -315,13 +312,6 @@ export const DocumentEditForm = ({
|
||||
}
|
||||
};
|
||||
|
||||
const onPasswordSubmit = async (password: string) => {
|
||||
await setPasswordForDocument({
|
||||
documentId: document.id,
|
||||
password,
|
||||
});
|
||||
};
|
||||
|
||||
const currentDocumentFlow = documentFlow[step];
|
||||
|
||||
/**
|
||||
@@ -340,12 +330,10 @@ export const DocumentEditForm = ({
|
||||
gradient
|
||||
>
|
||||
<CardContent className="p-2">
|
||||
<LazyPDFViewer
|
||||
<PDFViewer
|
||||
key={document.documentData.id}
|
||||
documentData={document.documentData}
|
||||
document={document}
|
||||
password={document.documentMeta?.password}
|
||||
onPasswordSubmit={onPasswordSubmit}
|
||||
onDocumentLoad={() => setIsDocumentPdfLoaded(true)}
|
||||
/>
|
||||
</CardContent>
|
||||
|
||||
@@ -15,7 +15,7 @@ import { cn } from '@documenso/ui/lib/utils';
|
||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
import { DocumentFlowFormContainer } from '@documenso/ui/primitives/document-flow/document-flow-root';
|
||||
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
import { Stepper } from '@documenso/ui/primitives/stepper';
|
||||
import { AddTemplateFieldsFormPartial } from '@documenso/ui/primitives/template-flow/add-template-fields';
|
||||
import type { TAddTemplateFieldsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-fields.types';
|
||||
@@ -236,7 +236,7 @@ export const TemplateEditForm = ({
|
||||
gradient
|
||||
>
|
||||
<CardContent className="p-2">
|
||||
<LazyPDFViewer
|
||||
<PDFViewer
|
||||
key={templateDocumentData.id}
|
||||
documentData={templateDocumentData}
|
||||
onDocumentLoad={() => setIsDocumentPdfLoaded(true)}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import { Badge } from '@documenso/ui/primitives/badge';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
|
||||
import { DocumentHistorySheet } from '~/components/general/document/document-history-sheet';
|
||||
import { DocumentPageViewButton } from '~/components/general/document/document-page-view-button';
|
||||
@@ -196,7 +196,7 @@ export default function DocumentPage() {
|
||||
gradient
|
||||
>
|
||||
<CardContent className="p-2">
|
||||
<LazyPDFViewer document={document} key={documentData.id} documentData={documentData} />
|
||||
<PDFViewer document={document} key={documentData.id} documentData={documentData} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import { getSubscriptionsByUserId } from '@documenso/lib/server-only/subscriptio
|
||||
import { BillingPlans } from '~/components/general/billing-plans';
|
||||
import { BillingPortalButton } from '~/components/general/billing-portal-button';
|
||||
import { appMetaTags } from '~/utils/meta';
|
||||
import { superLoaderJson, useSuperLoaderData } from '~/utils/super-json-loader';
|
||||
|
||||
import type { Route } from './+types/billing';
|
||||
|
||||
@@ -62,17 +63,17 @@ export async function loader({ request }: Route.LoaderArgs) {
|
||||
const isMissingOrInactiveOrFreePlan =
|
||||
!subscription || subscription.status === SubscriptionStatus.INACTIVE;
|
||||
|
||||
return {
|
||||
return superLoaderJson({
|
||||
prices,
|
||||
subscription,
|
||||
subscriptionProductName: subscriptionProduct?.name,
|
||||
isMissingOrInactiveOrFreePlan,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default function TeamsSettingBillingPage({ loaderData }: Route.ComponentProps) {
|
||||
export default function TeamsSettingBillingPage() {
|
||||
const { prices, subscription, subscriptionProductName, isMissingOrInactiveOrFreePlan } =
|
||||
loaderData;
|
||||
useSuperLoaderData<typeof loader>();
|
||||
|
||||
const { i18n } = useLingui();
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
import { SettingsHeader } from '~/components/general/settings-header';
|
||||
import { TeamBillingPortalButton } from '~/components/general/teams/team-billing-portal-button';
|
||||
import { TeamSettingsBillingInvoicesTable } from '~/components/tables/team-settings-billing-invoices-table';
|
||||
import { superLoaderJson, useSuperLoaderData } from '~/utils/super-json-loader';
|
||||
|
||||
import type { Route } from './+types/settings.billing';
|
||||
|
||||
@@ -31,16 +32,16 @@ export async function loader({ request, params }: Route.LoaderArgs) {
|
||||
teamSubscription = await stripe.subscriptions.retrieve(team.subscription.planId);
|
||||
}
|
||||
|
||||
return {
|
||||
return superLoaderJson({
|
||||
team,
|
||||
teamSubscription,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default function TeamsSettingBillingPage({ loaderData }: Route.ComponentProps) {
|
||||
export default function TeamsSettingBillingPage() {
|
||||
const { _ } = useLingui();
|
||||
|
||||
const { team, teamSubscription } = loaderData;
|
||||
const { team, teamSubscription } = useSuperLoaderData<typeof loader>();
|
||||
|
||||
const canManageBilling = canExecuteTeamAction('MANAGE_BILLING', team.currentTeamMember.role);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getTemplateById } from '@documenso/lib/server-only/template/get-templat
|
||||
import { formatDocumentsPath, formatTemplatesPath } from '@documenso/lib/utils/teams';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
|
||||
|
||||
import { TemplateBulkSendDialog } from '~/components/dialogs/template-bulk-send-dialog';
|
||||
import { TemplateDirectLinkDialogWrapper } from '~/components/dialogs/template-direct-link-dialog-wrapper';
|
||||
@@ -144,11 +144,7 @@ export default function TemplatePage() {
|
||||
gradient
|
||||
>
|
||||
<CardContent className="p-2">
|
||||
<LazyPDFViewer
|
||||
document={template}
|
||||
key={template.id}
|
||||
documentData={templateDocumentData}
|
||||
/>
|
||||
<PDFViewer document={template} key={template.id} documentData={templateDocumentData} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@lingui/babel-plugin-lingui-macro": "^5.2.0",
|
||||
"@lingui/vite-plugin": "^5.2.0",
|
||||
"@react-router/dev": "^7.1.1",
|
||||
"@react-router/dev": "^7.1.5",
|
||||
"@react-router/remix-routes-option-adapter": "^7.1.5",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-commonjs": "^28.0.2",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { defineConfig } from '@lingui/cli';
|
||||
import type { LinguiConfig } from '@lingui/conf';
|
||||
import { formatter } from '@lingui/format-po';
|
||||
|
||||
import { APP_I18N_OPTIONS } from '@documenso/lib/constants/i18n';
|
||||
|
||||
@@ -14,6 +16,7 @@ const config: LinguiConfig = {
|
||||
},
|
||||
],
|
||||
compileNamespace: 'es',
|
||||
format: formatter({ lineNumbers: false }),
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
Generated
+1
-1
@@ -158,7 +158,7 @@
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@lingui/babel-plugin-lingui-macro": "^5.2.0",
|
||||
"@lingui/vite-plugin": "^5.2.0",
|
||||
"@react-router/dev": "^7.1.1",
|
||||
"@react-router/dev": "^7.1.5",
|
||||
"@react-router/remix-routes-option-adapter": "^7.1.5",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-commonjs": "^28.0.2",
|
||||
|
||||
+2425
-2446
File diff suppressed because it is too large
Load Diff
+2425
-2446
File diff suppressed because it is too large
Load Diff
+2425
-2446
File diff suppressed because it is too large
Load Diff
+2425
-2446
File diff suppressed because it is too large
Load Diff
+2425
-2446
File diff suppressed because it is too large
Load Diff
+2425
-2446
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,6 @@ import { DateTime } from 'luxon';
|
||||
|
||||
import { getServerLimits } from '@documenso/ee/server-only/limits/server';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { DOCUMENSO_ENCRYPTION_KEY } from '@documenso/lib/constants/crypto';
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { encryptSecondaryData } from '@documenso/lib/server-only/crypto/encrypt';
|
||||
import { createDocumentData } from '@documenso/lib/server-only/document-data/create-document-data';
|
||||
@@ -26,7 +25,6 @@ import { searchDocumentsWithKeyword } from '@documenso/lib/server-only/document/
|
||||
import { sendDocument } from '@documenso/lib/server-only/document/send-document';
|
||||
import { updateDocument } from '@documenso/lib/server-only/document/update-document';
|
||||
import { getTeamById } from '@documenso/lib/server-only/team/get-team';
|
||||
import { symmetricEncrypt } from '@documenso/lib/universal/crypto';
|
||||
import { getPresignPostUrl } from '@documenso/lib/universal/upload/server-actions';
|
||||
|
||||
import { authenticatedProcedure, procedure, router } from '../trpc';
|
||||
@@ -55,7 +53,6 @@ import {
|
||||
ZMoveDocumentToTeamSchema,
|
||||
ZResendDocumentMutationSchema,
|
||||
ZSearchDocumentsMutationSchema,
|
||||
ZSetPasswordForDocumentMutationSchema,
|
||||
ZSetSigningOrderForDocumentMutationSchema,
|
||||
ZSuccessResponseSchema,
|
||||
ZUpdateDocumentRequestSchema,
|
||||
@@ -444,35 +441,6 @@ export const documentRouter = router({
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
setPasswordForDocument: authenticatedProcedure
|
||||
.input(ZSetPasswordForDocumentMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { teamId } = ctx;
|
||||
const { documentId, password } = input;
|
||||
|
||||
const key = DOCUMENSO_ENCRYPTION_KEY;
|
||||
|
||||
if (!key) {
|
||||
throw new Error('Missing encryption key');
|
||||
}
|
||||
|
||||
const securePassword = symmetricEncrypt({
|
||||
data: password,
|
||||
key,
|
||||
});
|
||||
|
||||
await upsertDocumentMeta({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
documentId,
|
||||
password: securePassword,
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
|
||||
@@ -6,7 +6,7 @@ import { X } from 'lucide-react';
|
||||
|
||||
import { cn } from '../../lib/utils';
|
||||
import { Dialog, DialogOverlay, DialogPortal, DialogTrigger } from '../../primitives/dialog';
|
||||
import { LazyPDFViewerNoLoader } from '../../primitives/lazy-pdf-viewer';
|
||||
import PDFViewer from '../../primitives/pdf-viewer';
|
||||
|
||||
export type DocumentDialogProps = {
|
||||
trigger?: React.ReactNode;
|
||||
@@ -43,7 +43,7 @@ export default function DocumentDialog({ trigger, documentData, ...props }: Docu
|
||||
)}
|
||||
onClick={() => props.onOpenChange?.(false)}
|
||||
>
|
||||
<LazyPDFViewerNoLoader
|
||||
<PDFViewer
|
||||
className="mx-auto w-full max-w-3xl xl:max-w-5xl"
|
||||
documentData={documentData}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Button } from './button';
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './dialog';
|
||||
import { Form, FormControl, FormField, FormItem, FormMessage } from './form/form';
|
||||
import { Input } from './input';
|
||||
|
||||
const ZPasswordDialogFormSchema = z.object({
|
||||
password: z.string(),
|
||||
});
|
||||
|
||||
type TPasswordDialogFormSchema = z.infer<typeof ZPasswordDialogFormSchema>;
|
||||
|
||||
type PasswordDialogProps = {
|
||||
open: boolean;
|
||||
onOpenChange: (_open: boolean) => void;
|
||||
defaultPassword?: string;
|
||||
onPasswordSubmit?: (password: string) => void;
|
||||
isError?: boolean;
|
||||
};
|
||||
|
||||
export const PasswordDialog = ({
|
||||
open,
|
||||
onOpenChange,
|
||||
defaultPassword,
|
||||
onPasswordSubmit,
|
||||
isError,
|
||||
}: PasswordDialogProps) => {
|
||||
const { _ } = useLingui();
|
||||
|
||||
const form = useForm<TPasswordDialogFormSchema>({
|
||||
defaultValues: {
|
||||
password: defaultPassword ?? '',
|
||||
},
|
||||
resolver: zodResolver(ZPasswordDialogFormSchema),
|
||||
});
|
||||
|
||||
const onFormSubmit = ({ password }: TPasswordDialogFormSchema) => {
|
||||
onPasswordSubmit?.(password);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isError) {
|
||||
form.setError('password', {
|
||||
type: 'manual',
|
||||
message: _(msg`The password you have entered is incorrect. Please try again.`),
|
||||
});
|
||||
}
|
||||
}, [form, isError]);
|
||||
|
||||
return (
|
||||
<Dialog open={open}>
|
||||
<DialogContent className="w-full max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Password Required</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
<DialogDescription className="text-muted-foreground">
|
||||
<Trans>
|
||||
This document is password protected. Please enter the password to view the document.
|
||||
</Trans>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="flex flex-wrap items-start justify-between gap-4">
|
||||
<FormField
|
||||
name="password"
|
||||
control={form.control}
|
||||
render={({ field }) => (
|
||||
<FormItem className="relative flex-1">
|
||||
<FormControl>
|
||||
<Input
|
||||
type="password"
|
||||
className="bg-background"
|
||||
placeholder={_(msg`Enter password`)}
|
||||
autoComplete="off"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div>
|
||||
<Button>
|
||||
<Trans>Submit</Trans>
|
||||
</Button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</Form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
// Todo: (RR7) Not sure if this actually makes it client-only.
|
||||
import { Suspense, lazy } from 'react';
|
||||
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { Loader } from 'lucide-react';
|
||||
import { Await } from 'react-router';
|
||||
|
||||
const LoadingComponent = () => (
|
||||
<div className="dark:bg-background flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50">
|
||||
<Loader className="text-documenso h-12 w-12 animate-spin" />
|
||||
<p className="text-muted-foreground mt-4">
|
||||
<Trans>Loading document...</Trans>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const LazyPDFViewerImport = lazy(async () => import('./pdf-viewer'));
|
||||
|
||||
export const LazyPDFViewer = (props: React.ComponentProps<typeof LazyPDFViewerImport>) => (
|
||||
<Suspense fallback={<LoadingComponent />}>
|
||||
<Await resolve={LazyPDFViewerImport}>
|
||||
<LazyPDFViewerImport {...props} />
|
||||
</Await>
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
export const LazyPDFViewerNoLoader = (props: React.ComponentProps<typeof LazyPDFViewer>) => (
|
||||
<Suspense fallback={null}>
|
||||
<LazyPDFViewerImport {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
@@ -5,18 +5,15 @@ import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import type { DocumentData } from '@prisma/client';
|
||||
import { Loader } from 'lucide-react';
|
||||
import { type PDFDocumentProxy, PasswordResponses } from 'pdfjs-dist';
|
||||
import pdfWorker from 'pdfjs-dist/build/pdf.worker.min?url';
|
||||
import { type PDFDocumentProxy } from 'pdfjs-dist';
|
||||
import { Document as PDFDocument, Page as PDFPage, pdfjs } from 'react-pdf';
|
||||
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
|
||||
import 'react-pdf/dist/esm/Page/TextLayer.css';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
|
||||
import { getFile } from '@documenso/lib/universal/upload/get-file';
|
||||
|
||||
import { cn } from '../lib/utils';
|
||||
import { PasswordDialog } from './document-password-dialog';
|
||||
import { useToast } from './use-toast';
|
||||
|
||||
export type LoadedPDFDocument = PDFDocumentProxy;
|
||||
@@ -24,7 +21,10 @@ export type LoadedPDFDocument = PDFDocumentProxy;
|
||||
/**
|
||||
* This imports the worker from the `pdfjs-dist` package.
|
||||
*/
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = pdfWorker;
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
'pdfjs-dist/build/pdf.worker.min.js',
|
||||
import.meta.url,
|
||||
).toString();
|
||||
|
||||
export type OnPDFViewerPageClick = (_event: {
|
||||
pageNumber: number;
|
||||
@@ -49,8 +49,6 @@ const PDFLoader = () => (
|
||||
export type PDFViewerProps = {
|
||||
className?: string;
|
||||
documentData: DocumentData;
|
||||
password?: string | null;
|
||||
onPasswordSubmit?: (password: string) => void | Promise<void>;
|
||||
onDocumentLoad?: (_doc: LoadedPDFDocument) => void;
|
||||
onPageClick?: OnPDFViewerPageClick;
|
||||
[key: string]: unknown;
|
||||
@@ -59,8 +57,6 @@ export type PDFViewerProps = {
|
||||
export const PDFViewer = ({
|
||||
className,
|
||||
documentData,
|
||||
password: defaultPassword,
|
||||
onPasswordSubmit,
|
||||
onDocumentLoad,
|
||||
onPageClick,
|
||||
...props
|
||||
@@ -70,11 +66,7 @@ export const PDFViewer = ({
|
||||
|
||||
const $el = useRef<HTMLDivElement>(null);
|
||||
|
||||
const passwordCallbackRef = useRef<((password: string | null) => void) | null>(null);
|
||||
|
||||
const [isDocumentBytesLoading, setIsDocumentBytesLoading] = useState(false);
|
||||
const [isPasswordModalOpen, setIsPasswordModalOpen] = useState(false);
|
||||
const [isPasswordError, setIsPasswordError] = useState(false);
|
||||
const [documentBytes, setDocumentBytes] = useState<Uint8Array | null>(null);
|
||||
|
||||
const [width, setWidth] = useState(0);
|
||||
@@ -190,21 +182,6 @@ export const PDFViewer = ({
|
||||
className={cn('w-full overflow-hidden rounded', {
|
||||
'h-[80vh] max-h-[60rem]': numPages === 0,
|
||||
})}
|
||||
onPassword={(callback, reason) => {
|
||||
// If the document already has a password, we don't need to ask for it again.
|
||||
if (defaultPassword && reason !== PasswordResponses.INCORRECT_PASSWORD) {
|
||||
callback(defaultPassword);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsPasswordModalOpen(true);
|
||||
|
||||
passwordCallbackRef.current = callback;
|
||||
|
||||
match(reason)
|
||||
.with(PasswordResponses.NEED_PASSWORD, () => setIsPasswordError(false))
|
||||
.with(PasswordResponses.INCORRECT_PASSWORD, () => setIsPasswordError(true));
|
||||
}}
|
||||
onLoadSuccess={(d) => onDocumentLoaded(d)}
|
||||
// Uploading a invalid document causes an error which doesn't appear to be handled by the `error` prop.
|
||||
// Therefore we add some additional custom error handling.
|
||||
@@ -263,19 +240,6 @@ export const PDFViewer = ({
|
||||
</div>
|
||||
))}
|
||||
</PDFDocument>
|
||||
|
||||
<PasswordDialog
|
||||
open={isPasswordModalOpen}
|
||||
onOpenChange={setIsPasswordModalOpen}
|
||||
onPasswordSubmit={(password) => {
|
||||
passwordCallbackRef.current?.(password);
|
||||
|
||||
setIsPasswordModalOpen(false);
|
||||
|
||||
void onPasswordSubmit?.(password);
|
||||
}}
|
||||
isError={isPasswordError}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user