Compare commits
10 Commits
fix/team-m
...
fix/field-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c68eb4f198 | ||
|
|
33c2cbe01d | ||
|
|
db326cb4a9 | ||
|
|
d664f571d6 | ||
|
|
7c38970ee8 | ||
|
|
e08d62c844 | ||
|
|
25bb6ffe77 | ||
|
|
e79d762710 | ||
|
|
d970976299 | ||
|
|
3dce814ab2 |
@@ -1,7 +1,7 @@
|
|||||||
|
import { DocumentStatus } from '@prisma/client';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
|
||||||
import { kyselyPrisma, sql } from '@documenso/prisma';
|
import { kyselyPrisma, sql } from '@documenso/prisma';
|
||||||
import { DocumentStatus } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
export const getCompletedDocumentsMonthly = async (type: 'count' | 'cumulative' = 'count') => {
|
export const getCompletedDocumentsMonthly = async (type: 'count' | 'cumulative' = 'count') => {
|
||||||
const qb = kyselyPrisma.$kysely
|
const qb = kyselyPrisma.$kysely
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ export const EmbedDirectTemplateClientPage = ({
|
|||||||
{/* Widget */}
|
{/* Widget */}
|
||||||
<div
|
<div
|
||||||
key={isExpanded ? 'expanded' : 'collapsed'}
|
key={isExpanded ? 'expanded' : 'collapsed'}
|
||||||
className="group/document-widget fixed bottom-8 left-0 z-50 h-fit w-full flex-shrink-0 px-6 md:sticky md:top-4 md:z-auto md:w-[350px] md:px-0"
|
className="group/document-widget fixed bottom-8 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full flex-shrink-0 px-6 md:sticky md:top-4 md:z-auto md:w-[350px] md:px-0"
|
||||||
data-expanded={isExpanded || undefined}
|
data-expanded={isExpanded || undefined}
|
||||||
>
|
>
|
||||||
<div className="border-border bg-widget flex h-fit w-full flex-col rounded-xl border px-4 py-4 md:min-h-[min(calc(100dvh-2rem),48rem)] md:py-6">
|
<div className="border-border bg-widget flex h-fit w-full flex-col rounded-xl border px-4 py-4 md:min-h-[min(calc(100dvh-2rem),48rem)] md:py-6">
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ export const EmbedSignDocumentClientPage = ({
|
|||||||
{/* Widget */}
|
{/* Widget */}
|
||||||
<div
|
<div
|
||||||
key={isExpanded ? 'expanded' : 'collapsed'}
|
key={isExpanded ? 'expanded' : 'collapsed'}
|
||||||
className="embed--DocumentWidgetContainer group/document-widget fixed bottom-8 left-0 z-50 h-fit w-full flex-shrink-0 px-6 md:sticky md:top-4 md:z-auto md:w-[350px] md:px-0"
|
className="embed--DocumentWidgetContainer group/document-widget fixed bottom-8 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full flex-shrink-0 px-6 md:sticky md:top-4 md:z-auto md:w-[350px] md:px-0"
|
||||||
data-expanded={isExpanded || undefined}
|
data-expanded={isExpanded || undefined}
|
||||||
>
|
>
|
||||||
<div className="embed--DocumentWidget border-border bg-widget flex w-full flex-col rounded-xl border px-4 py-4 md:py-6">
|
<div className="embed--DocumentWidget border-border bg-widget flex w-full flex-col rounded-xl border px-4 py-4 md:py-6">
|
||||||
|
|||||||
@@ -181,6 +181,23 @@ export const DocumentSigningFieldContainer = ({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{(field.type === FieldType.RADIO || field.type === FieldType.CHECKBOX) &&
|
||||||
|
field.fieldMeta?.label && (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'absolute -top-16 left-0 right-0 rounded-md p-2 text-center text-xs text-gray-700',
|
||||||
|
{
|
||||||
|
'bg-foreground/5 border-border border': !field.inserted,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'bg-documenso-200 border-primary border': field.inserted,
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{field.fieldMeta.label}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</FieldRootContainer>
|
</FieldRootContainer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export const GenericErrorLayout = ({
|
|||||||
const team = useOptionalCurrentTeam();
|
const team = useOptionalCurrentTeam();
|
||||||
|
|
||||||
const { subHeading, heading, message } =
|
const { subHeading, heading, message } =
|
||||||
errorCodeMap[errorCode || 404] ?? defaultErrorCodeMap[500];
|
errorCodeMap[errorCode || 500] ?? defaultErrorCodeMap[500];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 z-0 flex h-screen w-screen items-center justify-center">
|
<div className="fixed inset-0 z-0 flex h-screen w-screen items-center justify-center">
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import Plausible from 'plausible-tracker';
|
import Plausible from 'plausible-tracker';
|
||||||
import posthog from 'posthog-js';
|
|
||||||
import {
|
import {
|
||||||
Links,
|
Links,
|
||||||
Meta,
|
Meta,
|
||||||
@@ -181,7 +180,6 @@ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
|
|||||||
|
|
||||||
if (errorCode !== 404) {
|
if (errorCode !== 404) {
|
||||||
console.error('[RootErrorBoundary]', error);
|
console.error('[RootErrorBoundary]', error);
|
||||||
posthog.captureException(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <GenericErrorLayout errorCode={errorCode} />;
|
return <GenericErrorLayout errorCode={errorCode} />;
|
||||||
|
|||||||
@@ -19,18 +19,29 @@ const posthogProxy = async (request: Request) => {
|
|||||||
const headers = new Headers(request.headers);
|
const headers = new Headers(request.headers);
|
||||||
headers.set('host', hostname);
|
headers.set('host', hostname);
|
||||||
|
|
||||||
const response = await fetch(newUrl, {
|
const fetchOptions: RequestInit = {
|
||||||
method: request.method,
|
method: request.method,
|
||||||
headers,
|
headers,
|
||||||
body: request.body,
|
redirect: 'follow',
|
||||||
// @ts-expect-error - Not really sure about this
|
};
|
||||||
duplex: 'half',
|
|
||||||
});
|
if (!['GET', 'HEAD'].includes(request.method)) {
|
||||||
|
fetchOptions.body = request.body;
|
||||||
|
fetchOptions.duplex = 'half';
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(newUrl, fetchOptions);
|
||||||
|
|
||||||
|
const responseHeaders = new Headers(response.headers);
|
||||||
|
responseHeaders.delete('content-encoding');
|
||||||
|
responseHeaders.delete('content-length');
|
||||||
|
responseHeaders.delete('transfer-encoding');
|
||||||
|
responseHeaders.delete('cookie');
|
||||||
|
|
||||||
return new Response(response.body, {
|
return new Response(response.body, {
|
||||||
status: response.status,
|
status: response.status,
|
||||||
statusText: response.statusText,
|
statusText: response.statusText,
|
||||||
headers: response.headers,
|
headers: responseHeaders,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,9 @@ export default function EmbedDirectTemplatePage() {
|
|||||||
recipient={recipient}
|
recipient={recipient}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
metadata={template.templateMeta}
|
metadata={template.templateMeta}
|
||||||
hidePoweredBy={isPlatformDocument || isEnterpriseDocument || hidePoweredBy}
|
hidePoweredBy={
|
||||||
|
isCommunityPlan || isPlatformDocument || isEnterpriseDocument || hidePoweredBy
|
||||||
|
}
|
||||||
allowWhiteLabelling={isCommunityPlan || isPlatformDocument || isEnterpriseDocument}
|
allowWhiteLabelling={isCommunityPlan || isPlatformDocument || isEnterpriseDocument}
|
||||||
/>
|
/>
|
||||||
</DocumentSigningRecipientProvider>
|
</DocumentSigningRecipientProvider>
|
||||||
|
|||||||
@@ -169,7 +169,9 @@ export default function EmbedSignDocumentPage() {
|
|||||||
fields={fields}
|
fields={fields}
|
||||||
metadata={document.documentMeta}
|
metadata={document.documentMeta}
|
||||||
isCompleted={document.status === DocumentStatus.COMPLETED}
|
isCompleted={document.status === DocumentStatus.COMPLETED}
|
||||||
hidePoweredBy={isPlatformDocument || isEnterpriseDocument || hidePoweredBy}
|
hidePoweredBy={
|
||||||
|
isCommunityPlan || isPlatformDocument || isEnterpriseDocument || hidePoweredBy
|
||||||
|
}
|
||||||
allowWhitelabelling={isCommunityPlan || isPlatformDocument || isEnterpriseDocument}
|
allowWhitelabelling={isCommunityPlan || isPlatformDocument || isEnterpriseDocument}
|
||||||
allRecipients={allRecipients}
|
allRecipients={allRecipients}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { fetchRequestHandler } from '@ts-rest/serverless/fetch';
|
import { TsRestHttpError, fetchRequestHandler } from '@ts-rest/serverless/fetch';
|
||||||
import { Hono } from 'hono';
|
import { Hono } from 'hono';
|
||||||
|
|
||||||
import { ApiContractV1 } from '@documenso/api/v1/contract';
|
import { ApiContractV1 } from '@documenso/api/v1/contract';
|
||||||
@@ -29,6 +29,12 @@ tsRestHonoApp.mount('/', async (request) => {
|
|||||||
request,
|
request,
|
||||||
contract: ApiContractV1,
|
contract: ApiContractV1,
|
||||||
router: ApiContractV1Implementation,
|
router: ApiContractV1Implementation,
|
||||||
options: {},
|
options: {
|
||||||
|
errorHandler: (err) => {
|
||||||
|
if (err instanceof TsRestHttpError && err.statusCode === 500) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import type { Prisma } from '@prisma/client';
|
||||||
|
import { DocumentDataType, DocumentStatus, SigningStatus, TeamMemberRole } from '@prisma/client';
|
||||||
import { tsr } from '@ts-rest/serverless/fetch';
|
import { tsr } from '@ts-rest/serverless/fetch';
|
||||||
import { match } from 'ts-pattern';
|
import { match } from 'ts-pattern';
|
||||||
|
|
||||||
@@ -50,13 +52,6 @@ import {
|
|||||||
} from '@documenso/lib/universal/upload/server-actions';
|
} from '@documenso/lib/universal/upload/server-actions';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { Prisma } from '@documenso/prisma/client';
|
|
||||||
import {
|
|
||||||
DocumentDataType,
|
|
||||||
DocumentStatus,
|
|
||||||
SigningStatus,
|
|
||||||
TeamMemberRole,
|
|
||||||
} from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { ApiContractV1 } from './contract';
|
import { ApiContractV1 } from './contract';
|
||||||
import { authenticatedMiddleware } from './middleware/authenticated';
|
import { authenticatedMiddleware } from './middleware/authenticated';
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
import type { Team, User } from '@prisma/client';
|
||||||
import type { TsRestRequest } from '@ts-rest/serverless';
|
import type { TsRestRequest } from '@ts-rest/serverless';
|
||||||
|
|
||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
|
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
|
||||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import type { Team, User } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
type B = {
|
type B = {
|
||||||
// appRoute: any;
|
// appRoute: any;
|
||||||
|
|||||||
@@ -1,4 +1,16 @@
|
|||||||
import { extendZodWithOpenApi } from '@anatine/zod-openapi';
|
import { extendZodWithOpenApi } from '@anatine/zod-openapi';
|
||||||
|
import {
|
||||||
|
DocumentDataType,
|
||||||
|
DocumentDistributionMethod,
|
||||||
|
DocumentSigningOrder,
|
||||||
|
FieldType,
|
||||||
|
ReadStatus,
|
||||||
|
RecipientRole,
|
||||||
|
SendStatus,
|
||||||
|
SigningStatus,
|
||||||
|
TeamMemberRole,
|
||||||
|
TemplateType,
|
||||||
|
} from '@prisma/client';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { DATE_FORMATS, DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
|
import { DATE_FORMATS, DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
|
||||||
@@ -12,18 +24,6 @@ import {
|
|||||||
} from '@documenso/lib/types/document-auth';
|
} from '@documenso/lib/types/document-auth';
|
||||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||||
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
|
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
|
||||||
import {
|
|
||||||
DocumentDataType,
|
|
||||||
DocumentDistributionMethod,
|
|
||||||
DocumentSigningOrder,
|
|
||||||
FieldType,
|
|
||||||
ReadStatus,
|
|
||||||
RecipientRole,
|
|
||||||
SendStatus,
|
|
||||||
SigningStatus,
|
|
||||||
TeamMemberRole,
|
|
||||||
TemplateType,
|
|
||||||
} from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
extendZodWithOpenApi(z);
|
extendZodWithOpenApi(z);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import { TeamMemberRole } from '@prisma/client';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ZFindTeamMembersResponseSchema,
|
ZFindTeamMembersResponseSchema,
|
||||||
@@ -10,7 +11,6 @@ import {
|
|||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
|
||||||
import { seedTeam } from '@documenso/prisma/seed/teams';
|
import { seedTeam } from '@documenso/prisma/seed/teams';
|
||||||
import { seedUser } from '@documenso/prisma/seed/users';
|
import { seedUser } from '@documenso/prisma/seed/users';
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import { FieldType } from '@prisma/client';
|
||||||
|
|
||||||
import { ZRecipientAuthOptionsSchema } from '@documenso/lib/types/document-auth';
|
import { ZRecipientAuthOptionsSchema } from '@documenso/lib/types/document-auth';
|
||||||
import {
|
import {
|
||||||
createDocumentAuthOptions,
|
createDocumentAuthOptions,
|
||||||
createRecipientAuthOptions,
|
createRecipientAuthOptions,
|
||||||
} from '@documenso/lib/utils/document-auth';
|
} from '@documenso/lib/utils/document-auth';
|
||||||
import { FieldType } from '@documenso/prisma/client';
|
|
||||||
import {
|
import {
|
||||||
seedPendingDocumentNoFields,
|
seedPendingDocumentNoFields,
|
||||||
seedPendingDocumentWithFullFields,
|
seedPendingDocumentWithFullFields,
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
import { DateTime } from 'luxon';
|
|
||||||
import path from 'node:path';
|
|
||||||
|
|
||||||
import { getRecipientByEmail } from '@documenso/lib/server-only/recipient/get-recipient-by-email';
|
|
||||||
import { prisma } from '@documenso/prisma';
|
|
||||||
import {
|
import {
|
||||||
DocumentSigningOrder,
|
DocumentSigningOrder,
|
||||||
DocumentStatus,
|
DocumentStatus,
|
||||||
FieldType,
|
FieldType,
|
||||||
RecipientRole,
|
RecipientRole,
|
||||||
SigningStatus,
|
SigningStatus,
|
||||||
} from '@documenso/prisma/client';
|
} from '@prisma/client';
|
||||||
|
import { DateTime } from 'luxon';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import { getRecipientByEmail } from '@documenso/lib/server-only/recipient/get-recipient-by-email';
|
||||||
|
import { prisma } from '@documenso/prisma';
|
||||||
import {
|
import {
|
||||||
seedBlankDocument,
|
seedBlankDocument,
|
||||||
seedPendingDocumentWithFullFields,
|
seedPendingDocumentWithFullFields,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import { DocumentStatus, FieldType } from '@prisma/client';
|
||||||
import { PDFDocument } from 'pdf-lib';
|
import { PDFDocument } from 'pdf-lib';
|
||||||
|
|
||||||
import { getDocumentByToken } from '@documenso/lib/server-only/document/get-document-by-token';
|
import { getDocumentByToken } from '@documenso/lib/server-only/document/get-document-by-token';
|
||||||
import { getFile } from '@documenso/lib/universal/upload/get-file';
|
import { getFile } from '@documenso/lib/universal/upload/get-file';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { DocumentStatus, FieldType } from '@documenso/prisma/client';
|
|
||||||
import { seedPendingDocumentWithFullFields } from '@documenso/prisma/seed/documents';
|
import { seedPendingDocumentWithFullFields } from '@documenso/prisma/seed/documents';
|
||||||
import { seedTeam } from '@documenso/prisma/seed/teams';
|
import { seedTeam } from '@documenso/prisma/seed/teams';
|
||||||
import { seedUser } from '@documenso/prisma/seed/users';
|
import { seedUser } from '@documenso/prisma/seed/users';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import { DocumentStatus, TeamMemberRole } from '@prisma/client';
|
||||||
|
|
||||||
import { DocumentStatus, TeamMemberRole } from '@documenso/prisma/client';
|
|
||||||
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
|
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
|
||||||
import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
|
import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||||
import { seedUser } from '@documenso/prisma/seed/users';
|
import { seedUser } from '@documenso/prisma/seed/users';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import { DocumentStatus, DocumentVisibility, TeamMemberRole } from '@prisma/client';
|
||||||
|
|
||||||
import { DocumentStatus, DocumentVisibility, TeamMemberRole } from '@documenso/prisma/client';
|
|
||||||
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
|
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
|
||||||
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
|
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
|
||||||
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
|
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import { TeamMemberRole } from '@prisma/client';
|
||||||
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
|
||||||
import { seedUserSubscription } from '@documenso/prisma/seed/subscriptions';
|
import { seedUserSubscription } from '@documenso/prisma/seed/subscriptions';
|
||||||
import { seedTeam } from '@documenso/prisma/seed/teams';
|
import { seedTeam } from '@documenso/prisma/seed/teams';
|
||||||
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
|
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
|
||||||
@@ -12,7 +12,7 @@ import { apiSignin } from '../fixtures/authentication';
|
|||||||
test.describe.configure({ mode: 'parallel' });
|
test.describe.configure({ mode: 'parallel' });
|
||||||
|
|
||||||
test.describe('[EE_ONLY]', () => {
|
test.describe('[EE_ONLY]', () => {
|
||||||
const enterprisePriceId = process.env.NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID || '';
|
const enterprisePriceId = '';
|
||||||
|
|
||||||
test.beforeEach(() => {
|
test.beforeEach(() => {
|
||||||
test.skip(
|
test.skip(
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import { DocumentDataType, TeamMemberRole } from '@prisma/client';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
|
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { DocumentDataType, TeamMemberRole } from '@documenso/prisma/client';
|
|
||||||
import { seedUserSubscription } from '@documenso/prisma/seed/subscriptions';
|
import { seedUserSubscription } from '@documenso/prisma/seed/subscriptions';
|
||||||
import { seedTeam } from '@documenso/prisma/seed/teams';
|
import { seedTeam } from '@documenso/prisma/seed/teams';
|
||||||
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
|
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
|
||||||
@@ -15,7 +15,7 @@ import { apiSignin } from '../fixtures/authentication';
|
|||||||
|
|
||||||
test.describe.configure({ mode: 'parallel' });
|
test.describe.configure({ mode: 'parallel' });
|
||||||
|
|
||||||
const enterprisePriceId = process.env.NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID || '';
|
const enterprisePriceId = '';
|
||||||
|
|
||||||
// Create a temporary PDF file for testing
|
// Create a temporary PDF file for testing
|
||||||
function createTempPdfFile() {
|
function createTempPdfFile() {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { UserSecurityAuditLogType } from '@prisma/client';
|
||||||
import { OAuth2Client, decodeIdToken } from 'arctic';
|
import { OAuth2Client, decodeIdToken } from 'arctic';
|
||||||
import type { Context } from 'hono';
|
import type { Context } from 'hono';
|
||||||
import { deleteCookie } from 'hono/cookie';
|
import { deleteCookie } from 'hono/cookie';
|
||||||
@@ -6,7 +7,6 @@ import { nanoid } from 'nanoid';
|
|||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { onCreateUserHook } from '@documenso/lib/server-only/user/create-user';
|
import { onCreateUserHook } from '@documenso/lib/server-only/user/create-user';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { UserSecurityAuditLogType } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import type { OAuthClientOptions } from '../../config';
|
import type { OAuthClientOptions } from '../../config';
|
||||||
import { AuthenticationErrorCode } from '../errors/error-codes';
|
import { AuthenticationErrorCode } from '../errors/error-codes';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { sValidator } from '@hono/standard-validator';
|
import { sValidator } from '@hono/standard-validator';
|
||||||
import { compare } from '@node-rs/bcrypt';
|
import { compare } from '@node-rs/bcrypt';
|
||||||
|
import { UserSecurityAuditLogType } from '@prisma/client';
|
||||||
import { Hono } from 'hono';
|
import { Hono } from 'hono';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@@ -22,7 +23,6 @@ import { updatePassword } from '@documenso/lib/server-only/user/update-password'
|
|||||||
import { verifyEmail } from '@documenso/lib/server-only/user/verify-email';
|
import { verifyEmail } from '@documenso/lib/server-only/user/verify-email';
|
||||||
import { env } from '@documenso/lib/utils/env';
|
import { env } from '@documenso/lib/utils/env';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { UserSecurityAuditLogType } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { AuthenticationErrorCode } from '../lib/errors/error-codes';
|
import { AuthenticationErrorCode } from '../lib/errors/error-codes';
|
||||||
import { getCsrfCookie } from '../lib/session/session-cookies';
|
import { getCsrfCookie } from '../lib/session/session-cookies';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import { DocumentSource, SubscriptionStatus } from '@prisma/client';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
|
||||||
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { DocumentSource, SubscriptionStatus } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { getDocumentRelatedPrices } from '../stripe/get-document-related-prices.ts';
|
import { getDocumentRelatedPrices } from '../stripe/get-document-related-prices.ts';
|
||||||
import { FREE_PLAN_LIMITS, SELFHOSTED_PLAN_LIMITS, TEAM_PLAN_LIMITS } from './constants';
|
import { FREE_PLAN_LIMITS, SELFHOSTED_PLAN_LIMITS, TEAM_PLAN_LIMITS } from './constants';
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import type { User } from '@prisma/client';
|
||||||
|
|
||||||
import { STRIPE_CUSTOMER_TYPE } from '@documenso/lib/constants/billing';
|
import { STRIPE_CUSTOMER_TYPE } from '@documenso/lib/constants/billing';
|
||||||
import { stripe } from '@documenso/lib/server-only/stripe';
|
import { stripe } from '@documenso/lib/server-only/stripe';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { User } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { onSubscriptionUpdated } from './webhook/on-subscription-updated';
|
import { onSubscriptionUpdated } from './webhook/on-subscription-updated';
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ import { stripe } from '@documenso/lib/server-only/stripe';
|
|||||||
type PlanType = (typeof STRIPE_PLAN_TYPE)[keyof typeof STRIPE_PLAN_TYPE];
|
type PlanType = (typeof STRIPE_PLAN_TYPE)[keyof typeof STRIPE_PLAN_TYPE];
|
||||||
|
|
||||||
export const getPricesByPlan = async (plan: PlanType | PlanType[]) => {
|
export const getPricesByPlan = async (plan: PlanType | PlanType[]) => {
|
||||||
const planTypes = typeof plan === 'string' ? [plan] : plan;
|
const planTypes: string[] = typeof plan === 'string' ? [plan] : plan;
|
||||||
|
|
||||||
const query = planTypes.map((planType) => `metadata['plan']:'${planType}'`).join(' OR ');
|
const prices = await stripe.prices.list({
|
||||||
|
|
||||||
const { data: prices } = await stripe.prices.search({
|
|
||||||
query,
|
|
||||||
expand: ['data.product'],
|
expand: ['data.product'],
|
||||||
limit: 100,
|
limit: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
return prices.filter((price) => price.type === 'recurring');
|
return prices.data.filter(
|
||||||
|
(price) => price.type === 'recurring' && planTypes.includes(price.metadata.plan),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
import { type Subscription, type Team, type User } from '@prisma/client';
|
||||||
import type Stripe from 'stripe';
|
import type Stripe from 'stripe';
|
||||||
|
|
||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { stripe } from '@documenso/lib/server-only/stripe';
|
import { stripe } from '@documenso/lib/server-only/stripe';
|
||||||
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
|
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { type Subscription, type Team, type User } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { deleteCustomerPaymentMethods } from './delete-customer-payment-methods';
|
import { deleteCustomerPaymentMethods } from './delete-customer-payment-methods';
|
||||||
import { getTeamPrices } from './get-team-prices';
|
import { getTeamPrices } from './get-team-prices';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import { SubscriptionStatus } from '@prisma/client';
|
||||||
|
|
||||||
import type { Stripe } from '@documenso/lib/server-only/stripe';
|
import type { Stripe } from '@documenso/lib/server-only/stripe';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { SubscriptionStatus } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
export type OnSubscriptionDeletedOptions = {
|
export type OnSubscriptionDeletedOptions = {
|
||||||
subscription: Stripe.Subscription;
|
subscription: Stripe.Subscription;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import type { Prisma } from '@prisma/client';
|
||||||
|
import { SubscriptionStatus } from '@prisma/client';
|
||||||
import { match } from 'ts-pattern';
|
import { match } from 'ts-pattern';
|
||||||
|
|
||||||
import type { Stripe } from '@documenso/lib/server-only/stripe';
|
import type { Stripe } from '@documenso/lib/server-only/stripe';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { Prisma } from '@documenso/prisma/client';
|
|
||||||
import { SubscriptionStatus } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
export type OnSubscriptionUpdatedOptions = {
|
export type OnSubscriptionUpdatedOptions = {
|
||||||
userId?: number;
|
userId?: number;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import type { Subscription } from '@prisma/client';
|
||||||
|
|
||||||
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
|
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { Subscription } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { getCommunityPlanPriceIds } from '../stripe/get-community-plan-prices';
|
import { getCommunityPlanPriceIds } from '../stripe/get-community-plan-prices';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import type { Subscription } from '@prisma/client';
|
||||||
|
|
||||||
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
||||||
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
|
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { Subscription } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { getEnterprisePlanPriceIds } from '../stripe/get-enterprise-plan-prices';
|
import { getEnterprisePlanPriceIds } from '../stripe/get-enterprise-plan-prices';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import type { Document, Subscription } from '@prisma/client';
|
||||||
|
|
||||||
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
||||||
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
|
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { Document, Subscription } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { getPlatformPlanPriceIds } from '../stripe/get-platform-plan-prices';
|
import { getPlatformPlanPriceIds } from '../stripe/get-platform-plan-prices';
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { useMemo } from 'react';
|
|||||||
|
|
||||||
import { useLingui } from '@lingui/react';
|
import { useLingui } from '@lingui/react';
|
||||||
import { Trans } from '@lingui/react/macro';
|
import { Trans } from '@lingui/react/macro';
|
||||||
|
import { RecipientRole } from '@prisma/client';
|
||||||
import { P, match } from 'ts-pattern';
|
import { P, match } from 'ts-pattern';
|
||||||
|
|
||||||
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
||||||
import { RecipientRole } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { Button, Section, Text } from '../components';
|
import { Button, Section, Text } from '../components';
|
||||||
import { TemplateDocumentImage } from './template-document-image';
|
import { TemplateDocumentImage } from './template-document-image';
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { msg } from '@lingui/core/macro';
|
import { msg } from '@lingui/core/macro';
|
||||||
import { useLingui } from '@lingui/react';
|
import { useLingui } from '@lingui/react';
|
||||||
import { Trans } from '@lingui/react/macro';
|
import { Trans } from '@lingui/react/macro';
|
||||||
|
import { RecipientRole } from '@prisma/client';
|
||||||
|
|
||||||
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
||||||
import { RecipientRole } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { Body, Button, Container, Head, Html, Img, Preview, Section, Text } from '../components';
|
import { Body, Button, Container, Head, Html, Img, Preview, Section, Text } from '../components';
|
||||||
import { useBranding } from '../providers/branding';
|
import { useBranding } from '../providers/branding';
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { msg } from '@lingui/core/macro';
|
import { msg } from '@lingui/core/macro';
|
||||||
import { useLingui } from '@lingui/react';
|
import { useLingui } from '@lingui/react';
|
||||||
import { Trans } from '@lingui/react/macro';
|
import { Trans } from '@lingui/react/macro';
|
||||||
|
import type { RecipientRole } from '@prisma/client';
|
||||||
|
|
||||||
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
||||||
import type { RecipientRole } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { Body, Container, Head, Hr, Html, Img, Link, Preview, Section, Text } from '../components';
|
import { Body, Container, Head, Hr, Html, Img, Link, Preview, Section, Text } from '../components';
|
||||||
import { useBranding } from '../providers/branding';
|
import { useBranding } from '../providers/branding';
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import type { Session } from '@prisma/client';
|
||||||
import { useLocation } from 'react-router';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
import { authClient } from '@documenso/auth/client';
|
import { authClient } from '@documenso/auth/client';
|
||||||
import type { SessionUser } from '@documenso/auth/server/lib/session/session';
|
import type { SessionUser } from '@documenso/auth/server/lib/session/session';
|
||||||
import { type TGetTeamsResponse } from '@documenso/lib/server-only/team/get-teams';
|
import { type TGetTeamsResponse } from '@documenso/lib/server-only/team/get-teams';
|
||||||
import type { Session } from '@documenso/prisma/client';
|
|
||||||
import { trpc } from '@documenso/trpc/client';
|
import { trpc } from '@documenso/trpc/client';
|
||||||
|
|
||||||
export type AppSession = {
|
export type AppSession = {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createElement } from 'react';
|
import { createElement } from 'react';
|
||||||
|
|
||||||
import { msg } from '@lingui/macro';
|
import { msg } from '@lingui/macro';
|
||||||
|
import type { TeamGlobalSettings } from '@prisma/client';
|
||||||
import { parse } from 'csv-parse/sync';
|
import { parse } from 'csv-parse/sync';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@@ -10,7 +11,6 @@ import { sendDocument } from '@documenso/lib/server-only/document/send-document'
|
|||||||
import { createDocumentFromTemplate } from '@documenso/lib/server-only/template/create-document-from-template';
|
import { createDocumentFromTemplate } from '@documenso/lib/server-only/template/create-document-from-template';
|
||||||
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
|
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { TeamGlobalSettings } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { getI18nInstance } from '../../../client-only/providers/i18n-server';
|
import { getI18nInstance } from '../../../client-only/providers/i18n-server';
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import { FieldType, RecipientRole, SigningStatus } from '@prisma/client';
|
||||||
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { FieldType, RecipientRole, SigningStatus } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
export type GetFieldsForTokenOptions = {
|
export type GetFieldsForTokenOptions = {
|
||||||
token: string;
|
token: string;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import { TeamMemberRole } from '@prisma/client';
|
||||||
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
export type GetApiTokensOptions = {
|
export type GetApiTokensOptions = {
|
||||||
userId: number;
|
userId: number;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import { FieldType } from '@prisma/client';
|
||||||
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { FieldType } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||||
|
|
||||||
|
|||||||
@@ -2804,6 +2804,8 @@ msgid "Field format"
|
|||||||
msgstr "Feldformat"
|
msgstr "Feldformat"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Field label"
|
msgid "Field label"
|
||||||
msgstr "Feldbeschriftung"
|
msgstr "Feldbeschriftung"
|
||||||
|
|
||||||
@@ -3171,8 +3173,10 @@ msgid "Join {teamName} on Documenso"
|
|||||||
msgstr "Tritt {teamName} auf Documenso bei"
|
msgstr "Tritt {teamName} auf Documenso bei"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Label"
|
msgid "Label"
|
||||||
msgstr "Beschriftung"
|
msgstr "Beschriftung"
|
||||||
|
|
||||||
|
|||||||
@@ -2799,6 +2799,8 @@ msgid "Field format"
|
|||||||
msgstr "Field format"
|
msgstr "Field format"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Field label"
|
msgid "Field label"
|
||||||
msgstr "Field label"
|
msgstr "Field label"
|
||||||
|
|
||||||
@@ -3166,8 +3168,10 @@ msgid "Join {teamName} on Documenso"
|
|||||||
msgstr "Join {teamName} on Documenso"
|
msgstr "Join {teamName} on Documenso"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Label"
|
msgid "Label"
|
||||||
msgstr "Label"
|
msgstr "Label"
|
||||||
|
|
||||||
|
|||||||
@@ -2804,6 +2804,8 @@ msgid "Field format"
|
|||||||
msgstr "Formato de campo"
|
msgstr "Formato de campo"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Field label"
|
msgid "Field label"
|
||||||
msgstr "Etiqueta de campo"
|
msgstr "Etiqueta de campo"
|
||||||
|
|
||||||
@@ -3171,8 +3173,10 @@ msgid "Join {teamName} on Documenso"
|
|||||||
msgstr "Únete a {teamName} en Documenso"
|
msgstr "Únete a {teamName} en Documenso"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Label"
|
msgid "Label"
|
||||||
msgstr "Etiqueta"
|
msgstr "Etiqueta"
|
||||||
|
|
||||||
|
|||||||
@@ -2804,6 +2804,8 @@ msgid "Field format"
|
|||||||
msgstr "Format du champ"
|
msgstr "Format du champ"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Field label"
|
msgid "Field label"
|
||||||
msgstr "Étiquette du champ"
|
msgstr "Étiquette du champ"
|
||||||
|
|
||||||
@@ -3171,8 +3173,10 @@ msgid "Join {teamName} on Documenso"
|
|||||||
msgstr "Rejoindre {teamName} sur Documenso"
|
msgstr "Rejoindre {teamName} sur Documenso"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Label"
|
msgid "Label"
|
||||||
msgstr "Étiquette"
|
msgstr "Étiquette"
|
||||||
|
|
||||||
|
|||||||
@@ -2804,6 +2804,8 @@ msgid "Field format"
|
|||||||
msgstr "Formato del campo"
|
msgstr "Formato del campo"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Field label"
|
msgid "Field label"
|
||||||
msgstr "Etichetta del campo"
|
msgstr "Etichetta del campo"
|
||||||
|
|
||||||
@@ -3171,8 +3173,10 @@ msgid "Join {teamName} on Documenso"
|
|||||||
msgstr "Unisci a {teamName} su Documenso"
|
msgstr "Unisci a {teamName} su Documenso"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Label"
|
msgid "Label"
|
||||||
msgstr "Etichetta"
|
msgstr "Etichetta"
|
||||||
|
|
||||||
|
|||||||
@@ -2804,6 +2804,8 @@ msgid "Field format"
|
|||||||
msgstr "Format pola"
|
msgstr "Format pola"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Field label"
|
msgid "Field label"
|
||||||
msgstr "Etykieta pola"
|
msgstr "Etykieta pola"
|
||||||
|
|
||||||
@@ -3171,8 +3173,10 @@ msgid "Join {teamName} on Documenso"
|
|||||||
msgstr "Dołącz do {teamName} na Documenso"
|
msgstr "Dołącz do {teamName} na Documenso"
|
||||||
|
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||||
|
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||||
msgid "Label"
|
msgid "Label"
|
||||||
msgstr "Etykieta"
|
msgstr "Etykieta"
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,11 @@ generator json {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generator zod {
|
generator zod {
|
||||||
provider = "zod-prisma-types"
|
provider = "zod-prisma-types"
|
||||||
createInputTypes = false
|
createInputTypes = false
|
||||||
writeBarrelFiles = false
|
writeBarrelFiles = false
|
||||||
useMultipleFiles = true
|
useMultipleFiles = true
|
||||||
|
useDefaultValidators = false
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Document, DocumentData, Recipient } from '@documenso/prisma/client';
|
import type { Document, DocumentData, Recipient } from '@prisma/client';
|
||||||
|
|
||||||
export type DocumentWithRecipients = Document & {
|
export type DocumentWithRecipients = Document & {
|
||||||
recipients: Recipient[];
|
recipients: Recipient[];
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import type { Field, Signature } from '@prisma/client';
|
||||||
|
|
||||||
import { type TFieldMetaSchema as FieldMeta } from '@documenso/lib/types/field-meta';
|
import { type TFieldMetaSchema as FieldMeta } from '@documenso/lib/types/field-meta';
|
||||||
import type { Field, Signature } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
export type FieldWithSignatureAndFieldMeta = Field & {
|
export type FieldWithSignatureAndFieldMeta = Field & {
|
||||||
signature?: Signature | null;
|
signature?: Signature | null;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Field, Signature } from '@documenso/prisma/client';
|
import type { Field, Signature } from '@prisma/client';
|
||||||
|
|
||||||
export type FieldWithSignature = Field & {
|
export type FieldWithSignature = Field & {
|
||||||
signature?: Signature | null;
|
signature?: Signature | null;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Field, Recipient } from '@documenso/prisma/client';
|
import type { Field, Recipient } from '@prisma/client';
|
||||||
|
|
||||||
export type RecipientWithFields = Recipient & {
|
export type RecipientWithFields = Recipient & {
|
||||||
fields: Field[];
|
fields: Field[];
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { Session } from '@prisma/client';
|
||||||
import type { Context } from 'hono';
|
import type { Context } from 'hono';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@@ -5,7 +6,6 @@ import type { SessionUser } from '@documenso/auth/server/lib/session/session';
|
|||||||
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
|
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
|
||||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import type { Session } from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
type CreateTrpcContextOptions = {
|
type CreateTrpcContextOptions = {
|
||||||
c: Context;
|
c: Context;
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|||||||
import { msg } from '@lingui/core/macro';
|
import { msg } from '@lingui/core/macro';
|
||||||
import { useLingui } from '@lingui/react';
|
import { useLingui } from '@lingui/react';
|
||||||
import { Trans } from '@lingui/react/macro';
|
import { Trans } from '@lingui/react/macro';
|
||||||
import { Prisma } from '@prisma/client';
|
|
||||||
import type { Field, Recipient } from '@prisma/client';
|
import type { Field, Recipient } from '@prisma/client';
|
||||||
import { FieldType, RecipientRole, SendStatus } from '@prisma/client';
|
import { FieldType, Prisma, RecipientRole, SendStatus } from '@prisma/client';
|
||||||
import {
|
import {
|
||||||
CalendarDays,
|
CalendarDays,
|
||||||
Check,
|
Check,
|
||||||
@@ -430,6 +429,7 @@ export const AddFieldsFormPartial = ({
|
|||||||
|
|
||||||
const newField: TAddFieldsFormSchema['fields'][0] = {
|
const newField: TAddFieldsFormSchema['fields'][0] = {
|
||||||
...structuredClone(lastActiveField),
|
...structuredClone(lastActiveField),
|
||||||
|
nativeId: undefined,
|
||||||
formId: nanoid(12),
|
formId: nanoid(12),
|
||||||
signerEmail: selectedSigner?.email ?? lastActiveField.signerEmail,
|
signerEmail: selectedSigner?.email ?? lastActiveField.signerEmail,
|
||||||
pageX: lastActiveField.pageX + 3,
|
pageX: lastActiveField.pageX + 3,
|
||||||
@@ -451,6 +451,7 @@ export const AddFieldsFormPartial = ({
|
|||||||
|
|
||||||
append({
|
append({
|
||||||
...copiedField,
|
...copiedField,
|
||||||
|
nativeId: undefined,
|
||||||
formId: nanoid(12),
|
formId: nanoid(12),
|
||||||
signerEmail: selectedSigner?.email ?? copiedField.signerEmail,
|
signerEmail: selectedSigner?.email ?? copiedField.signerEmail,
|
||||||
pageX: copiedField.pageX + 3,
|
pageX: copiedField.pageX + 3,
|
||||||
@@ -649,6 +650,8 @@ export const AddFieldsFormPartial = ({
|
|||||||
passive={isFieldWithinBounds && !!selectedField}
|
passive={isFieldWithinBounds && !!selectedField}
|
||||||
onFocus={() => setLastActiveField(field)}
|
onFocus={() => setLastActiveField(field)}
|
||||||
onBlur={() => setLastActiveField(null)}
|
onBlur={() => setLastActiveField(null)}
|
||||||
|
onMouseEnter={() => setLastActiveField(field)}
|
||||||
|
onMouseLeave={() => setLastActiveField(null)}
|
||||||
onResize={(options) => onFieldResize(options, index)}
|
onResize={(options) => onFieldResize(options, index)}
|
||||||
onMove={(options) => onFieldMove(options, index)}
|
onMove={(options) => onFieldMove(options, index)}
|
||||||
onRemove={() => remove(index)}
|
onRemove={() => remove(index)}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import { FieldType } from '@prisma/client';
|
||||||
import { CopyPlus, Settings2, Trash } from 'lucide-react';
|
import { CopyPlus, Settings2, Trash } from 'lucide-react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { Rnd } from 'react-rnd';
|
import { Rnd } from 'react-rnd';
|
||||||
@@ -33,6 +34,8 @@ export type FieldItemProps = {
|
|||||||
onAdvancedSettings?: () => void;
|
onAdvancedSettings?: () => void;
|
||||||
onFocus?: () => void;
|
onFocus?: () => void;
|
||||||
onBlur?: () => void;
|
onBlur?: () => void;
|
||||||
|
onMouseEnter?: () => void;
|
||||||
|
onMouseLeave?: () => void;
|
||||||
recipientIndex?: number;
|
recipientIndex?: number;
|
||||||
hideRecipients?: boolean;
|
hideRecipients?: boolean;
|
||||||
hasErrors?: boolean;
|
hasErrors?: boolean;
|
||||||
@@ -174,11 +177,35 @@ export const FieldItem = ({
|
|||||||
() => hasFieldMetaValues('CHECKBOX', field.fieldMeta, ZCheckboxFieldMeta),
|
() => hasFieldMetaValues('CHECKBOX', field.fieldMeta, ZCheckboxFieldMeta),
|
||||||
[field.fieldMeta],
|
[field.fieldMeta],
|
||||||
);
|
);
|
||||||
|
|
||||||
const radioHasValues = useMemo(
|
const radioHasValues = useMemo(
|
||||||
() => hasFieldMetaValues('RADIO', field.fieldMeta, ZRadioFieldMeta),
|
() => hasFieldMetaValues('RADIO', field.fieldMeta, ZRadioFieldMeta),
|
||||||
[field.fieldMeta],
|
[field.fieldMeta],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const hasCheckedValues = (fieldMeta: TFieldMetaSchema, type: FieldType) => {
|
||||||
|
if (!fieldMeta || (type !== FieldType.RADIO && type !== FieldType.CHECKBOX)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === FieldType.RADIO) {
|
||||||
|
const parsed = ZRadioFieldMeta.parse(fieldMeta);
|
||||||
|
return parsed.values?.some((value) => value.checked) ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === FieldType.CHECKBOX) {
|
||||||
|
const parsed = ZCheckboxFieldMeta.parse(fieldMeta);
|
||||||
|
return parsed.values?.some((value) => value.checked) ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const fieldHasCheckedValues = useMemo(
|
||||||
|
() => hasCheckedValues(field.fieldMeta, field.type),
|
||||||
|
[field.fieldMeta, field.type],
|
||||||
|
);
|
||||||
|
|
||||||
const fixedSize = checkBoxHasValues || radioHasValues;
|
const fixedSize = checkBoxHasValues || radioHasValues;
|
||||||
|
|
||||||
return createPortal(
|
return createPortal(
|
||||||
@@ -202,6 +229,8 @@ export const FieldItem = ({
|
|||||||
bounds={`${PDF_VIEWER_PAGE_SELECTOR}[data-page-number="${field.pageNumber}"]`}
|
bounds={`${PDF_VIEWER_PAGE_SELECTOR}[data-page-number="${field.pageNumber}"]`}
|
||||||
onDragStart={() => onFieldActivate?.()}
|
onDragStart={() => onFieldActivate?.()}
|
||||||
onResizeStart={() => onFieldActivate?.()}
|
onResizeStart={() => onFieldActivate?.()}
|
||||||
|
onMouseEnter={() => onFocus?.()}
|
||||||
|
onMouseLeave={() => onBlur?.()}
|
||||||
enableResizing={!fixedSize}
|
enableResizing={!fixedSize}
|
||||||
resizeHandleStyles={{
|
resizeHandleStyles={{
|
||||||
bottom: { bottom: -8, cursor: 'ns-resize' },
|
bottom: { bottom: -8, cursor: 'ns-resize' },
|
||||||
@@ -218,6 +247,21 @@ export const FieldItem = ({
|
|||||||
onMove?.(d.node);
|
onMove?.(d.node);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{(field.type === FieldType.RADIO || field.type === FieldType.CHECKBOX) &&
|
||||||
|
field.fieldMeta?.label && (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'absolute -top-16 left-0 right-0 rounded-md p-2 text-center text-xs text-gray-700',
|
||||||
|
{
|
||||||
|
'bg-foreground/5 border-primary border': !fieldHasCheckedValues,
|
||||||
|
'bg-documenso-200 border-primary border': fieldHasCheckedValues,
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{field.fieldMeta.label}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
'relative flex h-full w-full items-center justify-center bg-white',
|
'relative flex h-full w-full items-center justify-center bg-white',
|
||||||
|
|||||||
@@ -125,6 +125,18 @@ export const CheckboxFieldAdvancedSettings = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
|
<div className="mb-2">
|
||||||
|
<Label>
|
||||||
|
<Trans>Label</Trans>
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
id="label"
|
||||||
|
className="bg-background mt-2"
|
||||||
|
placeholder={_(msg`Field label`)}
|
||||||
|
value={fieldState.label}
|
||||||
|
onChange={(e) => handleFieldChange('label', e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="flex flex-row items-center gap-x-4">
|
<div className="flex flex-row items-center gap-x-4">
|
||||||
<div className="flex w-2/3 flex-col">
|
<div className="flex w-2/3 flex-col">
|
||||||
<Label>
|
<Label>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { msg } from '@lingui/core/macro';
|
||||||
|
import { useLingui } from '@lingui/react';
|
||||||
import { Trans } from '@lingui/react/macro';
|
import { Trans } from '@lingui/react/macro';
|
||||||
import { ChevronDown, ChevronUp, Trash } from 'lucide-react';
|
import { ChevronDown, ChevronUp, Trash } from 'lucide-react';
|
||||||
|
|
||||||
@@ -25,6 +27,8 @@ export const RadioFieldAdvancedSettings = ({
|
|||||||
handleFieldChange,
|
handleFieldChange,
|
||||||
handleErrors,
|
handleErrors,
|
||||||
}: RadioFieldAdvancedSettingsProps) => {
|
}: RadioFieldAdvancedSettingsProps) => {
|
||||||
|
const { _ } = useLingui();
|
||||||
|
|
||||||
const [showValidation, setShowValidation] = useState(false);
|
const [showValidation, setShowValidation] = useState(false);
|
||||||
const [values, setValues] = useState(
|
const [values, setValues] = useState(
|
||||||
fieldState.values ?? [{ id: 1, checked: false, value: 'Default value' }],
|
fieldState.values ?? [{ id: 1, checked: false, value: 'Default value' }],
|
||||||
@@ -100,6 +104,18 @@ export const RadioFieldAdvancedSettings = ({
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
|
<div>
|
||||||
|
<Label>
|
||||||
|
<Trans>Label</Trans>
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
id="label"
|
||||||
|
className="bg-background mt-2"
|
||||||
|
placeholder={_(msg`Field label`)}
|
||||||
|
value={fieldState.label}
|
||||||
|
onChange={(e) => handleFieldChange('label', e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="flex flex-row items-center gap-2">
|
<div className="flex flex-row items-center gap-2">
|
||||||
<Switch
|
<Switch
|
||||||
className="bg-background"
|
className="bg-background"
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ export const AddTemplateFieldsFormPartial = ({
|
|||||||
const newField: TAddTemplateFieldsFormSchema['fields'][0] = {
|
const newField: TAddTemplateFieldsFormSchema['fields'][0] = {
|
||||||
...structuredClone(lastActiveField),
|
...structuredClone(lastActiveField),
|
||||||
formId: nanoid(12),
|
formId: nanoid(12),
|
||||||
|
nativeId: undefined,
|
||||||
signerEmail: selectedSigner?.email ?? lastActiveField.signerEmail,
|
signerEmail: selectedSigner?.email ?? lastActiveField.signerEmail,
|
||||||
signerId: selectedSigner?.id ?? lastActiveField.signerId,
|
signerId: selectedSigner?.id ?? lastActiveField.signerId,
|
||||||
signerToken: selectedSigner?.token ?? lastActiveField.signerToken,
|
signerToken: selectedSigner?.token ?? lastActiveField.signerToken,
|
||||||
@@ -195,6 +196,7 @@ export const AddTemplateFieldsFormPartial = ({
|
|||||||
append({
|
append({
|
||||||
...copiedField,
|
...copiedField,
|
||||||
formId: nanoid(12),
|
formId: nanoid(12),
|
||||||
|
nativeId: undefined,
|
||||||
signerEmail: selectedSigner?.email ?? copiedField.signerEmail,
|
signerEmail: selectedSigner?.email ?? copiedField.signerEmail,
|
||||||
signerId: selectedSigner?.id ?? copiedField.signerId,
|
signerId: selectedSigner?.id ?? copiedField.signerId,
|
||||||
signerToken: selectedSigner?.token ?? copiedField.signerToken,
|
signerToken: selectedSigner?.token ?? copiedField.signerToken,
|
||||||
@@ -483,12 +485,6 @@ export const AddTemplateFieldsFormPartial = ({
|
|||||||
form.setValue('fields', updatedFields);
|
form.setValue('fields', updatedFields);
|
||||||
};
|
};
|
||||||
|
|
||||||
const isTypedSignatureEnabled = form.watch('typedSignatureEnabled');
|
|
||||||
|
|
||||||
const handleTypedSignatureChange = (value: boolean) => {
|
|
||||||
form.setValue('typedSignatureEnabled', value, { shouldDirty: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{showAdvancedSettings && currentField ? (
|
{showAdvancedSettings && currentField ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user