mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 16:51:38 +10:00
feat: avoid sending document if the owner is the only recipient
This commit is contained in:
@ -6,6 +6,7 @@ import { useRouter, useSearchParams } from 'next/navigation';
|
|||||||
|
|
||||||
import { msg } from '@lingui/macro';
|
import { msg } from '@lingui/macro';
|
||||||
import { useLingui } from '@lingui/react';
|
import { useLingui } from '@lingui/react';
|
||||||
|
import { useSession } from 'next-auth/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
|
DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
|
||||||
@ -53,6 +54,7 @@ export const EditDocumentForm = ({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const team = useOptionalCurrentTeam();
|
const team = useOptionalCurrentTeam();
|
||||||
|
const { data: session } = useSession();
|
||||||
|
|
||||||
const [isDocumentPdfLoaded, setIsDocumentPdfLoaded] = useState(false);
|
const [isDocumentPdfLoaded, setIsDocumentPdfLoaded] = useState(false);
|
||||||
|
|
||||||
@ -138,6 +140,19 @@ export const EditDocumentForm = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { mutateAsync: selfSignDocument } = trpc.document.selfSignDocument.useMutation({
|
||||||
|
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
|
||||||
|
onSuccess: (newData) => {
|
||||||
|
utils.document.getDocumentWithDetailsById.setData(
|
||||||
|
{
|
||||||
|
id: initialDocument.id,
|
||||||
|
teamId: team?.id,
|
||||||
|
},
|
||||||
|
(oldData) => ({ ...(oldData || initialDocument), ...newData }),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const { mutateAsync: setPasswordForDocument } =
|
const { mutateAsync: setPasswordForDocument } =
|
||||||
trpc.document.setPasswordForDocument.useMutation();
|
trpc.document.setPasswordForDocument.useMutation();
|
||||||
|
|
||||||
@ -266,10 +281,22 @@ export const EditDocumentForm = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hasSameOwnerAsRecipient =
|
||||||
|
recipients.length === 1 && recipients[0].email === session?.user?.email;
|
||||||
|
|
||||||
|
if (hasSameOwnerAsRecipient) {
|
||||||
|
await selfSignDocument({
|
||||||
|
documentId: document.id,
|
||||||
|
teamId: team?.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
router.push(`/sign/${recipients[0].token}`);
|
||||||
|
} else {
|
||||||
// Router refresh is here to clear the router cache for when navigating to /documents.
|
// Router refresh is here to clear the router cache for when navigating to /documents.
|
||||||
router.refresh();
|
router.refresh();
|
||||||
|
|
||||||
setStep('subject');
|
setStep('subject');
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import {
|
|||||||
ZMoveDocumentsToTeamSchema,
|
ZMoveDocumentsToTeamSchema,
|
||||||
ZResendDocumentMutationSchema,
|
ZResendDocumentMutationSchema,
|
||||||
ZSearchDocumentsMutationSchema,
|
ZSearchDocumentsMutationSchema,
|
||||||
|
ZSelfSignDocumentMutationSchema,
|
||||||
ZSendDocumentMutationSchema,
|
ZSendDocumentMutationSchema,
|
||||||
ZSetPasswordForDocumentMutationSchema,
|
ZSetPasswordForDocumentMutationSchema,
|
||||||
ZSetSettingsForDocumentMutationSchema,
|
ZSetSettingsForDocumentMutationSchema,
|
||||||
@ -367,6 +368,29 @@ export const documentRouter = router({
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
selfSignDocument: authenticatedProcedure
|
||||||
|
.input(ZSelfSignDocumentMutationSchema)
|
||||||
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
|
const { documentId, teamId } = input;
|
||||||
|
|
||||||
|
return await sendDocument({
|
||||||
|
userId: ctx.user.id,
|
||||||
|
documentId,
|
||||||
|
teamId,
|
||||||
|
sendEmail: false,
|
||||||
|
requestMetadata: extractNextApiRequestMetadata(ctx.req),
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw new TRPCError({
|
||||||
|
code: 'BAD_REQUEST',
|
||||||
|
message: 'We were unable to self sign this document. Please try again later.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
resendDocument: authenticatedProcedure
|
resendDocument: authenticatedProcedure
|
||||||
.input(ZResendDocumentMutationSchema)
|
.input(ZResendDocumentMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
|||||||
@ -140,6 +140,11 @@ export const ZSendDocumentMutationSchema = z.object({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ZSelfSignDocumentMutationSchema = z.object({
|
||||||
|
documentId: z.number(),
|
||||||
|
teamId: z.number().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
export const ZSetPasswordForDocumentMutationSchema = z.object({
|
export const ZSetPasswordForDocumentMutationSchema = z.object({
|
||||||
documentId: z.number(),
|
documentId: z.number(),
|
||||||
password: z.string(),
|
password: z.string(),
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import {
|
|||||||
Type,
|
Type,
|
||||||
User,
|
User,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
import { useSession } from 'next-auth/react';
|
||||||
import { useFieldArray, useForm } from 'react-hook-form';
|
import { useFieldArray, useForm } from 'react-hook-form';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { prop, sortBy } from 'remeda';
|
import { prop, sortBy } from 'remeda';
|
||||||
@ -99,6 +100,13 @@ export type AddFieldsFormProps = {
|
|||||||
teamId?: number;
|
teamId?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Self Sign
|
||||||
|
// If the recipient is the user and it is the only recipient,
|
||||||
|
// dont send the document, after adding the fields, skip the next step and go straight to the point
|
||||||
|
// no need for the sending section
|
||||||
|
// it will create the document
|
||||||
|
// and redirect you to the signing page.
|
||||||
|
|
||||||
export const AddFieldsFormPartial = ({
|
export const AddFieldsFormPartial = ({
|
||||||
documentFlow,
|
documentFlow,
|
||||||
hideRecipients = false,
|
hideRecipients = false,
|
||||||
@ -110,6 +118,7 @@ export const AddFieldsFormPartial = ({
|
|||||||
teamId,
|
teamId,
|
||||||
}: AddFieldsFormProps) => {
|
}: AddFieldsFormProps) => {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
const { data: session } = useSession();
|
||||||
|
|
||||||
const [isMissingSignatureDialogVisible, setIsMissingSignatureDialogVisible] = useState(false);
|
const [isMissingSignatureDialogVisible, setIsMissingSignatureDialogVisible] = useState(false);
|
||||||
|
|
||||||
@ -530,6 +539,10 @@ export const AddFieldsFormPartial = ({
|
|||||||
);
|
);
|
||||||
}, [recipientsByRole]);
|
}, [recipientsByRole]);
|
||||||
|
|
||||||
|
const hasSameOwnerAsRecipient =
|
||||||
|
recipientsByRole.SIGNER.length === 1 &&
|
||||||
|
recipientsByRole.SIGNER[0].email === session?.user?.email;
|
||||||
|
|
||||||
const handleAdvancedSettings = () => {
|
const handleAdvancedSettings = () => {
|
||||||
setShowAdvancedSettings((prev) => !prev);
|
setShowAdvancedSettings((prev) => !prev);
|
||||||
};
|
};
|
||||||
@ -1067,6 +1080,7 @@ export const AddFieldsFormPartial = ({
|
|||||||
documentFlow.onBackStep?.();
|
documentFlow.onBackStep?.();
|
||||||
}}
|
}}
|
||||||
goBackLabel={canRenderBackButtonAsRemove ? msg`Remove` : undefined}
|
goBackLabel={canRenderBackButtonAsRemove ? msg`Remove` : undefined}
|
||||||
|
goNextLabel={hasSameOwnerAsRecipient ? msg`Self Sign` : undefined}
|
||||||
onGoNextClick={handleGoNextClick}
|
onGoNextClick={handleGoNextClick}
|
||||||
/>
|
/>
|
||||||
</DocumentFlowFormContainerFooter>
|
</DocumentFlowFormContainerFooter>
|
||||||
|
|||||||
Reference in New Issue
Block a user