Compare commits

...

6 Commits

Author SHA1 Message Date
49b61c6c07 feat: improve resend dialog 2025-09-17 10:31:23 +03:00
e49910c8ef Merge branch 'main' of github.com:documenso/documenso 2025-09-17 10:12:37 +03:00
a4fe4b4951 feat: show branding logo on signing page 2025-09-15 15:43:34 +03:00
ed4dfc9b55 v1.12.4 2025-09-13 18:08:55 +10:00
32ce573de4 fix: incorrect certificate health logic (#2028) 2025-09-13 18:07:39 +10:00
2ecfdbdde5 v1.12.3 2025-09-12 23:02:59 +10:00
9 changed files with 46 additions and 13 deletions

View File

@ -6,7 +6,7 @@ import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro'; import { Trans } from '@lingui/react/macro';
import { type Recipient, SigningStatus } from '@prisma/client'; import { type Recipient, SigningStatus } from '@prisma/client';
import { History } from 'lucide-react'; import { History } from 'lucide-react';
import { useForm } from 'react-hook-form'; import { useForm, useWatch } from 'react-hook-form';
import * as z from 'zod'; import * as z from 'zod';
import { useSession } from '@documenso/lib/client-only/providers/session'; import { useSession } from '@documenso/lib/client-only/providers/session';
@ -85,6 +85,11 @@ export const DocumentResendDialog = ({ document, recipients }: DocumentResendDia
formState: { isSubmitting }, formState: { isSubmitting },
} = form; } = form;
const selectedRecipients = useWatch({
control: form.control,
name: 'recipients',
});
const onFormSubmit = async ({ recipients }: TResendDocumentFormSchema) => { const onFormSubmit = async ({ recipients }: TResendDocumentFormSchema) => {
try { try {
await resendDocument({ documentId: document.id, recipients }); await resendDocument({ documentId: document.id, recipients });
@ -151,7 +156,7 @@ export const DocumentResendDialog = ({ document, recipients }: DocumentResendDia
<FormControl> <FormControl>
<Checkbox <Checkbox
className="h-5 w-5 rounded-full" className="h-5 w-5 rounded-full border border-neutral-400"
value={recipient.id} value={recipient.id}
checked={value.includes(recipient.id)} checked={value.includes(recipient.id)}
onCheckedChange={(checked: boolean) => onCheckedChange={(checked: boolean) =>
@ -182,7 +187,13 @@ export const DocumentResendDialog = ({ document, recipients }: DocumentResendDia
</Button> </Button>
</DialogClose> </DialogClose>
<Button className="flex-1" loading={isSubmitting} type="submit" form={FORM_ID}> <Button
className="flex-1"
loading={isSubmitting}
type="submit"
form={FORM_ID}
disabled={isSubmitting || selectedRecipients.length === 0}
>
<Trans>Send reminder</Trans> <Trans>Send reminder</Trans>
</Button> </Button>
</div> </div>

View File

@ -160,6 +160,14 @@ export const DocumentSigningPageView = ({
return ( return (
<DocumentSigningRecipientProvider recipient={recipient} targetSigner={targetSigner}> <DocumentSigningRecipientProvider recipient={recipient} targetSigner={targetSigner}>
<div className="mx-auto w-full max-w-screen-xl sm:px-6"> <div className="mx-auto w-full max-w-screen-xl sm:px-6">
{document.team.teamGlobalSettings.brandingEnabled &&
document.team.teamGlobalSettings.brandingLogo && (
<img
src={`/api/branding/logo/team/${document.teamId}`}
alt={`${document.team.name}'s Logo`}
className="mb-4 h-12 w-12 md:mb-2"
/>
)}
<h1 <h1
className="block max-w-[20rem] truncate text-2xl font-semibold sm:mt-4 md:max-w-[30rem] md:text-3xl" className="block max-w-[20rem] truncate text-2xl font-semibold sm:mt-4 md:max-w-[30rem] md:text-3xl"
title={document.title} title={document.title}

View File

@ -23,10 +23,12 @@ export const loader = async () => {
try { try {
const certStatus = getCertificateStatus(); const certStatus = getCertificateStatus();
if (certStatus.isAvailable) { if (certStatus.isAvailable) {
checks.certificate = { status: 'ok' }; checks.certificate = { status: 'ok' };
} else { } else {
checks.certificate = { status: 'warning' }; checks.certificate = { status: 'warning' };
if (overallStatus === 'ok') { if (overallStatus === 'ok') {
overallStatus = 'warning'; overallStatus = 'warning';
} }

View File

@ -101,5 +101,5 @@
"vite-plugin-babel-macros": "^1.0.6", "vite-plugin-babel-macros": "^1.0.6",
"vite-tsconfig-paths": "^5.1.4" "vite-tsconfig-paths": "^5.1.4"
}, },
"version": "1.12.2-rc.6" "version": "1.12.4"
} }

6
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "@documenso/root", "name": "@documenso/root",
"version": "1.12.2-rc.6", "version": "1.12.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@documenso/root", "name": "@documenso/root",
"version": "1.12.2-rc.6", "version": "1.12.4",
"workspaces": [ "workspaces": [
"apps/*", "apps/*",
"packages/*" "packages/*"
@ -89,7 +89,7 @@
}, },
"apps/remix": { "apps/remix": {
"name": "@documenso/remix", "name": "@documenso/remix",
"version": "1.12.2-rc.6", "version": "1.12.4",
"dependencies": { "dependencies": {
"@documenso/api": "*", "@documenso/api": "*",
"@documenso/assets": "*", "@documenso/assets": "*",

View File

@ -1,6 +1,6 @@
{ {
"private": true, "private": true,
"version": "1.12.2-rc.6", "version": "1.12.4",
"scripts": { "scripts": {
"build": "turbo run build", "build": "turbo run build",
"dev": "turbo run dev --filter=@documenso/remix", "dev": "turbo run dev --filter=@documenso/remix",

View File

@ -2,18 +2,25 @@ import * as fs from 'node:fs';
import { env } from '@documenso/lib/utils/env'; import { env } from '@documenso/lib/utils/env';
export type CertificateStatus = { export const getCertificateStatus = () => {
isAvailable: boolean; if (env('NEXT_PRIVATE_SIGNING_TRANSPORT') !== 'local') {
}; return { isAvailable: true };
}
if (env('NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS')) {
return { isAvailable: true };
}
export const getCertificateStatus = (): CertificateStatus => {
const defaultPath = const defaultPath =
env('NODE_ENV') === 'production' ? '/opt/documenso/cert.p12' : './example/cert.p12'; env('NODE_ENV') === 'production' ? '/opt/documenso/cert.p12' : './example/cert.p12';
const filePath = env('NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH') || defaultPath; const filePath = env('NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH') || defaultPath;
try { try {
fs.accessSync(filePath, fs.constants.F_OK | fs.constants.R_OK); fs.accessSync(filePath, fs.constants.F_OK | fs.constants.R_OK);
const stats = fs.statSync(filePath); const stats = fs.statSync(filePath);
return { isAvailable: stats.size > 0 }; return { isAvailable: stats.size > 0 };
} catch { } catch {
return { isAvailable: false }; return { isAvailable: false };

View File

@ -91,6 +91,12 @@ export const getDocumentAndSenderByToken = async ({
select: { select: {
name: true, name: true,
teamEmail: true, teamEmail: true,
teamGlobalSettings: {
select: {
brandingEnabled: true,
brandingLogo: true,
},
},
}, },
}, },
}, },

View File

@ -714,7 +714,6 @@ export const AddSignersFormPartial = ({
handleRecipientAutoCompleteSelect(index, suggestion) handleRecipientAutoCompleteSelect(index, suggestion)
} }
onSearchQueryChange={(query) => { onSearchQueryChange={(query) => {
console.log('onSearchQueryChange', query);
field.onChange(query); field.onChange(query);
setRecipientSearchQuery(query); setRecipientSearchQuery(query);
}} }}