mirror of
https://github.com/documenso/documenso.git
synced 2025-11-12 07:43:16 +10:00
feat add documentPassword to documenet meta and improve the ux
Signed-off-by: harkiratsm <multaniharry714@gmail.com>
This commit is contained in:
@ -4,10 +4,11 @@ import { prisma } from '@documenso/prisma';
|
||||
|
||||
export type CreateDocumentMetaOptions = {
|
||||
documentId: number;
|
||||
subject: string;
|
||||
message: string;
|
||||
timezone: string;
|
||||
dateFormat: string;
|
||||
subject?: string;
|
||||
message?: string;
|
||||
timezone?: string;
|
||||
documentPassword?: string;
|
||||
dateFormat?: string;
|
||||
userId: number;
|
||||
};
|
||||
|
||||
@ -18,6 +19,7 @@ export const upsertDocumentMeta = async ({
|
||||
dateFormat,
|
||||
documentId,
|
||||
userId,
|
||||
documentPassword,
|
||||
}: CreateDocumentMetaOptions) => {
|
||||
await prisma.document.findFirstOrThrow({
|
||||
where: {
|
||||
@ -35,12 +37,14 @@ export const upsertDocumentMeta = async ({
|
||||
message,
|
||||
dateFormat,
|
||||
timezone,
|
||||
documentPassword,
|
||||
documentId,
|
||||
},
|
||||
update: {
|
||||
subject,
|
||||
message,
|
||||
dateFormat,
|
||||
documentPassword,
|
||||
timezone,
|
||||
},
|
||||
});
|
||||
|
||||
@ -26,6 +26,7 @@ export const duplicateDocumentById = async ({ id, userId }: DuplicateDocumentByI
|
||||
message: true,
|
||||
subject: true,
|
||||
dateFormat: true,
|
||||
documentPassword: true,
|
||||
timezone: true,
|
||||
},
|
||||
},
|
||||
|
||||
@ -162,6 +162,7 @@ model DocumentMeta {
|
||||
subject String?
|
||||
message String?
|
||||
timezone String? @db.Text @default("Etc/UTC")
|
||||
documentPassword String?
|
||||
dateFormat String? @db.Text @default("yyyy-MM-dd hh:mm a")
|
||||
documentId Int @unique
|
||||
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
||||
|
||||
@ -24,6 +24,7 @@ import {
|
||||
ZSearchDocumentsMutationSchema,
|
||||
ZSendDocumentMutationSchema,
|
||||
ZSetFieldsForDocumentMutationSchema,
|
||||
ZSetPasswordForDocumentMutationSchema,
|
||||
ZSetRecipientsForDocumentMutationSchema,
|
||||
ZSetTitleForDocumentMutationSchema,
|
||||
} from './schema';
|
||||
@ -174,6 +175,29 @@ export const documentRouter = router({
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
setDocumentPassword: authenticatedProcedure
|
||||
.input(ZSetPasswordForDocumentMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { documentId, documentPassword } = input;
|
||||
await upsertDocumentMeta({
|
||||
documentId,
|
||||
documentPassword,
|
||||
userId: ctx.user.id,
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to send this document. Please try again later.',
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
|
||||
|
||||
sendDocument: authenticatedProcedure
|
||||
.input(ZSendDocumentMutationSchema)
|
||||
|
||||
@ -73,6 +73,11 @@ export const ZSendDocumentMutationSchema = z.object({
|
||||
}),
|
||||
});
|
||||
|
||||
export const ZSetPasswordForDocumentMutationSchema = z.object({
|
||||
documentId: z.number(),
|
||||
documentPassword: z.string(),
|
||||
});
|
||||
|
||||
export const ZResendDocumentMutationSchema = z.object({
|
||||
documentId: z.number(),
|
||||
recipients: z.array(z.number()).min(1),
|
||||
|
||||
@ -10,11 +10,13 @@ import 'react-pdf/dist/esm/Page/TextLayer.css';
|
||||
|
||||
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
|
||||
import { getFile } from '@documenso/lib/universal/upload/get-file';
|
||||
import type { DocumentData } from '@documenso/prisma/client';
|
||||
import type { DocumentData, DocumentMeta } from '@documenso/prisma/client';
|
||||
|
||||
import { cn } from '../lib/utils';
|
||||
import { PasswordDialog } from './document-password-dialog';
|
||||
import { useToast } from './use-toast';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { DocumentWithData } from '@documenso/prisma/types/document-with-data';
|
||||
|
||||
export type LoadedPDFDocument = PDFDocumentProxy;
|
||||
|
||||
@ -44,6 +46,8 @@ const PDFLoader = () => (
|
||||
export type PDFViewerProps = {
|
||||
className?: string;
|
||||
documentData: DocumentData;
|
||||
document?: DocumentWithData;
|
||||
documentMeta?: DocumentMeta | null;
|
||||
onDocumentLoad?: (_doc: LoadedPDFDocument) => void;
|
||||
onPageClick?: OnPDFViewerPageClick;
|
||||
[key: string]: unknown;
|
||||
@ -52,6 +56,8 @@ export type PDFViewerProps = {
|
||||
export const PDFViewer = ({
|
||||
className,
|
||||
documentData,
|
||||
document,
|
||||
documentMeta,
|
||||
onDocumentLoad,
|
||||
onPageClick,
|
||||
...props
|
||||
@ -62,7 +68,7 @@ export const PDFViewer = ({
|
||||
|
||||
const [isDocumentBytesLoading, setIsDocumentBytesLoading] = useState(false);
|
||||
const [isPasswordModalOpen, setIsPasswordModalOpen] = useState(false);
|
||||
const [password, setPassword] = useState<string | null>(null);
|
||||
const [password, setPassword] = useState<string | null>(documentMeta?.documentPassword || null);
|
||||
const passwordCallbackRef = useRef<((password: string | null) => void) | null>(null);
|
||||
const [isPasswordError, setIsPasswordError] = useState(false);
|
||||
const [documentBytes, setDocumentBytes] = useState<Uint8Array | null>(null);
|
||||
@ -76,6 +82,9 @@ export const PDFViewer = ({
|
||||
[documentData.data, documentData.type],
|
||||
);
|
||||
|
||||
const {mutateAsync: addDocumentPassword } = trpc.document.setDocumentPassword.useMutation();
|
||||
|
||||
|
||||
const isLoading = isDocumentBytesLoading || !documentBytes;
|
||||
|
||||
const onDocumentLoaded = (doc: LoadedPDFDocument) => {
|
||||
@ -83,12 +92,20 @@ export const PDFViewer = ({
|
||||
onDocumentLoad?.(doc);
|
||||
};
|
||||
|
||||
const onPasswordSubmit = () => {
|
||||
const onPasswordSubmit = async() => {
|
||||
setIsPasswordModalOpen(false);
|
||||
if (passwordCallbackRef.current) {
|
||||
passwordCallbackRef.current(password);
|
||||
try{
|
||||
await addDocumentPassword({
|
||||
documentId: document?.id ?? 0,
|
||||
documentPassword: password!,
|
||||
});
|
||||
passwordCallbackRef.current?.(password);
|
||||
} catch (error) {
|
||||
console.error('Error adding document password:', error);
|
||||
} finally {
|
||||
passwordCallbackRef.current = null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const onDocumentPageClick = (
|
||||
@ -189,6 +206,11 @@ export const PDFViewer = ({
|
||||
'h-[80vh] max-h-[60rem]': numPages === 0,
|
||||
})}
|
||||
onPassword={(callback, reason) => {
|
||||
// If the documentMeta already has a password, we don't need to ask for it again.
|
||||
if(password && reason !== PasswordResponses.INCORRECT_PASSWORD){
|
||||
callback(password);
|
||||
return;
|
||||
}
|
||||
setIsPasswordModalOpen(true);
|
||||
passwordCallbackRef.current = callback;
|
||||
switch (reason) {
|
||||
|
||||
Reference in New Issue
Block a user