mirror of
https://github.com/documenso/documenso.git
synced 2026-06-30 00:01:09 +10:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ec1741db8e | |||
| 93d868a389 |
+2
-1
@@ -42,8 +42,8 @@ Documenso is an open-source document signing platform built as a **monorepo** us
|
||||
| Package | Description | Port |
|
||||
| -------------------------- | -------------------------------------------------------- | ---- |
|
||||
| `@documenso/remix` | Main application - React Router (Remix) with Hono server | 3000 |
|
||||
| `@documenso/documentation` | Documentation site (Next.js + Nextra) | 3002 |
|
||||
| `@documenso/openpage-api` | Public analytics API | 3003 |
|
||||
| `@documenso/docs` | Documentation site | 3004 |
|
||||
|
||||
### Core Packages (`packages/`)
|
||||
|
||||
@@ -65,6 +65,7 @@ Documenso is an open-source document signing platform built as a **monorepo** us
|
||||
| Package | Description |
|
||||
| ---------------------------- | ------------------------- |
|
||||
| `@documenso/app-tests` | E2E tests (Playwright) |
|
||||
| `@documenso/tailwind-config` | Shared Tailwind config |
|
||||
| `@documenso/tsconfig` | Shared TypeScript configs |
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -6,6 +6,8 @@ description: Create, manage, and send documents for signing via the API.
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
<Callout type="warn">
|
||||
This guide may not reflect the latest endpoints or parameters. For an always up-to-date reference,
|
||||
see the [OpenAPI Reference](https://openapi.documenso.com).
|
||||
|
||||
@@ -5,6 +5,8 @@ description: Complete reference for the Documenso REST API.
|
||||
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
<Callout type="warn">
|
||||
The guides below cover common API patterns but may not reflect the latest endpoints or parameters.
|
||||
For an always up-to-date reference, see the [OpenAPI Reference](https://openapi.documenso.com).
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"teams",
|
||||
"rate-limits",
|
||||
"versioning",
|
||||
"migrate-to-envelopes",
|
||||
"developer-mode",
|
||||
"common-errors"
|
||||
]
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
---
|
||||
title: Migrating to Envelopes
|
||||
description: Why Documenso unified documents and templates into envelopes, and how to migrate from the deprecated document and template create endpoints.
|
||||
---
|
||||
|
||||
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||
|
||||
## Summary
|
||||
|
||||
The following items have been deprecated and will be removed on the <strong>1st of March 2027</strong>:
|
||||
|
||||
- <strong>API V1</strong>
|
||||
- <strong>A subset of SDK/API V2 endpoints</strong>
|
||||
- <strong>Legacy documents and templates</strong>
|
||||
- <strong>EmbedCreateDocumentV1</strong>
|
||||
- <strong>EmbedCreateTemplateV1</strong>
|
||||
- <strong>EmbedUpdateDocumentV1</strong>
|
||||
- <strong>EmbedUpdateTemplateV1</strong>
|
||||
|
||||
The beta endpoint `/api/v2-beta` will also be removed. Use `/api/v2` instead, which is a drop-in replacement.
|
||||
|
||||
Nothing breaks before 1st of March 2027, so you can migrate at your own pace.
|
||||
|
||||
## What are legacy documents and templates
|
||||
|
||||
These are documents and templates created by the following endpoints:
|
||||
|
||||
- `POST /api/v2/document/create`
|
||||
- `POST /api/v2/document/create/beta`
|
||||
- `POST /api/v2/template/create`
|
||||
- `POST /api/v2/template/create/beta`
|
||||
- `POST /api/v1/documents`
|
||||
- `POST /api/v1/templates`
|
||||
- `POST /api/v1/templates/create-document`
|
||||
- `POST /api/v1/templates/generate-document`
|
||||
|
||||
## What replaces legacy documents and templates
|
||||
|
||||
At the end of 2025 we introduced a unified system for documents and templates, called <strong>envelopes</strong>.
|
||||
|
||||
We still reference documents and templates throughout the documentation and application to distinguish them, but internally they are envelopes.
|
||||
|
||||
Moving to the envelope system gives you:
|
||||
|
||||
- **Multiple PDFs in one envelope.** Send several documents to sign in a single request.
|
||||
- **One API for documents and templates.** Learn one set of endpoints instead of two misaligned ones.
|
||||
- **A better editor and signing experience** for you and your recipients.
|
||||
|
||||
## How to migrate
|
||||
|
||||
{/* prettier-ignore */}
|
||||
<Steps>
|
||||
<Step>
|
||||
### Switch to the envelope endpoints
|
||||
|
||||
Replace each deprecated endpoint with its `/api/v2/envelope/*` equivalent from the [mapping tables](#endpoint-mapping-reference) below.
|
||||
</Step>
|
||||
<Step>
|
||||
### Set the envelope `type` on create
|
||||
|
||||
A single endpoint, `POST /api/v2/envelope/create`, can create both documents and templates. Set `type` to `DOCUMENT` or `TEMPLATE`. You can now upload more than one PDF using the `files` field.
|
||||
</Step>
|
||||
<Step>
|
||||
### Update how you store IDs
|
||||
|
||||
Envelope IDs are **strings** (for example `envelope_abc123`), not numbers. Update any code that stores, parses, or compares IDs.
|
||||
</Step>
|
||||
<Step>
|
||||
### Test, then remove the old calls
|
||||
|
||||
Verify the new flow against your account, then delete the deprecated calls.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
The main data differences are as follows:
|
||||
- ID format changed from number to string (e.g. `42` to `envelope_abc123`)
|
||||
- pageNumber becomes page
|
||||
- pageX becomes positionX
|
||||
- pageY becomes positionY
|
||||
|
||||
See the [Documents API](/docs/developers/api/documents) and [Templates API](/docs/developers/api/templates) for the full envelope reference.
|
||||
|
||||
### Deprecated V1 API Endpoints
|
||||
|
||||
Full reference in the [V1 OpenAPI reference](https://openapi-v1.documenso.com).
|
||||
|
||||
| Deprecated endpoint | Replacement |
|
||||
| -------------------------------------------------------- | ----------------------------------------------------- |
|
||||
| `GET /api/v1/documents` | `GET /api/v2/envelope` |
|
||||
| `GET /api/v1/documents/{id}` | `GET /api/v2/envelope/{envelopeId}` |
|
||||
| `POST /api/v1/documents` | `POST /api/v2/envelope/create` |
|
||||
| `POST /api/v1/documents/{id}/send` | `POST /api/v2/envelope/distribute` |
|
||||
| `POST /api/v1/documents/{id}/resend` | `POST /api/v2/envelope/redistribute` |
|
||||
| `DELETE /api/v1/documents/{id}` | `POST /api/v2/envelope/delete` |
|
||||
| `GET /api/v1/documents/{id}/download` | `GET /api/v2/envelope/item/{envelopeItemId}/download` |
|
||||
| `POST /api/v1/documents/{id}/recipients` | `POST /api/v2/envelope/recipient/create-many` |
|
||||
| `PATCH /api/v1/documents/{id}/recipients/{recipientId}` | `POST /api/v2/envelope/recipient/update-many` |
|
||||
| `DELETE /api/v1/documents/{id}/recipients/{recipientId}` | `POST /api/v2/envelope/recipient/delete` |
|
||||
| `POST /api/v1/documents/{id}/fields` | `POST /api/v2/envelope/field/create-many` |
|
||||
| `PATCH /api/v1/documents/{id}/fields/{fieldId}` | `POST /api/v2/envelope/field/update-many` |
|
||||
| `DELETE /api/v1/documents/{id}/fields/{fieldId}` | `POST /api/v2/envelope/field/delete` |
|
||||
| `GET /api/v1/templates` | `GET /api/v2/envelope` (with `type=TEMPLATE`) |
|
||||
| `GET /api/v1/templates/{id}` | `GET /api/v2/envelope/{envelopeId}` |
|
||||
| `POST /api/v1/templates` | `POST /api/v2/envelope/create` (`type=TEMPLATE`) |
|
||||
| `DELETE /api/v1/templates/{id}` | `POST /api/v2/envelope/delete` |
|
||||
| `POST /api/v1/templates/{templateId}/create-document` | `POST /api/v2/envelope/use` |
|
||||
| `POST /api/v1/templates/{templateId}/generate-document` | `POST /api/v2/envelope/use` |
|
||||
|
||||
### Deprecated V2 API Endpoints
|
||||
|
||||
Full reference in the [V2 OpenAPI reference](https://openapi.documenso.com).
|
||||
|
||||
#### Documents
|
||||
|
||||
| Deprecated endpoint | Replacement |
|
||||
| ------------------------------------------------- | ----------------------------------------------------- |
|
||||
| `GET /api/v2/document` | `GET /api/v2/envelope` |
|
||||
| `GET /api/v2/document/{documentId}` | `GET /api/v2/envelope/{envelopeId}` |
|
||||
| `POST /api/v2/document/get-many` | `POST /api/v2/envelope/get-many` |
|
||||
| `POST /api/v2/document/create` | `POST /api/v2/envelope/create` |
|
||||
| `POST /api/v2/document/create/beta` | `POST /api/v2/envelope/create` |
|
||||
| `POST /api/v2/document/update` | `POST /api/v2/envelope/update` |
|
||||
| `POST /api/v2/document/delete` | `POST /api/v2/envelope/delete` |
|
||||
| `POST /api/v2/document/duplicate` | `POST /api/v2/envelope/duplicate` |
|
||||
| `POST /api/v2/document/distribute` | `POST /api/v2/envelope/distribute` |
|
||||
| `POST /api/v2/document/redistribute` | `POST /api/v2/envelope/redistribute` |
|
||||
| `GET /api/v2/document/attachment` | `GET /api/v2/envelope/attachment` |
|
||||
| `POST /api/v2/document/attachment/create` | `POST /api/v2/envelope/attachment/create` |
|
||||
| `POST /api/v2/document/attachment/update` | `POST /api/v2/envelope/attachment/update` |
|
||||
| `POST /api/v2/document/attachment/delete` | `POST /api/v2/envelope/attachment/delete` |
|
||||
| `GET /api/v2/document/{documentId}/download` | `GET /api/v2/envelope/item/{envelopeItemId}/download` |
|
||||
| `GET /api/v2/document/{documentId}/download-beta` | `GET /api/v2/envelope/item/{envelopeItemId}/download` |
|
||||
|
||||
#### Templates
|
||||
|
||||
| Deprecated endpoint | Replacement |
|
||||
| ------------------------------------- | ------------------------------------------------ |
|
||||
| `GET /api/v2/template` | `GET /api/v2/envelope` (with `type=TEMPLATE`) |
|
||||
| `GET /api/v2/template/{templateId}` | `GET /api/v2/envelope/{envelopeId}` |
|
||||
| `POST /api/v2/template/get-many` | `POST /api/v2/envelope/get-many` |
|
||||
| `POST /api/v2/template/create` | `POST /api/v2/envelope/create` (`type=TEMPLATE`) |
|
||||
| `POST /api/v2/template/create/beta` | `POST /api/v2/envelope/create` (`type=TEMPLATE`) |
|
||||
| `POST /api/v2/template/update` | `POST /api/v2/envelope/update` |
|
||||
| `POST /api/v2/template/duplicate` | `POST /api/v2/envelope/duplicate` |
|
||||
| `POST /api/v2/template/delete` | `POST /api/v2/envelope/delete` |
|
||||
| `POST /api/v2/template/use` | `POST /api/v2/envelope/use` |
|
||||
| `POST /api/v2/template/direct/create` | **Pending replacement** |
|
||||
| `POST /api/v2/template/direct/delete` | **Pending replacement** |
|
||||
| `POST /api/v2/template/direct/toggle` | **Pending replacement** |
|
||||
|
||||
#### Document fields
|
||||
|
||||
| Deprecated endpoint | Replacement |
|
||||
| ----------------------------------------- | ----------------------------------------- |
|
||||
| `GET /api/v2/document/field/{fieldId}` | `GET /api/v2/envelope/field/{fieldId}` |
|
||||
| `POST /api/v2/document/field/create` | `POST /api/v2/envelope/field/create-many` |
|
||||
| `POST /api/v2/document/field/create-many` | `POST /api/v2/envelope/field/create-many` |
|
||||
| `POST /api/v2/document/field/update` | `POST /api/v2/envelope/field/update-many` |
|
||||
| `POST /api/v2/document/field/update-many` | `POST /api/v2/envelope/field/update-many` |
|
||||
| `POST /api/v2/document/field/delete` | `POST /api/v2/envelope/field/delete` |
|
||||
|
||||
#### Template fields
|
||||
|
||||
| Deprecated endpoint | Replacement |
|
||||
| ----------------------------------------- | ----------------------------------------- |
|
||||
| `GET /api/v2/template/field/{fieldId}` | `GET /api/v2/envelope/field/{fieldId}` |
|
||||
| `POST /api/v2/template/field/create` | `POST /api/v2/envelope/field/create-many` |
|
||||
| `POST /api/v2/template/field/create-many` | `POST /api/v2/envelope/field/create-many` |
|
||||
| `POST /api/v2/template/field/update` | `POST /api/v2/envelope/field/update-many` |
|
||||
| `POST /api/v2/template/field/update-many` | `POST /api/v2/envelope/field/update-many` |
|
||||
| `POST /api/v2/template/field/delete` | `POST /api/v2/envelope/field/delete` |
|
||||
|
||||
#### Document recipients
|
||||
|
||||
| Deprecated endpoint | Replacement |
|
||||
| ---------------------------------------------- | ---------------------------------------------- |
|
||||
| `GET /api/v2/document/recipient/{recipientId}` | `GET /api/v2/envelope/recipient/{recipientId}` |
|
||||
| `POST /api/v2/document/recipient/create` | `POST /api/v2/envelope/recipient/create-many` |
|
||||
| `POST /api/v2/document/recipient/create-many` | `POST /api/v2/envelope/recipient/create-many` |
|
||||
| `POST /api/v2/document/recipient/update` | `POST /api/v2/envelope/recipient/update-many` |
|
||||
| `POST /api/v2/document/recipient/update-many` | `POST /api/v2/envelope/recipient/update-many` |
|
||||
| `POST /api/v2/document/recipient/delete` | `POST /api/v2/envelope/recipient/delete` |
|
||||
|
||||
#### Template recipients
|
||||
|
||||
| Deprecated endpoint | Replacement |
|
||||
| ---------------------------------------------- | ---------------------------------------------- |
|
||||
| `GET /api/v2/template/recipient/{recipientId}` | `GET /api/v2/envelope/recipient/{recipientId}` |
|
||||
| `POST /api/v2/template/recipient/create` | `POST /api/v2/envelope/recipient/create-many` |
|
||||
| `POST /api/v2/template/recipient/create-many` | `POST /api/v2/envelope/recipient/create-many` |
|
||||
| `POST /api/v2/template/recipient/update` | `POST /api/v2/envelope/recipient/update-many` |
|
||||
| `POST /api/v2/template/recipient/update-many` | `POST /api/v2/envelope/recipient/update-many` |
|
||||
| `POST /api/v2/template/recipient/delete` | `POST /api/v2/envelope/recipient/delete` |
|
||||
|
||||
### Embedding components
|
||||
|
||||
| Deprecated component | Replacement |
|
||||
| ----------------------- | --------------------- |
|
||||
| `EmbedCreateDocumentV1` | `EmbedCreateEnvelope` |
|
||||
| `EmbedCreateTemplateV1` | `EmbedCreateEnvelope` |
|
||||
| `EmbedUpdateDocumentV1` | `EmbedUpdateEnvelope` |
|
||||
| `EmbedUpdateTemplateV1` | `EmbedUpdateEnvelope` |
|
||||
|
||||
See the [embedding guide](/docs/developers/embedding) for the envelope components.
|
||||
|
||||
## FAQ
|
||||
|
||||
<Accordions>
|
||||
<Accordion title="What happens on 1 March 2027?">
|
||||
The deprecated V1 API, the V2 endpoints listed above, and the V1 embedding components are removed.
|
||||
Requests to them will fail, so migrate to the envelope API before that date.
|
||||
</Accordion>
|
||||
<Accordion title="Will my existing documents and templates keep working?">
|
||||
Yes. Documents and templates you already created remain in your account and continue to work. They will automatically be converted to envelopes. Only
|
||||
the deprecated endpoints you call are going away. Your data is not deleted.
|
||||
</Accordion>
|
||||
<Accordion title="Do I need a new API token?">
|
||||
No. Authentication is unchanged. The same API token works for the envelope endpoints under
|
||||
`https://app.documenso.com/api/v2`.
|
||||
</Accordion>
|
||||
<Accordion title="What is the difference between a document and a template now?">
|
||||
Both are envelopes, distinguished by a `type` field of `DOCUMENT` or `TEMPLATE`. They share the same
|
||||
endpoints, recipients, fields, and attachments.
|
||||
</Accordion>
|
||||
<Accordion title="I use an official SDK, what should I do?">
|
||||
The function calls to the legacy endpoints will break on the 1st of March 2027. Update to the latest SDK version and switch to its envelope methods.
|
||||
The deprecated document and template methods map to the envelope endpoints in the tables above.
|
||||
</Accordion>
|
||||
<Accordion title="I need more time or help migrating">
|
||||
Reach out to [support@documenso.com](mailto:support@documenso.com) with your use case and we will
|
||||
help you plan the migration.
|
||||
</Accordion>
|
||||
</Accordions>
|
||||
|
||||
## Getting help
|
||||
|
||||
- [V2 OpenAPI reference](https://openapi.documenso.com): the up-to-date envelope API.
|
||||
- [V1 OpenAPI reference](https://openapi-v1.documenso.com): the deprecated V1 API.
|
||||
- [support@documenso.com](mailto:support@documenso.com): migration questions and extensions.
|
||||
|
||||
## See also
|
||||
|
||||
- [Documents API](/docs/developers/api/documents): create and manage envelopes
|
||||
- [Templates API](/docs/developers/api/templates): work with templates and direct links
|
||||
- [Fields API](/docs/developers/api/fields) and [Recipients API](/docs/developers/api/recipients)
|
||||
- [API Versioning](/docs/developers/api/versioning): how Documenso versions the public API
|
||||
@@ -11,7 +11,7 @@ Documenso enforces rate limits on all API endpoints to ensure service stability.
|
||||
|
||||
## HTTP Rate Limits
|
||||
|
||||
**Limit:** 100 requests per minute per IP address
|
||||
**Limit:** 100 requests per minute per IP address
|
||||
**Response:** 429 Too Many Requests
|
||||
|
||||
### Rate Limit Response
|
||||
|
||||
@@ -6,6 +6,8 @@ description: Create documents from reusable templates via API.
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
<Callout type="warn">
|
||||
This guide may not reflect the latest endpoints or parameters. For an always up-to-date reference,
|
||||
see the [OpenAPI Reference](https://openapi.documenso.com).
|
||||
|
||||
@@ -5,6 +5,8 @@ description: Versioning information for the Documenso public API.
|
||||
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
## Overview
|
||||
|
||||
Documenso uses API versioning to manage changes to the public API. This allows us to introduce new features, fix bugs, and make other changes without breaking existing integrations.
|
||||
@@ -19,7 +21,16 @@ Also, we may deprecate certain features or endpoints in the API. When we depreca
|
||||
|
||||
---
|
||||
|
||||
## Documents, Templates, and Envelopes
|
||||
|
||||
Documenso has unified documents and templates into a single resource called an **envelope**. New integrations should create documents and templates through the `/envelope/*` endpoints. The `POST /document/create` and `POST /template/create` endpoints (including their `/beta` variants) are deprecated in favor of `POST /envelope/create`.
|
||||
|
||||
See [Migrating to the Envelope API](/docs/developers/api/migrate-to-envelopes) for the rationale and step-by-step migration examples.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Migrating to the Envelope API](/docs/developers/api/migrate-to-envelopes) - Move from the document and template create endpoints
|
||||
- [Authentication](/docs/developers/getting-started/authentication) - API authentication guide
|
||||
- [Rate Limits](/docs/developers/api/rate-limits) - API rate limit details
|
||||
|
||||
@@ -8,6 +8,8 @@ import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
## Workflow 1: Send a Document for Signature
|
||||
|
||||
The most common workflow: upload a PDF, add recipients with signature fields, and send for signing.
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Examples
|
||||
description: Common integration patterns and end-to-end workflows.
|
||||
---
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="Common Workflows"
|
||||
|
||||
@@ -7,6 +7,8 @@ import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A Documenso account (cloud or self-hosted)
|
||||
|
||||
@@ -7,6 +7,8 @@ import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting, you need:
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Getting Started
|
||||
description: Get your API key and make your first API call.
|
||||
---
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="Authentication"
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Developer Guide
|
||||
description: Integrate Documenso into your applications using the REST API, webhooks, and embedding options.
|
||||
---
|
||||
|
||||
<EnvelopeWarning />
|
||||
|
||||
## Getting Started
|
||||
|
||||
<Cards>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { createMDX } from 'fumadocs-mdx/next';
|
||||
import type { NextConfig } from 'next';
|
||||
|
||||
const withMDX = createMDX();
|
||||
|
||||
const config: NextConfig = {
|
||||
/** @type {import('next').NextConfig} */
|
||||
const config = {
|
||||
reactStrictMode: true,
|
||||
// biome-ignore lint/suspicious/useAwait: config file
|
||||
async rewrites() {
|
||||
return [
|
||||
{
|
||||
@@ -14,7 +13,6 @@ const config: NextConfig = {
|
||||
},
|
||||
];
|
||||
},
|
||||
// biome-ignore lint/suspicious/useAwait: config file
|
||||
async redirects() {
|
||||
return [
|
||||
// ============================================================
|
||||
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"dev": "next dev",
|
||||
"dev": "next dev --port 3004",
|
||||
"start": "next start",
|
||||
"types:check": "fumadocs-mdx && next typegen && tsc --noEmit",
|
||||
"postinstall": "fumadocs-mdx"
|
||||
@@ -16,7 +16,7 @@
|
||||
"fumadocs-ui": "16.5.0",
|
||||
"lucide-react": "^0.563.0",
|
||||
"mermaid": "^11.12.2",
|
||||
"next": "16.2.9",
|
||||
"next": "16.2.6",
|
||||
"next-plausible": "^3.12.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"react": "^19.2.4",
|
||||
@@ -30,7 +30,7 @@
|
||||
"@types/react": "^19.2.10",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"postcss": "^8.5.14",
|
||||
"tailwindcss": "^4.3.1",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...
|
||||
}}
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img src={logoSrc} alt="Documenso" style={{ height: 28 }} />
|
||||
<img src={logoSrc} alt="Documenso" height="28" />
|
||||
<span
|
||||
style={{
|
||||
color: '#D4D4D8',
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
|
||||
const MIGRATION_GUIDE_HREF = '/docs/developers/api/migrate-to-envelopes';
|
||||
|
||||
/**
|
||||
* Deprecation banner steering API consumers away from the legacy document and
|
||||
* template create endpoints and towards the unified Envelope API.
|
||||
*
|
||||
* Registered globally in `mdx-components.tsx`, so it can be used in any MDX page
|
||||
* as `<EnvelopeWarning />` without an explicit import.
|
||||
*/
|
||||
export function EnvelopeWarning() {
|
||||
return (
|
||||
<Callout type="error">
|
||||
<strong>Documents and templates are being deprecated and replaced by envelopes.</strong>{' '}
|
||||
<a href={MIGRATION_GUIDE_HREF}>Read the migration guide here.</a>
|
||||
</Callout>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as TabsComponents from 'fumadocs-ui/components/tabs';
|
||||
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
||||
import type { MDXComponents } from 'mdx/types';
|
||||
import { EnvelopeWarning } from '@/components/mdx/envelope-warning';
|
||||
import { Mermaid } from '@/components/mdx/mermaid';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -9,6 +10,7 @@ export function getMDXComponents(components?: MDXComponents): any {
|
||||
...defaultMdxComponents,
|
||||
...TabsComponents,
|
||||
Mermaid,
|
||||
EnvelopeWarning,
|
||||
...components,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"dependencies": {
|
||||
"@documenso/prisma": "*",
|
||||
"luxon": "^3.7.2",
|
||||
"next": "16.2.9"
|
||||
"next": "16.2.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
|
||||
+3
-14
@@ -1,15 +1,5 @@
|
||||
@import "@documenso/ui/styles/theme.css";
|
||||
|
||||
/* Content sources: this app plus the shared `ui` and `email` packages it renders. */
|
||||
@source "./**/*.{ts,tsx}";
|
||||
@source "../../../packages/ui/primitives/**/*.{ts,tsx}";
|
||||
@source "../../../packages/ui/components/**/*.{ts,tsx}";
|
||||
@source "../../../packages/ui/icons/**/*.{ts,tsx}";
|
||||
@source "../../../packages/ui/lib/**/*.{ts,tsx}";
|
||||
@source "../../../packages/email/templates/**/*.{ts,tsx}";
|
||||
@source "../../../packages/email/template-components/**/*.{ts,tsx}";
|
||||
@source "../../../packages/email/providers/**/*.{ts,tsx}";
|
||||
|
||||
/* Inter Variable Fonts */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
@@ -74,9 +64,8 @@
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
/* Consumed by the `--font-*` theme tokens in @documenso/ui/styles/theme.css. */
|
||||
--font-family-sans: "Inter";
|
||||
--font-family-signature: "Caveat";
|
||||
--font-family-noto: "Noto Sans", "Noto Sans Korean", "Noto Sans Japanese", "Noto Sans Chinese";
|
||||
--font-sans: "Inter";
|
||||
--font-signature: "Caveat";
|
||||
--font-noto: "Noto Sans", "Noto Sans Korean", "Noto Sans Japanese", "Noto Sans Chinese";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ export const AccountDeleteDialog = ({ className }: AccountDeleteDialogProps) =>
|
||||
</AlertDescription>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0">
|
||||
<div className="flex-shrink-0">
|
||||
<Dialog onOpenChange={() => setEnteredEmail('')}>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="destructive">
|
||||
@@ -82,7 +82,7 @@ export const AccountDeleteDialog = ({ className }: AccountDeleteDialogProps) =>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader className="twv3-space-y-4">
|
||||
<DialogHeader className="space-y-4">
|
||||
<DialogTitle>
|
||||
<Trans>Delete Account</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
@@ -71,7 +71,7 @@ export const AdminDocumentDeleteDialog = ({ envelopeId }: AdminDocumentDeleteDia
|
||||
</AlertDescription>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0">
|
||||
<div className="flex-shrink-0">
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="destructive">
|
||||
@@ -80,7 +80,7 @@ export const AdminDocumentDeleteDialog = ({ envelopeId }: AdminDocumentDeleteDia
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader className="twv3-space-y-4">
|
||||
<DialogHeader className="space-y-4">
|
||||
<DialogTitle>
|
||||
<Trans>Delete Document</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
@@ -90,7 +90,7 @@ export const AdminOrganisationCreateDialog = ({ trigger, ownerUserId, ...props }
|
||||
<Dialog {...props} open={open} onOpenChange={(value) => !form.formState.isSubmitting && setOpen(value)}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0" variant="secondary">
|
||||
<Button className="flex-shrink-0" variant="secondary">
|
||||
<Trans>Create organisation</Trans>
|
||||
</Button>
|
||||
)}
|
||||
@@ -109,7 +109,7 @@ export const AdminOrganisationCreateDialog = ({ trigger, ownerUserId, ...props }
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
|
||||
@@ -128,7 +128,7 @@ export const AdminOrganisationDeleteDialog = ({
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="organisationName"
|
||||
@@ -151,7 +151,7 @@ export const AdminOrganisationDeleteDialog = ({
|
||||
control={form.control}
|
||||
name="sendEmailToOwner"
|
||||
render={({ field }) => (
|
||||
<FormItem className="twv3-space-x-3 twv3-space-y-0 flex flex-row items-start">
|
||||
<FormItem className="flex flex-row items-start space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
id="admin-delete-organisation-send-email"
|
||||
|
||||
@@ -76,7 +76,7 @@ export const AdminOrganisationMemberDeleteDialog = ({
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader className="twv3-space-y-4">
|
||||
<DialogHeader className="space-y-4">
|
||||
<DialogTitle>
|
||||
<Trans>Remove Organisation Member</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
@@ -110,12 +110,12 @@ export const AdminOrganisationSyncSubscriptionDialog = ({
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="syncClaims"
|
||||
render={({ field }) => (
|
||||
<FormItem className="twv3-space-x-3 twv3-space-y-0 flex flex-row items-center">
|
||||
<FormItem className="flex flex-row items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
id="admin-sync-subscription-sync-claims"
|
||||
|
||||
@@ -128,7 +128,7 @@ export const AdminSwapSubscriptionDialog = ({
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<fieldset className="twv3-space-y-4 flex flex-col" disabled={isSubmitting}>
|
||||
<fieldset className="flex flex-col space-y-4" disabled={isSubmitting}>
|
||||
<div className="flex flex-col gap-2">
|
||||
<label className="font-medium text-sm">
|
||||
<Trans>Target Organisation</Trans>
|
||||
|
||||
@@ -76,7 +76,7 @@ export const AdminTeamMemberDeleteDialog = ({
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader className="twv3-space-y-4">
|
||||
<DialogHeader className="space-y-4">
|
||||
<DialogTitle>
|
||||
<Trans>Remove Team Member</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
@@ -82,7 +82,7 @@ export const AdminUserCreateDialog = ({ trigger, ...props }: AdminUserCreateDial
|
||||
<Dialog {...props} open={open} onOpenChange={(value) => !form.formState.isSubmitting && setOpen(value)}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0" variant="secondary">
|
||||
<Button className="flex-shrink-0" variant="secondary">
|
||||
<Trans>Create User</Trans>
|
||||
</Button>
|
||||
)}
|
||||
@@ -101,7 +101,7 @@ export const AdminUserCreateDialog = ({ trigger, ...props }: AdminUserCreateDial
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
|
||||
@@ -77,7 +77,7 @@ export const AdminUserDeleteDialog = ({ className, user }: AdminUserDeleteDialog
|
||||
</AlertDescription>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0">
|
||||
<div className="flex-shrink-0">
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="destructive">
|
||||
@@ -86,7 +86,7 @@ export const AdminUserDeleteDialog = ({ className, user }: AdminUserDeleteDialog
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader className="twv3-space-y-4">
|
||||
<DialogHeader className="space-y-4">
|
||||
<DialogTitle>
|
||||
<Trans>Delete Account</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
@@ -74,7 +74,7 @@ export const AdminUserDisableDialog = ({ className, userToDisable }: AdminUserDi
|
||||
</AlertDescription>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0">
|
||||
<div className="flex-shrink-0">
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="destructive">
|
||||
@@ -83,7 +83,7 @@ export const AdminUserDisableDialog = ({ className, userToDisable }: AdminUserDi
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader className="twv3-space-y-4">
|
||||
<DialogHeader className="space-y-4">
|
||||
<DialogTitle>
|
||||
<Trans>Disable Account</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
@@ -74,7 +74,7 @@ export const AdminUserEnableDialog = ({ className, userToEnable }: AdminUserEnab
|
||||
</AlertDescription>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0">
|
||||
<div className="flex-shrink-0">
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button>
|
||||
@@ -83,7 +83,7 @@ export const AdminUserEnableDialog = ({ className, userToEnable }: AdminUserEnab
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader className="twv3-space-y-4">
|
||||
<DialogHeader className="space-y-4">
|
||||
<DialogTitle>
|
||||
<Trans>Enable Account</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
@@ -90,7 +90,7 @@ export const AdminUserResetTwoFactorDialog = ({ className, user }: AdminUserRese
|
||||
</AlertDescription>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0">
|
||||
<div className="flex-shrink-0">
|
||||
<Dialog open={open} onOpenChange={handleOpenChange}>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="destructive">
|
||||
@@ -99,7 +99,7 @@ export const AdminUserResetTwoFactorDialog = ({ className, user }: AdminUserRese
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader className="twv3-space-y-4">
|
||||
<DialogHeader className="space-y-4">
|
||||
<DialogTitle>
|
||||
<Trans>Reset Two Factor Authentication</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
@@ -71,7 +71,7 @@ export const AiFeaturesEnableDialog = ({ open, onOpenChange, onEnabled }: AiFeat
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="twv3-space-y-4">
|
||||
<div className="space-y-4">
|
||||
<p className="text-muted-foreground text-sm">
|
||||
<Trans>
|
||||
Turn on AI detection to automatically find recipients and fields in your documents. AI providers do not
|
||||
|
||||
@@ -158,7 +158,7 @@ export const AiFieldDetectionDialog = ({
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="twv3-space-y-4">
|
||||
<div className="space-y-4">
|
||||
<p className="text-muted-foreground text-sm">
|
||||
<Trans>
|
||||
We'll scan your document to find form fields like signature lines, text inputs, checkboxes, and more.
|
||||
@@ -166,14 +166,14 @@ export const AiFieldDetectionDialog = ({
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<Alert className="twv3-space-y-0 flex items-center gap-2" variant="neutral">
|
||||
<Alert className="flex items-center gap-2 space-y-0" variant="neutral">
|
||||
<ShieldCheckIcon className="h-5 w-5 stroke-green-600" />
|
||||
<AlertDescription className="mt-0">
|
||||
<Trans>Your document is processed securely using AI services that don't retain your data.</Trans>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
<div className="twv3-space-y-1.5">
|
||||
<div className="space-y-1.5">
|
||||
<Label htmlFor="context">
|
||||
<Trans>Context</Trans>
|
||||
</Label>
|
||||
|
||||
@@ -145,7 +145,7 @@ export const AiRecipientDetectionDialog = ({
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<Alert className="twv3-space-y-0 mt-4 flex items-center gap-2" variant="neutral">
|
||||
<Alert className="mt-4 flex items-center gap-2 space-y-0" variant="neutral">
|
||||
<ShieldCheckIcon className="h-5 w-5 stroke-green-600" />
|
||||
<AlertDescription className="mt-0">
|
||||
<Trans>Your document is processed securely using AI services that don't retain your data.</Trans>
|
||||
|
||||
@@ -50,7 +50,7 @@ export const ClaimCreateDialog = ({ licenseFlags }: ClaimCreateDialogProps) => {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
|
||||
<Button className="shrink-0" variant="secondary">
|
||||
<Button className="flex-shrink-0" variant="secondary">
|
||||
<Trans>Create claim</Trans>
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
@@ -75,7 +75,7 @@ export const ClaimUpdateDialog = ({ claim, trigger, licenseFlags }: ClaimUpdateD
|
||||
licenseFlags={licenseFlags}
|
||||
formSubmitTrigger={
|
||||
<>
|
||||
<div className="twv3-space-x-2 flex items-center">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="backport-email-transport"
|
||||
checked={backportEmailTransport}
|
||||
|
||||
@@ -59,7 +59,7 @@ export const EmailTransportCreateDialog = ({ trigger }: EmailTransportCreateDial
|
||||
<Dialog open={open} onOpenChange={(value) => !isPending && setOpen(value)}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0">
|
||||
<Button className="flex-shrink-0">
|
||||
<Trans>Add transport</Trans>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -86,7 +86,7 @@ export const EmailTransportSendTestDialog = ({ transportId, trigger }: EmailTran
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset disabled={form.formState.isSubmitting} className="twv3-space-y-4">
|
||||
<fieldset disabled={form.formState.isSubmitting} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="to"
|
||||
|
||||
@@ -264,7 +264,7 @@ export const EnvelopeDistributeDialog = ({
|
||||
<fieldset disabled={isSubmitting}>
|
||||
{hasOverlappingEnvelopeFields && (
|
||||
<Alert variant="warning" className="mb-4 flex flex-row items-start gap-3">
|
||||
<AlertTriangleIcon className="mt-0.5 h-5 w-5 shrink-0" />
|
||||
<AlertTriangleIcon className="mt-0.5 h-5 w-5 flex-shrink-0" />
|
||||
|
||||
<div className="flex flex-col gap-1">
|
||||
<AlertTitle>
|
||||
|
||||
@@ -163,14 +163,14 @@ export const EnvelopeDownloadDialog = ({
|
||||
{isLoadingEnvelopeItems
|
||||
? Array.from({ length: 1 }).map((_, index) => (
|
||||
<div key={index} className="flex items-center gap-2 rounded-lg border border-border bg-card p-4">
|
||||
<Skeleton className="h-10 w-10 shrink-0 rounded-lg" />
|
||||
<Skeleton className="h-10 w-10 flex-shrink-0 rounded-lg" />
|
||||
|
||||
<div className="flex w-full flex-col gap-2">
|
||||
<Skeleton className="h-4 w-28 rounded-lg" />
|
||||
<Skeleton className="h-4 w-20 rounded-lg" />
|
||||
</div>
|
||||
|
||||
<Skeleton className="h-10 w-20 shrink-0 rounded-lg" />
|
||||
<Skeleton className="h-10 w-20 flex-shrink-0 rounded-lg" />
|
||||
</div>
|
||||
))
|
||||
: envelopeItems.map((item) => (
|
||||
@@ -178,7 +178,7 @@ export const EnvelopeDownloadDialog = ({
|
||||
key={item.id}
|
||||
className="flex items-center gap-4 rounded-lg border border-border bg-card p-4 transition-colors hover:bg-accent/50"
|
||||
>
|
||||
<div className="shrink-0">
|
||||
<div className="flex-shrink-0">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10">
|
||||
<FileTextIcon className="h-5 w-5 text-primary" />
|
||||
</div>
|
||||
@@ -194,7 +194,7 @@ export const EnvelopeDownloadDialog = ({
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center gap-2">
|
||||
<div className="flex flex-shrink-0 items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
|
||||
@@ -118,12 +118,12 @@ export const EnvelopeDuplicateDialog = ({ envelopeId, envelopeType, trigger }: E
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="twv3-space-y-4">
|
||||
<div className="space-y-4">
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="includeRecipients"
|
||||
render={({ field }) => (
|
||||
<div className="twv3-space-x-2 flex items-center">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="envelopeDuplicateIncludeRecipients"
|
||||
checked={field.value}
|
||||
@@ -146,7 +146,7 @@ export const EnvelopeDuplicateDialog = ({ envelopeId, envelopeType, trigger }: E
|
||||
control={form.control}
|
||||
name="includeFields"
|
||||
render={({ field }) => (
|
||||
<div className="twv3-space-x-2 flex items-center">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="envelopeDuplicateIncludeFields"
|
||||
checked={field.value}
|
||||
|
||||
@@ -225,7 +225,7 @@ export const EnvelopeItemEditDialog = ({
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<fieldset disabled={form.formState.isSubmitting} className="twv3-space-y-4">
|
||||
<fieldset disabled={form.formState.isSubmitting} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="title"
|
||||
@@ -253,13 +253,13 @@ export const EnvelopeItemEditDialog = ({
|
||||
</FormLabel>
|
||||
|
||||
{replacementFile ? (
|
||||
<div className="twv3-space-y-2 mt-1.5">
|
||||
<div className="mt-1.5 space-y-2">
|
||||
<div
|
||||
data-testid="envelope-item-edit-selected-file"
|
||||
className="flex items-center justify-between rounded-md border border-border bg-muted/50 px-3 py-2"
|
||||
>
|
||||
<div className="twv3-space-x-2 flex min-w-0 items-center">
|
||||
<FileIcon className="h-4 w-4 shrink-0 text-muted-foreground" />
|
||||
<div className="flex min-w-0 items-center space-x-2">
|
||||
<FileIcon className="h-4 w-4 flex-shrink-0 text-muted-foreground" />
|
||||
<div className="min-w-0">
|
||||
<p className="truncate font-medium text-sm">{replacementFile.file.name}</p>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
@@ -309,7 +309,7 @@ export const EnvelopeItemEditDialog = ({
|
||||
)}
|
||||
>
|
||||
<input {...getInputProps()} />
|
||||
<div className="twv3-space-x-2 flex items-center text-muted-foreground text-sm">
|
||||
<div className="flex items-center space-x-2 text-muted-foreground text-sm">
|
||||
<UploadIcon className="h-4 w-4" />
|
||||
<span>
|
||||
<Trans>Drop PDF here or click to select</Trans>
|
||||
|
||||
@@ -116,12 +116,12 @@ export const EnvelopeSaveAsTemplateDialog = ({
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="twv3-space-y-4">
|
||||
<div className="space-y-4">
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="includeRecipients"
|
||||
render={({ field }) => (
|
||||
<div className="twv3-space-x-2 flex items-center">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="envelopeIncludeRecipients"
|
||||
checked={field.value}
|
||||
@@ -144,7 +144,7 @@ export const EnvelopeSaveAsTemplateDialog = ({
|
||||
control={form.control}
|
||||
name="includeFields"
|
||||
render={({ field }) => (
|
||||
<div className="twv3-space-x-2 flex items-center">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="envelopeIncludeFields"
|
||||
checked={field.value}
|
||||
|
||||
@@ -173,7 +173,7 @@ export const EnvelopesBulkMoveDialog = ({
|
||||
</FormLabel>
|
||||
|
||||
<FormControl>
|
||||
<div className="twv3-space-y-2 max-h-96 overflow-y-auto">
|
||||
<div className="max-h-96 space-y-2 overflow-y-auto">
|
||||
{isFoldersLoading ? (
|
||||
<div className="flex h-10 items-center justify-center">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
|
||||
@@ -103,7 +103,7 @@ export const FolderCreateDialog = ({ type, trigger, parentFolderId, ...props }:
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<fieldset disabled={form.formState.isSubmitting} className="twv3-space-y-4">
|
||||
<fieldset disabled={form.formState.isSubmitting} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
|
||||
@@ -113,7 +113,7 @@ export const FolderDeleteDialog = ({ folder, isOpen, onOpenChange }: FolderDelet
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset disabled={form.formState.isSubmitting} className="twv3-space-y-4">
|
||||
<fieldset disabled={form.formState.isSubmitting} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="confirmText"
|
||||
|
||||
@@ -126,14 +126,14 @@ export const FolderMoveDialog = ({ foldersData, folder, isOpen, onOpenChange }:
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset disabled={form.formState.isSubmitting} className="twv3-space-y-4">
|
||||
<fieldset disabled={form.formState.isSubmitting} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="targetFolderId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<div className="twv3-space-y-2 max-h-96 overflow-y-auto">
|
||||
<div className="max-h-96 space-y-2 overflow-y-auto">
|
||||
<Button
|
||||
type="button"
|
||||
variant={!field.value ? 'default' : 'outline'}
|
||||
|
||||
@@ -105,7 +105,7 @@ export const FolderUpdateDialog = ({ folder, isOpen, onOpenChange }: FolderUpdat
|
||||
</DialogHeader>
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)} className="twv3-space-y-4">
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
|
||||
@@ -136,7 +136,7 @@ export const OrganisationCreateDialog = ({ trigger, ...props }: OrganisationCrea
|
||||
<Dialog {...props} open={open} onOpenChange={(value) => !form.formState.isSubmitting && setOpen(value)}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0" variant="secondary">
|
||||
<Button className="flex-shrink-0" variant="secondary">
|
||||
<Trans>Create organisation</Trans>
|
||||
</Button>
|
||||
)}
|
||||
@@ -199,7 +199,7 @@ export const OrganisationCreateDialog = ({ trigger, ...props }: OrganisationCrea
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
@@ -305,7 +305,7 @@ const BillingPlanForm = ({ value, onChange, plans, canCreateFreeOrganisation }:
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="twv3-space-y-4">
|
||||
<div className="space-y-4">
|
||||
<Tabs
|
||||
className="flex w-full items-center justify-center"
|
||||
defaultValue="monthlyPrice"
|
||||
@@ -327,7 +327,7 @@ const BillingPlanForm = ({ value, onChange, plans, canCreateFreeOrganisation }:
|
||||
<button
|
||||
onClick={() => onChange('')}
|
||||
className={cn(
|
||||
'twv3-space-x-2 flex cursor-pointer items-center rounded-md border p-4 transition-all hover:border-primary hover:shadow-xs',
|
||||
'flex cursor-pointer items-center space-x-2 rounded-md border p-4 transition-all hover:border-primary hover:shadow-sm',
|
||||
{
|
||||
'border-primary ring-2 ring-primary/10 ring-offset-1': '' === value,
|
||||
},
|
||||
@@ -360,7 +360,7 @@ const BillingPlanForm = ({ value, onChange, plans, canCreateFreeOrganisation }:
|
||||
key={plan[billingPeriod]?.id}
|
||||
onClick={() => onChange(plan[billingPeriod]?.id ?? '')}
|
||||
className={cn(
|
||||
'twv3-space-x-2 flex cursor-pointer items-center rounded-md border p-4 transition-all hover:border-primary hover:shadow-xs',
|
||||
'flex cursor-pointer items-center space-x-2 rounded-md border p-4 transition-all hover:border-primary hover:shadow-sm',
|
||||
{
|
||||
'border-primary ring-2 ring-primary/10 ring-offset-1': plan[billingPeriod]?.id === value,
|
||||
},
|
||||
@@ -382,7 +382,7 @@ const BillingPlanForm = ({ value, onChange, plans, canCreateFreeOrganisation }:
|
||||
<Link
|
||||
to="https://documen.so/enterprise-cta"
|
||||
target="_blank"
|
||||
className="twv3-space-x-2 flex items-center rounded-md border bg-muted/30 p-4"
|
||||
className="flex items-center space-x-2 rounded-md border bg-muted/30 p-4"
|
||||
>
|
||||
<div className="flex-1 font-normal">
|
||||
<p className="font-medium text-muted-foreground">
|
||||
|
||||
@@ -117,7 +117,7 @@ export const OrganisationDeleteDialog = ({ trigger }: OrganisationDeleteDialogPr
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="organisationName"
|
||||
|
||||
@@ -114,7 +114,7 @@ export const OrganisationEmailCreateDialog = ({
|
||||
<Dialog {...props} open={open} onOpenChange={(value) => !isPending && setOpen(value)}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0" variant="secondary">
|
||||
<Button className="flex-shrink-0" variant="secondary">
|
||||
<Trans>Add Email</Trans>
|
||||
</Button>
|
||||
)}
|
||||
@@ -135,7 +135,7 @@ export const OrganisationEmailCreateDialog = ({
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={isPending}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={isPending}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="emailName"
|
||||
|
||||
@@ -113,7 +113,7 @@ export const OrganisationEmailDomainCreateDialog = ({ trigger, ...props }: Organ
|
||||
<Dialog {...props} open={open} onOpenChange={(value) => !form.formState.isSubmitting && setOpen(value)}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0" variant="secondary">
|
||||
<Button className="flex-shrink-0" variant="secondary">
|
||||
<Trans>Add Email Domain</Trans>
|
||||
</Button>
|
||||
)}
|
||||
@@ -135,7 +135,7 @@ export const OrganisationEmailDomainCreateDialog = ({ trigger, ...props }: Organ
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="domain"
|
||||
|
||||
@@ -106,7 +106,7 @@ export const OrganisationEmailDomainDeleteDialog = ({
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset disabled={form.formState.isSubmitting} className="twv3-space-y-4">
|
||||
<fieldset disabled={form.formState.isSubmitting} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="confirmText"
|
||||
|
||||
@@ -59,11 +59,11 @@ export const OrganisationEmailDomainRecordContent = ({ records }: { records: Dom
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="twv3-space-y-6">
|
||||
<div className="twv3-space-y-4">
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-4">
|
||||
{records.map((record) => (
|
||||
<div className="twv3-space-y-4 rounded-md border p-4" key={record.name}>
|
||||
<div className="twv3-space-y-2">
|
||||
<div className="space-y-4 rounded-md border p-4" key={record.name}>
|
||||
<div className="space-y-2">
|
||||
<Label>
|
||||
<Trans>Record Type</Trans>
|
||||
</Label>
|
||||
@@ -79,7 +79,7 @@ export const OrganisationEmailDomainRecordContent = ({ records }: { records: Dom
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="twv3-space-y-2">
|
||||
<div className="space-y-2">
|
||||
<Label>
|
||||
<Trans>Record Name</Trans>
|
||||
</Label>
|
||||
@@ -95,7 +95,7 @@ export const OrganisationEmailDomainRecordContent = ({ records }: { records: Dom
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="twv3-space-y-2">
|
||||
<div className="space-y-2">
|
||||
<Label>
|
||||
<Trans>Record Value</Trans>
|
||||
</Label>
|
||||
|
||||
@@ -115,7 +115,7 @@ export const OrganisationEmailUpdateDialog = ({
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={isPending}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={isPending}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="emailName"
|
||||
|
||||
@@ -108,7 +108,7 @@ export const OrganisationGroupCreateDialog = ({ trigger, ...props }: Organisatio
|
||||
<Dialog {...props} open={open} onOpenChange={(value) => !form.formState.isSubmitting && setOpen(value)}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0" variant="secondary">
|
||||
<Button className="flex-shrink-0" variant="secondary">
|
||||
<Trans>Create group</Trans>
|
||||
</Button>
|
||||
)}
|
||||
@@ -127,7 +127,7 @@ export const OrganisationGroupCreateDialog = ({ trigger, ...props }: Organisatio
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
|
||||
@@ -313,10 +313,10 @@ export const OrganisationMemberInviteDialog = ({ trigger, ...props }: Organisati
|
||||
<TabsContent value="INDIVIDUAL">
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<div className="custom-scrollbar twv3-space-y-4 -m-1 max-h-[60vh] overflow-y-auto p-1">
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<div className="custom-scrollbar -m-1 max-h-[60vh] space-y-4 overflow-y-auto p-1">
|
||||
{organisationMemberInvites.map((organisationMemberInvite, index) => (
|
||||
<div className="twv3-space-x-4 flex w-full flex-row" key={organisationMemberInvite.id}>
|
||||
<div className="flex w-full flex-row space-x-4" key={organisationMemberInvite.id}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`invitations.${index}.email`}
|
||||
@@ -409,7 +409,7 @@ export const OrganisationMemberInviteDialog = ({ trigger, ...props }: Organisati
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="BULK">
|
||||
<div className="twv3-space-y-4 mt-4">
|
||||
<div className="mt-4 space-y-4">
|
||||
<Card gradient className="h-32">
|
||||
<CardContent
|
||||
className="flex h-full cursor-pointer flex-col items-center justify-center rounded-lg p-0 text-muted-foreground/80 transition-colors hover:text-muted-foreground/90"
|
||||
|
||||
@@ -147,7 +147,7 @@ export const PasskeyCreateDialog = ({ trigger, onSuccess, ...props }: PasskeyCre
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="passkeyName"
|
||||
|
||||
@@ -214,7 +214,7 @@ export const ManagePublicTemplateDialog = ({
|
||||
|
||||
return (
|
||||
<Dialog {...props} open={isOpen || open} onOpenChange={handleOnOpenChange}>
|
||||
<fieldset disabled={isLoading} className="relative shrink-0">
|
||||
<fieldset disabled={isLoading} className="relative flex-shrink-0">
|
||||
<DialogTrigger asChild>{trigger}</DialogTrigger>
|
||||
|
||||
<AnimateGenericFadeInOut motionKey={currentStep}>
|
||||
@@ -311,7 +311,7 @@ export const ManagePublicTemplateDialog = ({
|
||||
</DialogHeader>
|
||||
|
||||
<Form {...form}>
|
||||
<form className="twv3-space-y-4 flex h-full flex-col" onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<form className="flex h-full flex-col space-y-4" onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="publicTitle"
|
||||
|
||||
@@ -102,8 +102,8 @@ export const SignFieldCheckboxDialog = createCallable<SignFieldCheckboxDialogPro
|
||||
call.end(data.values.map((value, i) => (value.checked ? i : null)).filter((value) => value !== null)),
|
||||
)}
|
||||
>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<ul className="twv3-space-y-3">
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<ul className="space-y-3">
|
||||
{(formValues.values || []).map((value, index) => (
|
||||
<li key={`checkbox-${index}`}>
|
||||
<FormField
|
||||
|
||||
@@ -51,7 +51,7 @@ export const SignFieldEmailDialog = createCallable<SignFieldEmailDialogProps, st
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit((data) => call.end(data.email))}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
|
||||
@@ -49,7 +49,7 @@ export const SignFieldInitialsDialog = createCallable<SignFieldInitialsDialogPro
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit((data) => call.end(data.initials))}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="initials"
|
||||
|
||||
@@ -49,7 +49,7 @@ export const SignFieldNameDialog = createCallable<SignFieldNameDialogProps, stri
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit((data) => call.end(data.name))}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
|
||||
@@ -107,7 +107,7 @@ export const SignFieldNumberDialog = createCallable<SignFieldNumberDialogProps,
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit((data) => call.end(data.number))}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="number"
|
||||
|
||||
@@ -51,7 +51,7 @@ export const SignFieldTextDialog = createCallable<SignFieldTextDialogProps, stri
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit((data) => call.end(data.text))}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="text"
|
||||
|
||||
@@ -154,7 +154,7 @@ export const TeamCreateDialog = ({ trigger, onCreated, ...props }: TeamCreateDia
|
||||
<Dialog {...props} open={open} onOpenChange={(value) => !form.formState.isSubmitting && setOpen(value)}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0" variant="secondary">
|
||||
<Button className="flex-shrink-0" variant="secondary">
|
||||
<Trans>Create team</Trans>
|
||||
</Button>
|
||||
)}
|
||||
@@ -195,7 +195,7 @@ export const TeamCreateDialog = ({ trigger, onCreated, ...props }: TeamCreateDia
|
||||
{dialogState === 'form' && (
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="teamName"
|
||||
@@ -256,7 +256,7 @@ export const TeamCreateDialog = ({ trigger, onCreated, ...props }: TeamCreateDia
|
||||
control={form.control}
|
||||
name="inheritMembers"
|
||||
render={({ field }) => (
|
||||
<FormItem className="twv3-space-x-2 flex items-center">
|
||||
<FormItem className="flex items-center space-x-2">
|
||||
<FormControl>
|
||||
<div className="flex items-center">
|
||||
<Checkbox id="inherit-members" checked={field.value} onCheckedChange={field.onChange} />
|
||||
|
||||
@@ -142,7 +142,7 @@ export const TeamDeleteDialog = ({ trigger, teamId, teamName, redirectTo }: Team
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="teamName"
|
||||
|
||||
@@ -119,7 +119,7 @@ export const TeamEmailAddDialog = ({ teamId, trigger, ...props }: TeamEmailAddDi
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
|
||||
@@ -104,7 +104,7 @@ export const TeamEmailUpdateDialog = ({ teamEmail, trigger, ...props }: TeamEmai
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onFormSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
|
||||
@@ -202,10 +202,10 @@ export const TeamGroupCreateDialog = ({ ...props }: TeamGroupCreateDialogProps)
|
||||
|
||||
{step === 'ROLES' && (
|
||||
<>
|
||||
<div className="custom-scrollbar twv3-space-y-4 -m-1 max-h-[60vh] overflow-y-auto p-1">
|
||||
<div className="custom-scrollbar -m-1 max-h-[60vh] space-y-4 overflow-y-auto p-1">
|
||||
{form.getValues('groups').map((group, index) => (
|
||||
<div className="twv3-space-x-4 flex w-full flex-row" key={index}>
|
||||
<div className="twv3-space-y-2 w-full">
|
||||
<div className="flex w-full flex-row space-x-4" key={index}>
|
||||
<div className="w-full space-y-2">
|
||||
{index === 0 && (
|
||||
<FormLabel>
|
||||
<Trans>Group</Trans>
|
||||
|
||||
@@ -241,7 +241,7 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi
|
||||
control={form.control}
|
||||
name="members"
|
||||
render={({ field }) => (
|
||||
<FormItem className="twv3-space-y-2">
|
||||
<FormItem className="space-y-2">
|
||||
<FormLabel>
|
||||
<Trans>Members</Trans>
|
||||
</FormLabel>
|
||||
@@ -310,7 +310,7 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi
|
||||
</FormDescription>
|
||||
|
||||
{canInviteOrganisationMembers && (
|
||||
<Alert variant="neutral" className="twv3-space-y-0 mt-2 flex items-center gap-2">
|
||||
<Alert variant="neutral" className="mt-2 flex items-center gap-2 space-y-0">
|
||||
<div>
|
||||
<UserPlusIcon className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
@@ -358,10 +358,10 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi
|
||||
|
||||
{step === 'MEMBERS' && (
|
||||
<>
|
||||
<div className="custom-scrollbar twv3-space-y-4 -m-1 max-h-[60vh] overflow-y-auto p-1">
|
||||
<div className="custom-scrollbar -m-1 max-h-[60vh] space-y-4 overflow-y-auto p-1">
|
||||
{form.getValues('members').map((member, index) => (
|
||||
<div className="twv3-space-x-4 flex w-full flex-row" key={index}>
|
||||
<div className="twv3-space-y-2 w-full">
|
||||
<div className="flex w-full flex-row space-x-4" key={index}>
|
||||
<div className="w-full space-y-2">
|
||||
{index === 0 && (
|
||||
<FormLabel>
|
||||
<Trans>Member</Trans>
|
||||
|
||||
@@ -222,7 +222,7 @@ export const TemplateBulkSendDialog = ({ templateId, recipients, trigger, onSucc
|
||||
control={form.control}
|
||||
name="sendImmediately"
|
||||
render={({ field }) => (
|
||||
<FormItem className="twv3-space-x-2 flex items-center">
|
||||
<FormItem className="flex items-center space-x-2">
|
||||
<FormControl>
|
||||
<div className="flex items-center">
|
||||
<Checkbox id="send-immediately" checked={field.value} onCheckedChange={field.onChange} />
|
||||
|
||||
@@ -211,7 +211,7 @@ export const TemplateDirectLinkDialog = ({
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<ul className="twv3-space-y-4 mt-4 pl-12">
|
||||
<ul className="mt-4 space-y-4 pl-12">
|
||||
{DIRECT_TEMPLATE_DOCUMENTATION.map((step, index) => (
|
||||
<li className="relative" key={index}>
|
||||
<div className="absolute -left-12">
|
||||
@@ -259,7 +259,7 @@ export const TemplateDirectLinkDialog = ({
|
||||
.with({ token: P.nullish, currentStep: 'SELECT_RECIPIENT' }, () => (
|
||||
<DialogContent className="relative">
|
||||
{isCreatingTemplateDirectLink && validDirectTemplateRecipients.length !== 0 && (
|
||||
<div className="absolute inset-0 z-50 flex items-center justify-center rounded-sm bg-white/50 dark:bg-black/50">
|
||||
<div className="absolute inset-0 z-50 flex items-center justify-center rounded bg-white/50 dark:bg-black/50">
|
||||
<LoaderIcon className="h-6 w-6 animate-spin text-gray-500" />
|
||||
</div>
|
||||
)}
|
||||
@@ -405,7 +405,7 @@ export const TemplateDirectLinkDialog = ({
|
||||
className="h-8 w-8"
|
||||
onClick={() => void onCopyClick(token)}
|
||||
>
|
||||
<ClipboardCopyIcon className="h-4 w-4 shrink-0" />
|
||||
<ClipboardCopyIcon className="h-4 w-4 flex-shrink-0" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -240,9 +240,9 @@ export function TemplateUseDialog({
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<fieldset className="flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<div className="custom-scrollbar twv3-space-y-4 -m-1 max-h-[60vh] overflow-y-auto p-1">
|
||||
<div className="custom-scrollbar -m-1 max-h-[60vh] space-y-4 overflow-y-auto p-1">
|
||||
{formRecipients.map((recipient, index) => (
|
||||
<div className="twv3-space-x-4 flex w-full flex-row" key={recipient.id}>
|
||||
<div className="flex w-full flex-row space-x-4" key={recipient.id}>
|
||||
{templateSigningOrder === DocumentSigningOrder.SEQUENTIAL && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -337,7 +337,7 @@ export function TemplateUseDialog({
|
||||
<InfoIcon className="mx-1 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="twv3-space-y-2 z-[99999] max-w-md p-4 text-muted-foreground">
|
||||
<TooltipContent className="z-[99999] max-w-md space-y-2 p-4 text-muted-foreground">
|
||||
<p>
|
||||
<Trans>
|
||||
The document will be immediately sent to recipients if this is checked.
|
||||
@@ -362,7 +362,7 @@ export function TemplateUseDialog({
|
||||
<TooltipTrigger type="button">
|
||||
<InfoIcon className="mx-1 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="twv3-space-y-2 z-[99999] max-w-md p-4 text-muted-foreground">
|
||||
<TooltipContent className="z-[99999] max-w-md space-y-2 p-4 text-muted-foreground">
|
||||
<p>
|
||||
<Trans>Create the document as pending and ready to sign.</Trans>
|
||||
</p>
|
||||
@@ -414,7 +414,7 @@ export function TemplateUseDialog({
|
||||
<TooltipTrigger type="button">
|
||||
<InfoIcon className="mx-1 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="twv3-space-y-2 z-[99999] max-w-md p-4 text-muted-foreground">
|
||||
<TooltipContent className="z-[99999] max-w-md space-y-2 p-4 text-muted-foreground">
|
||||
<p>
|
||||
<Trans>
|
||||
Upload a custom document to use instead of the template's default document
|
||||
@@ -429,7 +429,7 @@ export function TemplateUseDialog({
|
||||
/>
|
||||
|
||||
{form.watch('useCustomDocument') && (
|
||||
<div className="twv3-space-y-2 my-4">
|
||||
<div className="my-4 space-y-2">
|
||||
{isLoadingEnvelopeItems ? (
|
||||
<SpinnerBox className="py-16" />
|
||||
) : (
|
||||
@@ -445,7 +445,7 @@ export function TemplateUseDialog({
|
||||
key={item.id}
|
||||
className="flex items-center gap-4 rounded-lg border border-border bg-card p-4 transition-colors hover:bg-accent/10"
|
||||
>
|
||||
<div className="shrink-0">
|
||||
<div className="flex-shrink-0">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10">
|
||||
<FileTextIcon className="h-5 w-5 text-primary" />
|
||||
</div>
|
||||
@@ -464,7 +464,7 @@ export function TemplateUseDialog({
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center gap-2">
|
||||
<div className="flex flex-shrink-0 items-center gap-2">
|
||||
{field.value ? (
|
||||
<div className="">
|
||||
<Button
|
||||
|
||||
@@ -117,7 +117,7 @@ export default function TokenDeleteDialog({ token, onDelete, children }: TokenDe
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="tokenName"
|
||||
|
||||
@@ -94,7 +94,7 @@ export const WebhookCreateDialog = ({ trigger, ...props }: WebhookCreateDialogPr
|
||||
<Dialog open={open} onOpenChange={(value) => !form.formState.isSubmitting && setOpen(value)} {...props}>
|
||||
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild>
|
||||
{trigger ?? (
|
||||
<Button className="shrink-0">
|
||||
<Button className="flex-shrink-0">
|
||||
<Trans>Create Webhook</Trans>
|
||||
</Button>
|
||||
)}
|
||||
@@ -112,7 +112,7 @@ export const WebhookCreateDialog = ({ trigger, ...props }: WebhookCreateDialogPr
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<div className="flex flex-col-reverse gap-4 md:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
||||
@@ -108,7 +108,7 @@ export const WebhookDeleteDialog = ({ webhook, children }: WebhookDeleteDialogPr
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="webhookUrl"
|
||||
|
||||
@@ -88,7 +88,7 @@ export const WebhookTestDialog = ({ webhook, children }: WebhookTestDialogProps)
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<fieldset className="twv3-space-y-4 flex h-full flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex h-full flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="event"
|
||||
|
||||
@@ -75,7 +75,7 @@ export const ConfigureDocumentAdvancedSettings = ({
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="general" className="mt-0">
|
||||
<div className="twv3-space-y-6 flex flex-col">
|
||||
<div className="flex flex-col space-y-6">
|
||||
{features.allowConfigureSignatureTypes && (
|
||||
<FormField
|
||||
control={control}
|
||||
@@ -215,7 +215,7 @@ export const ConfigureDocumentAdvancedSettings = ({
|
||||
|
||||
{features.allowConfigureCommunication && (
|
||||
<TabsContent value="communication" className="mt-0">
|
||||
<div className="twv3-space-y-6 flex flex-col">
|
||||
<div className="flex flex-col space-y-6">
|
||||
<FormField
|
||||
control={control}
|
||||
name="meta.distributionMethod"
|
||||
@@ -254,7 +254,7 @@ export const ConfigureDocumentAdvancedSettings = ({
|
||||
/>
|
||||
|
||||
<fieldset
|
||||
className="twv3-space-y-6 flex flex-col disabled:cursor-not-allowed disabled:opacity-60"
|
||||
className="flex flex-col space-y-6 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
disabled={!isEmailDistribution}
|
||||
>
|
||||
<FormField
|
||||
|
||||
@@ -147,7 +147,7 @@ export const ConfigureDocumentRecipients = ({ control, isSubmitting }: Configure
|
||||
control={control}
|
||||
name="meta.signingOrder"
|
||||
render={({ field }) => (
|
||||
<FormItem className="twv3-space-x-2 twv3-space-y-0 mb-6 flex flex-row items-center">
|
||||
<FormItem className="mb-6 flex flex-row items-center space-x-2 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
{...field}
|
||||
@@ -173,7 +173,7 @@ export const ConfigureDocumentRecipients = ({ control, isSubmitting }: Configure
|
||||
control={control}
|
||||
name="meta.allowDictateNextSigner"
|
||||
render={({ field: { value, ...field } }) => (
|
||||
<FormItem className="twv3-space-x-2 twv3-space-y-0 mb-6 flex flex-row items-center">
|
||||
<FormItem className="mb-6 flex flex-row items-center space-x-2 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
{...field}
|
||||
@@ -221,7 +221,7 @@ export const ConfigureDocumentRecipients = ({ control, isSubmitting }: Configure
|
||||
>
|
||||
<Droppable droppableId="signers">
|
||||
{(provided) => (
|
||||
<div {...provided.droppableProps} ref={provided.innerRef} className="twv3-space-y-2">
|
||||
<div {...provided.droppableProps} ref={provided.innerRef} className="space-y-2">
|
||||
{signers.map((signer, index) => (
|
||||
<Draggable
|
||||
key={signer.id}
|
||||
@@ -254,7 +254,7 @@ export const ConfigureDocumentRecipients = ({ control, isSubmitting }: Configure
|
||||
'mb-6': errors?.signers?.[index] && !errors?.signers?.[index]?.signingOrder,
|
||||
})}
|
||||
>
|
||||
<GripVertical className="h-5 w-5 shrink-0 opacity-40" />
|
||||
<GripVertical className="h-5 w-5 flex-shrink-0 opacity-40" />
|
||||
<FormControl>
|
||||
<Input
|
||||
type="number"
|
||||
|
||||
@@ -158,7 +158,7 @@ export const ConfigureDocumentUpload = ({ isSubmitting = false }: ConfigureDocum
|
||||
/>
|
||||
|
||||
<div
|
||||
className={cn('twv3-space-y-1 flex flex-col', {
|
||||
className={cn('flex flex-col space-y-1', {
|
||||
'text-primary': isDragActive,
|
||||
'text-muted-foreground': !isDragActive,
|
||||
})}
|
||||
|
||||
@@ -75,7 +75,7 @@ export const ConfigureDocumentView = ({
|
||||
const onFormSubmit = handleSubmit(onSubmit);
|
||||
|
||||
return (
|
||||
<div className="twv3-space-y-8 flex w-full flex-col">
|
||||
<div className="flex w-full flex-col space-y-8">
|
||||
<div>
|
||||
<h2 className="mb-1 font-semibold text-foreground text-xl">
|
||||
{isTemplate ? <Trans>Configure Template</Trans> : <Trans>Configure Document</Trans>}
|
||||
@@ -91,7 +91,7 @@ export const ConfigureDocumentView = ({
|
||||
</div>
|
||||
|
||||
<Form {...form}>
|
||||
<div className="twv3-space-y-8 flex flex-col">
|
||||
<div className="flex flex-col space-y-8">
|
||||
<div>
|
||||
<FormField
|
||||
control={control}
|
||||
|
||||
@@ -462,7 +462,7 @@ export const ConfigureFieldsView = ({
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
<div className="twv3-space-y-2">
|
||||
<div className="space-y-2">
|
||||
<FieldSelector
|
||||
selectedField={selectedField}
|
||||
onSelectedFieldChange={setSelectedField}
|
||||
@@ -604,7 +604,7 @@ export const ConfigureFieldsView = ({
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
<div className="twv3-space-y-2">
|
||||
<div className="space-y-2">
|
||||
<FieldSelector
|
||||
selectedField={selectedField}
|
||||
onSelectedFieldChange={(field) => {
|
||||
|
||||
@@ -372,7 +372,7 @@ export const EmbedDirectTemplateClientPage = ({
|
||||
{/* Widget */}
|
||||
<div
|
||||
key={isExpanded ? 'expanded' : 'collapsed'}
|
||||
className="group/document-widget fixed bottom-8 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full shrink-0 px-6 md:sticky md:top-4 md:bottom-[unset] 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:bottom-[unset] md:z-auto md:w-[350px] md:px-0"
|
||||
data-expanded={isExpanded || undefined}
|
||||
>
|
||||
<div className="flex h-fit w-full flex-col rounded-xl border border-border bg-widget px-4 py-4 md:min-h-[min(calc(100dvh-2rem),48rem)] md:py-6">
|
||||
|
||||
@@ -304,7 +304,7 @@ export const EmbedSignDocumentV1ClientPage = ({
|
||||
{/* Widget */}
|
||||
<div
|
||||
key={isExpanded ? 'expanded' : 'collapsed'}
|
||||
className="embed--DocumentWidgetContainer group/document-widget fixed bottom-8 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full shrink-0 px-6 md:sticky md:top-4 md:bottom-[unset] 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:bottom-[unset] md:z-auto md:w-[350px] md:px-0"
|
||||
data-expanded={isExpanded || undefined}
|
||||
>
|
||||
<div className="embed--DocumentWidget flex w-full flex-col rounded-xl border border-border bg-widget px-4 py-4 md:py-6">
|
||||
@@ -369,7 +369,7 @@ export const EmbedSignDocumentV1ClientPage = ({
|
||||
|
||||
<fieldset className="mt-2 rounded-2xl border border-border bg-white p-3 dark:bg-background">
|
||||
<RadioGroup
|
||||
className="twv3-space-y-3 gap-0 shadow-none"
|
||||
className="gap-0 space-y-3 shadow-none"
|
||||
value={selectedSignerId?.toString()}
|
||||
onValueChange={(value) => setSelectedSignerId(Number(value))}
|
||||
>
|
||||
|
||||
@@ -234,7 +234,7 @@ export const MultiSignDocumentSigningView = ({
|
||||
{document.status !== DocumentStatus.COMPLETED && (
|
||||
<div
|
||||
key={isExpanded ? 'expanded' : 'collapsed'}
|
||||
className="embed--DocumentWidgetContainer group/document-widget fixed bottom-8 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full shrink-0 px-6 md:sticky md:top-0 md:bottom-[unset] 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-0 md:bottom-[unset] md:z-auto md:w-[350px] md:px-0"
|
||||
data-expanded={isExpanded || undefined}
|
||||
>
|
||||
<div className="embed--DocumentWidget flex w-full flex-col rounded-xl border border-border bg-widget px-4 py-4 md:py-6">
|
||||
|
||||
@@ -98,7 +98,7 @@ export const DisableAuthenticatorAppDialog = () => {
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={onCloseTwoFactorDisableDialog}>
|
||||
<DialogTrigger asChild={true}>
|
||||
<Button className="shrink-0" variant="destructive">
|
||||
<Button className="flex-shrink-0" variant="destructive">
|
||||
<Trans>Disable 2FA</Trans>
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
@@ -139,7 +139,7 @@ export const EnableAuthenticatorAppDialog = ({ onSuccess }: EnableAuthenticatorA
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DialogTrigger asChild={true}>
|
||||
<Button
|
||||
className="shrink-0"
|
||||
className="flex-shrink-0"
|
||||
loading={isSettingUp2FA}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -75,7 +75,7 @@ export const ViewRecoveryCodesDialog = () => {
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="shrink-0">
|
||||
<Button className="flex-shrink-0">
|
||||
<Trans>View Codes</Trans>
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
@@ -120,7 +120,7 @@ export const ViewRecoveryCodesDialog = () => {
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<fieldset className="twv3-space-y-4 flex flex-col" disabled={form.formState.isSubmitting}>
|
||||
<fieldset className="flex flex-col space-y-4" disabled={form.formState.isSubmitting}>
|
||||
<FormField
|
||||
name="token"
|
||||
control={form.control}
|
||||
|
||||
@@ -500,7 +500,7 @@ export function BrandingPreferencesForm({
|
||||
|
||||
<Accordion type="single" collapsible>
|
||||
<AccordionItem value="custom-css" className="border-none">
|
||||
<AccordionTrigger className="rounded-sm border px-3 py-2 text-left text-foreground hover:bg-muted/40 hover:no-underline">
|
||||
<AccordionTrigger className="rounded border px-3 py-2 text-left text-foreground hover:bg-muted/40 hover:no-underline">
|
||||
<Trans>Advanced — Custom CSS</Trans>
|
||||
</AccordionTrigger>
|
||||
|
||||
@@ -538,7 +538,7 @@ export function BrandingPreferencesForm({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="twv3-space-x-4 flex flex-row justify-end">
|
||||
<div className="flex flex-row justify-end space-x-4">
|
||||
<Button type="submit" loading={form.formState.isSubmitting}>
|
||||
<Trans>Update</Trans>
|
||||
</Button>
|
||||
|
||||
@@ -552,7 +552,7 @@ export const DocumentPreferencesForm = ({
|
||||
)}
|
||||
|
||||
{(field.value !== null || !canInherit) && (
|
||||
<div className="twv3-space-y-4">
|
||||
<div className="space-y-4">
|
||||
<DefaultRecipientsMultiSelectCombobox
|
||||
listValues={recipients}
|
||||
onChange={field.onChange}
|
||||
@@ -756,7 +756,7 @@ export const DocumentPreferencesForm = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="twv3-space-x-4 flex flex-row justify-end">
|
||||
<div className="flex flex-row justify-end space-x-4">
|
||||
<Button type="submit" loading={form.formState.isSubmitting}>
|
||||
<Trans>Update</Trans>
|
||||
</Button>
|
||||
|
||||
@@ -272,7 +272,7 @@ export const EditorFieldCheckboxForm = ({
|
||||
|
||||
<EditorGenericReadOnlyField formControl={form.control} />
|
||||
|
||||
<section className="twv3-space-y-2">
|
||||
<section className="space-y-2">
|
||||
<div className="-mx-4 mt-2 mb-4">
|
||||
<Separator />
|
||||
</div>
|
||||
@@ -287,7 +287,7 @@ export const EditorFieldCheckboxForm = ({
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul className="twv3-space-y-2">
|
||||
<ul className="space-y-2">
|
||||
{(formValues.values || []).map((value, index) => (
|
||||
<li key={`checkbox-value-${index}`} className="flex flex-row items-center gap-2">
|
||||
<FormField
|
||||
|
||||
@@ -190,7 +190,7 @@ export const EditorFieldDropdownForm = ({
|
||||
|
||||
<EditorGenericReadOnlyField formControl={form.control} />
|
||||
|
||||
<section className="twv3-space-y-2">
|
||||
<section className="space-y-2">
|
||||
<div className="-mx-4 mt-2 mb-4">
|
||||
<Separator />
|
||||
</div>
|
||||
@@ -205,7 +205,7 @@ export const EditorFieldDropdownForm = ({
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul className="twv3-space-y-2">
|
||||
<ul className="space-y-2">
|
||||
{(formValues.values || []).map((value, index) => (
|
||||
<li key={`dropdown-value-${index}`} className="flex flex-row gap-2">
|
||||
<FormField
|
||||
|
||||
@@ -237,7 +237,7 @@ export const EditorGenericRequiredField = ({
|
||||
control={formControl}
|
||||
name="required"
|
||||
render={({ field }) => (
|
||||
<FormItem className={cn('twv3-space-x-2 flex items-center', className)}>
|
||||
<FormItem className={cn('flex items-center space-x-2', className)}>
|
||||
<FormControl>
|
||||
<div className="flex items-center">
|
||||
<Checkbox
|
||||
@@ -281,7 +281,7 @@ export const EditorGenericReadOnlyField = ({
|
||||
control={formControl}
|
||||
name="readOnly"
|
||||
render={({ field }) => (
|
||||
<FormItem className={cn('twv3-space-x-2 flex items-center', className)}>
|
||||
<FormItem className={cn('flex items-center space-x-2', className)}>
|
||||
<FormControl>
|
||||
<div className="flex items-center">
|
||||
<Checkbox
|
||||
|
||||
@@ -230,7 +230,7 @@ export const EditorFieldNumberForm = ({
|
||||
<EditorGenericReadOnlyField formControl={form.control} />
|
||||
|
||||
{/* Validation section */}
|
||||
<section className="twv3-space-y-2">
|
||||
<section className="space-y-2">
|
||||
<div className="-mx-4 mt-2 mb-4">
|
||||
<Separator />
|
||||
</div>
|
||||
|
||||
@@ -149,7 +149,7 @@ export const EditorFieldRadioForm = ({
|
||||
|
||||
<EditorGenericReadOnlyField formControl={form.control} />
|
||||
|
||||
<section className="twv3-space-y-2">
|
||||
<section className="space-y-2">
|
||||
<div className="-mx-4 mt-2 mb-4">
|
||||
<Separator />
|
||||
</div>
|
||||
@@ -164,7 +164,7 @@ export const EditorFieldRadioForm = ({
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul className="twv3-space-y-2">
|
||||
<ul className="space-y-2">
|
||||
{(formValues.values || []).map((value, index) => (
|
||||
<li key={`radio-value-${index}`} className="flex flex-row items-center gap-2">
|
||||
<FormField
|
||||
|
||||
@@ -185,7 +185,7 @@ export const EmailPreferencesForm = ({ settings, onFormSubmit, canInherit }: Ema
|
||||
)}
|
||||
|
||||
{field.value && (
|
||||
<div className="twv3-space-y-2 rounded-md border p-4">
|
||||
<div className="space-y-2 rounded-md border p-4">
|
||||
<DocumentEmailCheckboxes
|
||||
value={field.value ?? DEFAULT_DOCUMENT_EMAIL_SETTINGS}
|
||||
onChange={(value) => field.onChange(value)}
|
||||
@@ -203,7 +203,7 @@ export const EmailPreferencesForm = ({ settings, onFormSubmit, canInherit }: Ema
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="twv3-space-x-4 flex flex-row justify-end">
|
||||
<div className="flex flex-row justify-end space-x-4">
|
||||
<Button type="submit" loading={form.formState.isSubmitting}>
|
||||
<Trans>Update</Trans>
|
||||
</Button>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user